Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations derfloh on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Dynamically change width of parallel DIV via splitter 1

Status
Not open for further replies.

awaresoft

Programmer
Feb 16, 2002
373
DE
Hi,

I have 2 parallel DIV sections - similar to a classic frames layout with a thin menu frame on the left and a wider content frame on the right.

I would like to offer my users the ability to dynamically drag the "vertical border" that seperates these 2 DIV (simulated frames) so that the user can customize the width of each DIV?

In the Windows world, I would use a Splitter control to allow a user to customize the widths of 2 adjacent containers.

My initial idea is to create a 3rd vertical DIV that sits between my left and right DIV's. This DIV would be the physical splitter that users would click and drag to resize the left and right DIV ("frames").

This is as far as I've gotten. Any suggestions or snippets?

Thanks!
Malcolm
 
Had a bit of a play with this. Here's what I've got so far:
Code:
<html>
<head>
<title>Divs acting as Frames</title>
<script language=&quot;JavaScript&quot; type=&quot;text/javascript&quot;>
var onSplitter = false;
var prevMouseX, currMouseX;
function startDrag(){
 onSplitter = true;
 prevMouseX = event.clientX;
}
function doDrag(){
 if(onSplitter){
  currMouseX = event.clientX;
  var difference = currMouseX - prevMouseX;
  prevMouseX = event.clientX;
  resizeFrames(difference);
 }
}
function endDrag(){
 if(onSplitter){
  onSplitter = false;
 }
}
function resizeFrames(intAmount){
 var styleSheet = document.styleSheets(0);
 var leftWidth = parseInt(styleSheet.rules.item(0).style.width) + parseInt(intAmount);
 if(leftWidth < 0){
  leftWidth = 0;
 }
 var mainWidth = parseInt(styleSheet.rules.item(2).style.width) + (-1 * parseInt(intAmount));
 if(mainWidth < 0){
  mainWidth = 0;
 }
 styleSheet.rules.item(0).style.width = leftWidth + 'px';
 styleSheet.rules.item(1).style.left = parseInt(styleSheet.rules.item(1).style.left) + parseInt(intAmount) + 'px';
 styleSheet.rules.item(2).style.left = parseInt(styleSheet.rules.item(2).style.left) + parseInt(intAmount) + 'px';
 styleSheet.rules.item(2).style.width = mainWidth + 'px';
}
</script>
<style type=&quot;text/css&quot;>
#LeftFrame {
 width: 100px;
 height: 100%;
 background: #AAAAFF;
 position: absolute;
 top: 0px;
}
#Splitter {
 width: 5px;
 height: 100%;
 background: #AAAAAA;
 position: absolute;
 top: 0px;
 left:100px;
 cursor: e-resize;
}
#MainFrame {
 width: 400px;
 height: 100%;
 background: #FFAAFF;
 position: absolute;
 top: 0px;
 left: 105px;
}
</style>
</head>

<body onmousemove=&quot;doDrag();&quot; onmouseup=&quot;endDrag();&quot;>
<div id=&quot;LeftFrame&quot;>This is the menu div</div>
<div id=&quot;Splitter&quot; onMouseDown=&quot;startDrag();&quot;></div>
<div id=&quot;MainFrame&quot;>This is the main div<br>
  <-- the splitter is here </div>
</body>
</html>

Never be afraid to share your dreams with the world.
There's nothing the world loves more than the taste of really sweet dreams.
 
very nice. *

Posting code? Wrap it with code tags: [ignore]
Code:
[/ignore][code]CodeHere
[ignore][/code][/ignore].
 
side note: doesn't work in NN7 - having a look at your resizeFrames() function to see if I can adapt it to work using only ECMAscript functionality (clientX has to go too :))

Posting code? Wrap it with code tags: [ignore]
Code:
[/ignore][code]CodeHere
[ignore][/code][/ignore].
 
Well I got it to work in IE6 & NN7 with:
Code:
<!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.01 Transitional//EN&quot; &quot;[URL unfurl="true"]http://www.w3.org/TR/html4/loose.dtd&quot;>[/URL]
<html>
<head>
<title>Divs acting as Frames.. crossBrowser attempt</title>
<script language=&quot;JavaScript&quot; type=&quot;text/javascript&quot;>
var onSplitter = false;
var prevMouseX, currMouseX;
function startDrag(thisEvent){
 onSplitter = true;
 prevMouseX = thisEvent.screenX;
}
function doDrag(thisEvent){
 if(onSplitter){
  currMouseX = thisEvent.screenX;
  var difference = currMouseX - prevMouseX;
  prevMouseX = thisEvent.screenX;
  resizeFrames(difference);
 }
}
function endDrag(thisEvent){
 if(onSplitter){
  onSplitter = false;
 }
}
function resizeFrames(intAmount){
 var leftFrame = document.getElementById(&quot;LeftFrame&quot;);
 var mainFrame = document.getElementById(&quot;MainFrame&quot;);
 var splitter = document.getElementById(&quot;Splitter&quot;);
 var amount = parseInt(intAmount);
 var splitterLeft = parseInt(splitter.style.left)
 var mainFrameLeft = parseInt(mainFrame.style.left)

 var leftWidth = parseInt(leftFrame.style.width) + amount;
 if(leftWidth < 0){
  leftWidth = 0;
 }
 var mainWidth = parseInt(mainFrame.style.width) + (-1 * amount);
 if(mainWidth < 0){
  mainWidth = 0;
 }
 leftFrame.style.width = leftWidth + 'px';
 splitter.style.left = splitterLeft + amount + 'px';
 mainFrame.style.left = mainFrameLeft + amount + 'px';
 mainFrame.style.width = mainWidth + 'px';
 
}
</script>
<style type=&quot;text/css&quot;>
#LeftFrame {
 height: 400px;
 background: #AAAAFF;
 position: absolute;
 top: 0px;
}
#Splitter {
 height: 400px;
 background: #AAAAAA;
 position: absolute;
 top: 0px;
 cursor: e-resize;
}
#MainFrame {
 height: 400px;
 background: #FFAAFF;
 position: absolute;
 top: 0px;
}
</style>
</head>

<body onmousemove=&quot;doDrag(event);&quot; onmouseup=&quot;endDrag(event);&quot;>
<div id=&quot;LeftFrame&quot; style=&quot;width: 100px&quot;>This is the menu div</div>
<div id=&quot;Splitter&quot; style=&quot;width: 5px;left: 100px&quot; onMouseDown=&quot;startDrag(event);&quot;></div>
<div id=&quot;MainFrame&quot; style=&quot;width: 400px;left: 105px&quot;>This is the main div<br>
  <-- the splitter is here</div>
</body>
</html>
Have a go and see. Had to change styles to be inline to be able to get at them - got a better way? ..

Any improvements on this?

Posting code? Wrap it with code tags: [ignore]
Code:
[/ignore][code]CodeHere
[ignore][/code][/ignore].
 
You'd need the inline style attributes, otherwise - without the document.styleSheets collection, all the values would return null. Good job.

Never be afraid to share your dreams with the world.
There's nothing the world loves more than the taste of really sweet dreams.
 
awaresoft - what did you end up using..
got an example page where you used this?

Posting code? Wrap it with code tags: [ignore]
Code:
[/ignore][code]CodeHere
[ignore][/code][/ignore].
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top