Current location: Hot Scripts Forums » General Web Coding » JavaScript » Add "Handles" to these draggable boxes?


Add "Handles" to these draggable boxes?

Reply
  #1 (permalink)  
Old 10-07-09, 09:13 AM
End User's Avatar
End User End User is offline
Level II Curmudgeon
 
Join Date: Dec 2004
Posts: 3,027
Thanks: 14
Thanked 35 Times in 33 Posts
Add "Handles" to these draggable boxes?

This is an example "drag n' drop" script from DHTMLGoodies that makes nicely formatted sortable boxes out of list items (LI).

I have another small script which provides an 'edit-in-place' feature when you click on some text within a marked span, but it won't work in this instance because the entire box is used as the draggable portion or handle, and that keeps the 'edit-in-place' script from activating.

If someone could give me an idea (or perhaps show me) how I could make only a portion of the boxes act as the drag "handle" for this script (like a few pixels on the right side, perhaps), I'd be grateful.

This is the whole thing, self-contained, no external files needed:

HTML Code:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<!-- http://www.dhtmlgoodies.com/scripts/arrange-nodes/arrange-nodes-d2.html -->
<html>
<head>
	<title>Text arrange</title>

<script type="text/javascript" src="instantedit.<acronym title="JavaScript"><acronym title="JavaScript">js</acronym></acronym>"></script>
	<style type="text/css">

	body{
		font-family: Trebuchet MS, Lucida Sans Unicode, Arial, sans-serif;
		margin:0px;
		padding:0px;
		padding-left:10px;
		-moz-user-select:no;
	}
	h1{
		margin-bottom:5px;
	}
	
	/* Don't change these options */
	#movableNode{
		position:absolute;
	}
	
	#arrDestInditcator{
		position:absolute;
		display:none;
		width:10px;
	}
	/* End options that shouldn't be changed */

	
	#arrangableNodes,#movableNode ul{
		padding-left:0px;
		margin-left:0px;
		margin-top:0px;
		padding-top:0px;
		width:300px;
	}
	
	#arrangableNodes li,#movableNode li{
		list-style-type:none;
		cursor:default;
		border:1px solid #999;
		padding:5px;
		background-color:#EEE;
		margin-top:2px;

	}
	img{
		border:0px;
	}
	</style>
	
	<script type="text/javascript">
		
	var arrParent = false;
	var arrMoveCont = false;
	var arrMoveCounter = -1;
	var arrTarget = false;
	var arrNextSibling = false;
	var leftPosArrangableNodes = false;
	var widthArrangableNodes = false;
	var nodePositionsY = new Array();
	var nodeHeights = new Array();
	var arrInsertDiv = false;
	var offsetYInsertDiv = -4; // Y offset for the little arrow indicating where the node should be inserted.
	if(!document.all)offsetYInsertDiv = offsetYInsertDiv - 7; 	// No IE
	var arrNodesDestination = false;
	var insertAsFirstNode = false;
	function cancelEvent()
	{
		return false;
	}
	function getTopPos(inputObj)
	{
		
	  var returnValue = inputObj.offsetTop;
	  while((inputObj = inputObj.offsetParent) != null){
	  	returnValue += inputObj.offsetTop;
	  }
	  return returnValue;
	}
	
	function getLeftPos(inputObj)
	{
	  var returnValue = inputObj.offsetLeft;
	  while((inputObj = inputObj.offsetParent) != null)returnValue += inputObj.offsetLeft;
	  return returnValue;
	}
		
	function clearMovableDiv()
	{
		if(arrMoveCont.getElementsByTagName('LI').length>0){
			if(arrNextSibling)arrParent.insertBefore(arrTarget,arrNextSibling); else arrParent.appendChild(arrTarget);			
		}
		
	}
	
	function initMoveNode(e)
	{
		clearMovableDiv();
		if(document.all)e = event;
		arrMoveCounter = 0;
		arrTarget = this;
		if(this.nextSibling)arrNextSibling = this.nextSibling; else arrNextSibling = false;
		timerMoveNode();
		arrMoveCont.parentNode.style.left = e.clientX + 'px';
		arrMoveCont.parentNode.style.top = (e.clientY + Math.max(document.body.scrollTop,document.documentElement.scrollTop)) + 'px';
		return false;
		
	}



	function timerMoveNode(){

//editBox(this);

		if(arrMoveCounter>=0 && arrMoveCounter<10){

			arrMoveCounter = arrMoveCounter +1;
			setTimeout('timerMoveNode()',20);
		}

		if(arrMoveCounter>=10){
			arrMoveCont.appendChild(arrTarget);
		}
	}
		
	function arrangeNodeMove(e)
	{
		if(document.all)e = event;
		if(arrMoveCounter<10)return;
		if(document.all && arrMoveCounter>=10 && e.button!=1 && navigator.userAgent.indexOf('Opera')==-1){
			arrangeNodeStopMove();
		}
		
		arrMoveCont.parentNode.style.left = e.clientX + 'px';
		arrMoveCont.parentNode.style.top = (e.clientY + Math.max(document.body.scrollTop,document.documentElement.scrollTop)) + 'px';	
		
		var tmpY = e.clientY + Math.max(document.body.scrollTop,document.documentElement.scrollTop);
		arrInsertDiv.style.display='none';
		arrNodesDestination = false;
		

		if(e.clientX<leftPosArrangableNodes || e.clientX>leftPosArrangableNodes + widthArrangableNodes)return; 
			
		var subs = arrParent.getElementsByTagName('LI');
		for(var no=0;no<subs.length;no++){
			var topPos =getTopPos(subs[no]);
			var tmpHeight = subs[no].offsetHeight;
			
			if(no==0){
				if(tmpY<=topPos && tmpY>=topPos-5){
					arrInsertDiv.style.top = (topPos + offsetYInsertDiv) + 'px';
					arrInsertDiv.style.display = 'block';				
					arrNodesDestination = subs[no];	
					insertAsFirstNode=true;
					return;
				}				
			}
			
			if(tmpY>=topPos && tmpY<=(topPos+tmpHeight)){
				arrInsertDiv.style.top = (topPos+tmpHeight + offsetYInsertDiv) + 'px';
				arrInsertDiv.style.display = 'block';				
				arrNodesDestination = subs[no];
				insertAsFirstNode = false;
				return;
			}				
		}
	}
	
	function arrangeNodeStopMove()
	{
		arrMoveCounter = -1; 
		arrInsertDiv.style.display='none';
		
		if(arrNodesDestination){
			var subs = arrParent.getElementsByTagName('LI');
			if(arrNodesDestination==subs[0] && insertAsFirstNode){
				arrParent.insertBefore(arrTarget,arrNodesDestination);		
			}else{
				if(arrNodesDestination.nextSibling){
					arrParent.insertBefore(arrTarget,arrNodesDestination.nextSibling);
				}else{
					arrParent.appendChild(arrTarget);
				}
			}
		}		
		arrNodesDestination = false;
		clearMovableDiv();
	}	
	
	function saveArrangableNodes()
	{
		var nodes = arrParent.getElementsByTagName('LI');
		var string = "";
		for(var no=0;no<nodes.length;no++){
			if(string.length>0)string = string + ',';
			string = string + nodes[no].id + ' ' + nodes[no].innerHTML;		
		}
		
		document.forms[0].hiddenNodeIds.value = string;
		
		// Just for testing
		document.getElementById('arrDebug').innerHTML = 'Ready to save these nodes:<br>' + string.replace(/,/g,',<BR>');	
		
		
	}
	
	function initArrangableNodes()
	{
		arrParent = document.getElementById('arrangableNodes');
		arrMoveCont = document.getElementById('movableNode').getElementsByTagName('UL')[0];
		arrInsertDiv = document.getElementById('arrDestInditcator');
		
		leftPosArrangableNodes = getLeftPos(arrParent);
		arrInsertDiv.style.left = leftPosArrangableNodes - 5 + 'px';
		widthArrangableNodes = arrParent.offsetWidth;
		
		var subs = arrParent.getElementsByTagName('LI');
		for(var no=0;no<subs.length;no++){
			subs[no].onmousedown = initMoveNode;
			subs[no].onselectstart = cancelEvent;	
		}
	
		document.documentElement.onmouseup = arrangeNodeStopMove;
		document.documentElement.onmousemove = arrangeNodeMove;
		document.documentElement.onselectstart = cancelEvent;
		
	}	
	
	window.onload = initArrangableNodes;
	
	</script>
</head>
<body>
		
<div class="konaBody">
	<H2>Arrange the Articles below by drag'n drop</H2>
</div>

<ul id="arrangableNodes">	
	<li id="node11">This is the title of an article</li>
	<li id="node2">Lorem ipsum dolor sit amet</li>
	<li id="node5">Excepteur sint occaecat </li>
	<li id="node15">Duis aute irure dolor in </li>
	<li id="node3">Sed do eiusmod tempor incididunt</li>		
	<li id="node6">Lorem ipsum dolor sit amet</li>
	<li id="node14">voluptatem sequi nesciunt</li>	
	<li id="node7">This is the title of an article</li>
	<li id="node12">This is the title of an article</li>	
	<li id="node1">Lorem ipsum dolor sit amet</li>
	<li id="node8">Duis aute irure dolor in</li>		
	<li id="node10">Sed do eiusmod tempor incididunt</li>
	<li id="node13">voluptatem sequi nesciunt</li>	
	<li id="node4">Excepteur sint occaecat </li>
	<li id="node9">Duis aute irure dolor in </li>		
</ul>	
<p>
	<a href="#" onclick="saveArrangableNodes();return false">Save</a>

</p>
<div id="movableNode"><ul></ul></div>	
<div id="arrDestInditcator"><img src="images/insert.gif"></div>
<div id="arrDebug"></div>
<form>
	<input type="hidden" name="hiddenNodeIds">
</form>
		
</body>
</html>
__________________
I don't live on the edge, but sometimes I go there to visit.
-------------------------------------------------------------------------
Sanitize Your Data | Oracle Date & Substring Functions | Code Snippet Library | [url=http://www.codmb.com/Call Of Duty[/url]
Reply With Quote
  #2 (permalink)  
Old 10-08-09, 05:13 PM
wirehopper's Avatar
wirehopper wirehopper is offline
-
 
Join Date: Feb 2006
Posts: 2,515
Thanks: 20
Thanked 109 Times in 106 Posts
You could try adding a span, inside the <li>, and adjust the logic to identify the spans as the movable elements, then change the move code to move the parent.

Sounds awkward, though.
Reply With Quote
  #3 (permalink)  
Old 10-08-09, 08:46 PM
End User's Avatar
End User End User is offline
Level II Curmudgeon
 
Join Date: Dec 2004
Posts: 3,027
Thanks: 14
Thanked 35 Times in 33 Posts
Quote:
Originally Posted by wirehopper View Post
You could try adding a span, inside the <li>, and adjust the logic to identify the spans as the movable elements, then change the move code to move the parent.

Sounds awkward, though.
Actually, I tried that...but I couldn't figure it out. I also tried adding a span outside the <li>, and several other things as well, but without success.

The whole <li> is draggable, if I could figure out how to make just part of it draggable, like a handle, I could make it work....but my javascript skills aren't up to the task, so I was hoping someone here would be able to give me a hand.

I need a way to sort and edit a group of items, and this script is 99% of what I need...it's that last 1% that's stopping me cold.

If I could combine the two scripts below from the DHTMLGoodies site, that would work too, but I've no idea where to start:

Draggable folder tree:
Folder tree with Drag and Drop capabilities

Editable folder tree:
Update your tree with AJAX

If there was one that was draggable and editable, I'd have the solution I need.
__________________
I don't live on the edge, but sometimes I go there to visit.
-------------------------------------------------------------------------
Sanitize Your Data | Oracle Date & Substring Functions | Code Snippet Library | [url=http://www.codmb.com/Call Of Duty[/url]
Reply With Quote
  #4 (permalink)  
Old 10-08-09, 10:51 PM
wirehopper's Avatar
wirehopper wirehopper is offline
-
 
Join Date: Feb 2006
Posts: 2,515
Thanks: 20
Thanked 109 Times in 106 Posts
Don't know if these help. I've had really good luck with dojo.

dojo/dnd - DojoCampus - Docs
SitePen Blog Inside Dojo DnD: Drag Handles

I'd probably split each node into two - a handle and the content. I tried using ids to reference the nodes, but no luck.

Very interesting.

Last edited by wirehopper; 10-09-09 at 12:04 AM.
Reply With Quote
  #5 (permalink)  
Old 10-09-09, 02:21 AM
job0107's Avatar
job0107 job0107 is offline
Community Liaison
 
Join Date: Dec 2006
Location: Tacoma, Washington USA
Posts: 3,454
Thanks: 0
Thanked 140 Times in 137 Posts
This was quite a difficult task using the code you have.
But with some modifications I was able to get it so you can edit the contents of the <li> you want to move.

I modified the form you have in the code to include a field that will contain the text of the <li> being moved.
And I added a submit button called edit, when clicked the edited text will appear in the <div> that contains the text of the moved <li>.

So if you grab one of the list items and move it away from the list, it will stay where you put it and then you can edit it and then move it to the disered position in the list.
HTML Code:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<!-- [url=http://www.dhtmlgoodies.com/scripts/arrange-nodes/arrange-nodes-d2.html]Text arrange[/url] -->
<html>
<head>
    <title>Text arrange</title>

<script type="text/javascript" src="instantedit.<acronym title="JavaScript"><acronym title="JavaScript">js</acronym></acronym>"></script>
    <style type="text/css">

    body{
        font-family: Trebuchet MS, Lucida Sans Unicode, Arial, sans-serif;
        margin:0px;
        padding:0px;
        padding-left:10px;
        -moz-user-select:no;
    }
    h1{
        margin-bottom:5px;
    }
    
    /* Don't change these options */
    #movableNode{
        position:absolute;
    }
    
    #arrDestInditcator{
        position:absolute;
        display:none;
        width:10px;
    }
    /* End options that shouldn't be changed */

    
    #arrangableNodes,#movableNode ul{
        padding-left:0px;
        margin-left:0px;
        margin-top:0px;
        padding-top:0px;
        width:300px;
    }
    
    #arrangableNodes li,#movableNode li{
        list-style-type:none;
        cursor:default;
        border:1px solid #999;
        padding:5px;
        background-color:#EEE;
        margin-top:2px;

    }
    img{
        border:0px;
    }
    #edit_box,#submit_button{display:none;}
    </style>
    
    <script type="text/javascript">
    var arrMovableNode = false;
    var edit_data = false;
    var arrDataEdited = false;    
    var arrParent = false;
    var arrMoveCont = false;
    var arrMoveCounter = -1;
    var arrTarget = false;
    var arrNextSibling = false;
    var leftPosArrangableNodes = false;
    var widthArrangableNodes = false;
    var nodePositionsY = new Array();
    var nodeHeights = new Array();
    var arrInsertDiv = false;
    var offsetYInsertDiv = -4; // Y offset for the little arrow indicating where the node should be inserted.
    if(!document.all)offsetYInsertDiv = offsetYInsertDiv - 7;     // No IE
    var arrNodesDestination = false;
    var insertAsFirstNode = false;
    function cancelEvent()
    {
      return false;
    }
    function getTopPos(inputObj)
    {
        
      var returnValue = inputObj.offsetTop;
      while((inputObj = inputObj.offsetParent) != null){
          returnValue += inputObj.offsetTop;
      }
      return returnValue;
    }
    
    function getLeftPos(inputObj)
    {
      var returnValue = inputObj.offsetLeft;
      while((inputObj = inputObj.offsetParent) != null)returnValue += inputObj.offsetLeft;
      return returnValue;
    }
        
    function clearMovableDiv()
    {
      if(arrMoveCont.getElementsByTagName('LI').length>0){
            if(arrNextSibling)arrParent.insertBefore(arrTarget,arrNextSibling); else arrParent.appendChild(arrTarget);            
        }
        
    }
    
    function initMoveNode(e)
    {
        clearMovableDiv();
        if(document.all)e = event;
        arrMoveCounter = 0;
        arrTarget = this;
        if(this.nextSibling)arrNextSibling = this.nextSibling; else arrNextSibling = false;
        timerMoveNode();
        arrMoveCont.parentNode.style.left = e.clientX + 'px';
        arrMoveCont.parentNode.style.top = (e.clientY + Math.max(document.body.scrollTop,document.documentElement.scrollTop)) + 'px';
        return false;
        
    }



    function timerMoveNode(){

//editBox(this);

        if(arrMoveCounter>=0 && arrMoveCounter<10){

            arrMoveCounter = arrMoveCounter +1;
            setTimeout('timerMoveNode()',1);
        }

        if(arrMoveCounter>=10){
        
            arrMoveCont.appendChild(arrTarget);
            arrMovableNode = document.getElementById("movableNode").getElementsByTagName("ul")[0].getElementsByTagName("li")[0];
            edit_data = arrMovableNode.innerHTML;
            if(!arrDataEdited)
            {
             document.getElementById("edit_box").style.display="inline";
             document.getElementById("submit_button").style.display="inline";
             document.getElementById("edit_box").value=edit_data;
             arrDataEdited = true;
             }
        }
    }
        
    function arrangeNodeMove(e)
    {
        if(document.all)e = event;
        if(arrMoveCounter<10)return;
        if(document.all && arrMoveCounter>=10 && e.button!=1 && navigator.userAgent.indexOf('Opera')==-1){
            arrangeNodeStopMove();
        }
        
        arrMoveCont.parentNode.style.left = e.clientX + 'px';
        arrMoveCont.parentNode.style.top = (e.clientY + Math.max(document.body.scrollTop,document.documentElement.scrollTop)) + 'px';    
        
        var tmpY = e.clientY + Math.max(document.body.scrollTop,document.documentElement.scrollTop);
        arrInsertDiv.style.display='none';
        arrNodesDestination = false;
        

        if(e.clientX<leftPosArrangableNodes || e.clientX>leftPosArrangableNodes + widthArrangableNodes)return;
            
        var subs = arrParent.getElementsByTagName('LI');
        for(var no=0;no<subs.length;no++){
            var topPos =getTopPos(subs[no]);
            var tmpHeight = subs[no].offsetHeight;
            
            if(no==0){
                if(tmpY<=topPos && tmpY>=topPos-5){
                    arrInsertDiv.style.top = (topPos + offsetYInsertDiv) + 'px';
                    arrInsertDiv.style.display = 'block';                
                    arrNodesDestination = subs[no];    
                    insertAsFirstNode=true;
                    return;
                }                
            }
            
            if(tmpY>=topPos && tmpY<=(topPos+tmpHeight)){
                arrInsertDiv.style.top = (topPos+tmpHeight + offsetYInsertDiv) + 'px';
                arrInsertDiv.style.display = 'block';                
                arrNodesDestination = subs[no];
                insertAsFirstNode = false;
                return;
            }                
        }
    }
    
    function arrangeNodeStopMove()
    {
      arrMoveCounter = -1;
        arrInsertDiv.style.display='none';
        if(arrNodesDestination)
      {
         var subs = arrParent.getElementsByTagName('LI');
         if(arrNodesDestination==subs[0] && insertAsFirstNode)
       {
          arrParent.insertBefore(arrTarget,arrNodesDestination);        
          }
       else
       {
          if(arrNodesDestination.nextSibling)
        {
            arrParent.insertBefore(arrTarget,arrNodesDestination.nextSibling);
            }
        else
        {
            arrParent.appendChild(arrTarget);
            }
          }
       document.getElementById("edit_box").style.display="none";
       document.getElementById("submit_button").style.display="none";
       arrDataEdited = false;     
        }        
      if(arrDataEdited && arrMoveCont.innerHTML == "")
      {
       document.getElementById("edit_box").style.display="none";
       document.getElementById("submit_button").style.display="none";
       arrDataEdited = false;
       }
      arrNodesDestination = false;
    }    
    
    function saveArrangableNodes()
    {
        var nodes = arrParent.getElementsByTagName('LI');
        var string = "";
        for(var no=0;no<nodes.length;no++){
            if(string.length>0)string = string + ',';
            string = string + nodes[no].id + ' ' + nodes[no].innerHTML;        
        }
        
        document.forms[0].hiddenNodeIds.value = string;
        
        // Just for testing
        document.getElementById('arrDebug').innerHTML = 'Ready to save these nodes:<br>' + string.replace(/,/g,',<BR />');    
        
        
    }
    
    function initArrangableNodes()
    {
        arrParent = document.getElementById('arrangableNodes');
        arrMoveCont = document.getElementById('movableNode').getElementsByTagName('UL')[0];
        arrInsertDiv = document.getElementById('arrDestInditcator');
        
        leftPosArrangableNodes = getLeftPos(arrParent);
        arrInsertDiv.style.left = leftPosArrangableNodes - 5 + 'px';
        widthArrangableNodes = arrParent.offsetWidth;
        
        var subs = arrParent.getElementsByTagName('LI');
        for(var no=0;no<subs.length;no++){
            subs[no].onmousedown = initMoveNode;
            subs[no].onselectstart = cancelEvent;    
        }
    
        document.documentElement.onmouseup = arrangeNodeStopMove;
        document.documentElement.onmousemove = arrangeNodeMove;
        document.documentElement.onselectstart = cancelEvent;
        
    }    

    function edit_node_value()
    {
       arrMovableNode.innerHTML = document.getElementById("edit_box").value;
       document.getElementById("edit_box").style.display="none";
       document.getElementById("submit_button").style.display="none";
       return false;
   }
   
    window.onload = initArrangableNodes;
    </script>
</head>
<body>
        
<div class="konaBody">
    <H2>Arrange the Articles below by drag'n drop</H2>
</div>

<ul id="arrangableNodes">    
    <li id="node11">This is the title of an article</li>
    <li id="node2">Lorem ipsum dolor sit amet</li>
    <li id="node5">Excepteur sint occaecat </li>
    <li id="node15">Duis aute irure dolor in </li>
    <li id="node3">Sed do eiusmod tempor incididunt</li>        
    <li id="node6">Lorem ipsum dolor sit amet</li>
    <li id="node14">voluptatem sequi nesciunt</li>    
    <li id="node7">This is the title of an article</li>
    <li id="node12">This is the title of an article</li>    
    <li id="node1">Lorem ipsum dolor sit amet</li>
    <li id="node8">Duis aute irure dolor in</li>        
    <li id="node10">Sed do eiusmod tempor incididunt</li>
    <li id="node13">voluptatem sequi nesciunt</li>    
    <li id="node4">Excepteur sint occaecat </li>
    <li id="node9">Duis aute irure dolor in </li>        
</ul>    
<p>
    <a href="#" onclick="saveArrangableNodes();return false">Save</a>

</p>
<div id="movableNode"><ul></ul></div>    
<div id="arrDestInditcator"><img src="http://www.hotscripts.com/forums/images/insert.gif"></div>
<div id="arrDebug"></div>
<form onsubmit="return edit_node_value();">
    <input type="hidden" name="hiddenNodeIds">
    <input id="edit_box">
    <input id="submit_button" type="submit" value="edit">
</form>
        
</body>
</html>
__________________
Jerry Broughton

Last edited by job0107; 10-09-09 at 02:24 AM.
Reply With Quote
The Following User Says Thank You to job0107 For This Useful Post:
End User (10-09-09)
  #6 (permalink)  
Old 10-09-09, 07:03 AM
End User's Avatar
End User End User is offline
Level II Curmudgeon
 
Join Date: Dec 2004
Posts: 3,027
Thanks: 14
Thanked 35 Times in 33 Posts
Jerry, this is awesome. I appreciate your help more than I know how to say. Thank you very, very much for looking at this and coming up with a solution.


Quote:
Originally Posted by job0107 View Post
This was quite a difficult task using the code you have.
But with some modifications I was able to get it so you can edit the contents of the <li> you want to move.

I modified the form you have in the code to include a field that will contain the text of the <li> being moved.
And I added a submit button called edit, when clicked the edited text will appear in the <div> that contains the text of the moved <li>.

So if you grab one of the list items and move it away from the list, it will stay where you put it and then you can edit it and then move it to the disered position in the list.
__________________
I don't live on the edge, but sometimes I go there to visit.
-------------------------------------------------------------------------
Sanitize Your Data | Oracle Date & Substring Functions | Code Snippet Library | [url=http://www.codmb.com/Call Of Duty[/url]
Reply With Quote
  #7 (permalink)  
Old 10-09-09, 10:31 AM
End User's Avatar
End User End User is offline
Level II Curmudgeon
 
Join Date: Dec 2004
Posts: 3,027
Thanks: 14
Thanked 35 Times in 33 Posts
I may have spoken too soon, but I still appreciate your effort.

This appears to work perfectly in Firefox, but in IE only the very top and bottom elements can be moved to a spot where they'll 'stick'. IEdoesn't display any error, but the draggable elements are now restricted in their movement.

I take it that there's no easy way to make just part of the <LI> draggable?

FWIW, basically what I have is a list of categories, a dozen or so, and I'm looking for a simple, easy way for users to re-order them, edit them, delete them, and add new categories. Here's an example that shows what I'm after:

JoobsBox PHP Demo
(demo login, then go to the Categories section)
This category manager allows you to drag the categories around and double-click to edit the name, click to add a new one, etc.

It uses JQuery, which unfortunately, I am restricted from using.

If there's a different way to do something like this, I'd be open to suggestions.
__________________
I don't live on the edge, but sometimes I go there to visit.
-------------------------------------------------------------------------
Sanitize Your Data | Oracle Date & Substring Functions | Code Snippet Library | [url=http://www.codmb.com/Call Of Duty[/url]
Reply With Quote
  #8 (permalink)  
Old 10-11-09, 01:58 AM
job0107's Avatar
job0107 job0107 is offline
Community Liaison
 
Join Date: Dec 2006
Location: Tacoma, Washington USA
Posts: 3,454
Thanks: 0
Thanked 140 Times in 137 Posts
This script is kind of difficult to work with.
But I have managed to get it to work.
It works very well in IE and works, but is a little clumsy in other browsers.

The way it works is like this:
When you click on a list item it goes into edit mode, at which time you can edit the contents.
When you click on it again it drops out of edit mode and retains the changes.
If you hold the mouse down on a list item, you will be able to move it.
You can change the sensitivity by changing the timer value of the setTimeout('timerMoveNode()',30); function in the timerMoveNode(obj) function.

The way I accomplished this is by putting your list items text in input elements.
Each input element must have a numeric id prefixed with the letter i.

You have 15 list items, so the input elements id's are i0 through i14.

I have tested the code in IE, FireFox and Safari.

HTML Code:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<!-- http://www.dhtmlgoodies.com/scripts/arrange-nodes/arrange-nodes-d2.html -->
<html>
<head>
<title>Text arrange</title>
<script type="text/javascript" src="instantedit.<acronym title="JavaScript"><acronym title="JavaScript">js</acronym></acronym>"></script>
<style type="text/css">
body
{
 font-family: Trebuchet MS, Lucida Sans Unicode, Arial, sans-serif;
 margin:0px;
 padding:0px;
 padding-left:10px;
 -moz-user-select:no;
 }
h1
{
 margin-bottom:5px;
 }
/* Don't change these options */
#movableNode{position:absolute;}
#arrDestInditcator
{
 position:absolute;
 display:none;
 width:10px;
 }
/* End options that shouldn't be changed */
#arrangableNodes,#movableNode ul
{
 padding-left:0px;
 margin-left:0px;
 margin-top:0px;
 padding-top:0px;
 width:300px;
 }
#arrangableNodes li,#movableNode li
{
 list-style-type:none;
 cursor:default;
 border:1px solid #999;
 padding:5px;
 margin-top:2px;
 padding:0px;
 background-color:#EEE;
 }
img{border:0px;}
input
{
 width:295px;
 height:25px;
 margin:0px;
 font-size:16px;
 border:none;
 background-color:#EEE;
 }
</style>
<script type="text/javascript">
var arrSwitch = new Array();
var arrInput = false;
var arrNum = false;    
var arrParent = false;
var arrMoveCont = false;
var arrMoveCounter = -1;
var arrTarget = false;
var arrNextSibling = false;
var leftPosArrangableNodes = false;
var widthArrangableNodes = false;
var nodePositionsY = new Array();
var nodeHeights = new Array();
var arrInsertDiv = false;
var offsetYInsertDiv = -4; // Y offset for the little arrow indicating where the node should be inserted.
if(!document.all)offsetYInsertDiv = offsetYInsertDiv - 7;     // No IE
var arrNodesDestination = false;
var insertAsFirstNode = false;
function cancelEvent(){return false;}
function getTopPos(inputObj)
{
 var returnValue = inputObj.offsetTop;
 while((inputObj = inputObj.offsetParent) != null){returnValue += inputObj.offsetTop;}
 return returnValue;
 }
function getLeftPos(inputObj)
{
 var returnValue = inputObj.offsetLeft;
 while((inputObj = inputObj.offsetParent) != null)returnValue += inputObj.offsetLeft;
 return returnValue;
 }
function clearMovableDiv()
{
 if(arrMoveCont.getElementsByTagName('LI').length>0){if(arrNextSibling)arrParent.insertBefore(arrTarget,arrNextSibling); else arrParent.appendChild(arrTarget);            }
 }
function initMoveNode(e)
{
 clearMovableDiv();
 if(document.all)e = event;
 arrMoveCounter = 0;
 arrTarget = this;
 arrInput = arrTarget.childNodes[0];
 arrNum = arrInput.id;
 edit_text(arrInput,arrNum);
 if(this.nextSibling)arrNextSibling = this.nextSibling; else arrNextSibling = false;
 timerMoveNode(arrInput);
 arrMoveCont.parentNode.style.left = e.clientX + 'px';
 arrMoveCont.parentNode.style.top = (e.clientY + Math.max(document.body.scrollTop,document.documentElement.scrollTop)) + 'px';
 return false;
 }
function timerMoveNode(obj)
{
 if(arrMoveCounter>=0 && arrMoveCounter<10)
 {
  arrMoveCounter = arrMoveCounter +1;
  setTimeout('timerMoveNode()',30);
  }
 if(arrMoveCounter>=10)
 {
  arrMoveCont.appendChild(arrTarget);
  }
 }
function arrangeNodeMove(e)
{
 if(document.all)e = event;
 if(arrMoveCounter<10)return;
 if(document.all && arrMoveCounter>=10 && e.button!=1 && navigator.userAgent.indexOf('Opera')==-1){arrangeNodeStopMove();}
 arrMoveCont.parentNode.style.left = e.clientX + 'px';
 arrMoveCont.parentNode.style.top = (e.clientY + Math.max(document.body.scrollTop,document.documentElement.scrollTop)) + 'px';    
 var tmpY = e.clientY + Math.max(document.body.scrollTop,document.documentElement.scrollTop);
 arrInsertDiv.style.display='none';
 arrNodesDestination = false;
 if(e.clientX<leftPosArrangableNodes || e.clientX>leftPosArrangableNodes + widthArrangableNodes)return;
 var subs = arrParent.getElementsByTagName('LI');
 for(var no=0;no<subs.length;no++)
 {
  var topPos =getTopPos(subs[no]);
  var tmpHeight = subs[no].offsetHeight;
  if(no==0)
  {
    if(tmpY<=topPos && tmpY>=topPos-5)
   {
     arrInsertDiv.style.top = (topPos + offsetYInsertDiv) + 'px';
     arrInsertDiv.style.display = 'block';                
     arrNodesDestination = subs[no];    
     insertAsFirstNode=true;
     return;
     }                
    }
  if(tmpY>=topPos && tmpY<=(topPos+tmpHeight))
  {
    arrInsertDiv.style.top = (topPos+tmpHeight + offsetYInsertDiv) + 'px';
    arrInsertDiv.style.display = 'block';                
    arrNodesDestination = subs[no];
    insertAsFirstNode = false;
    return;
    }                
  }
 }
function arrangeNodeStopMove()
{
 arrMoveCounter = -1;
 arrInsertDiv.style.display='none';
 if(arrNodesDestination)
 {
  var subs = arrParent.getElementsByTagName('LI');
  if(arrNodesDestination==subs[0] && insertAsFirstNode)
  {
   arrParent.insertBefore(arrTarget,arrNodesDestination);
   arrInput.style.border = "none";
   }
  else
  {
   if(arrNodesDestination.nextSibling)
   {
    arrParent.insertBefore(arrTarget,arrNodesDestination.nextSibling);
    arrInput.style.border = "none";
    }
   else
   {
    arrParent.appendChild(arrTarget);
    arrInput.style.border = "none";
    }
   }    
  }        
 arrNodesDestination = false;
 clearMovableDiv();
 }    
function saveArrangableNodes()
{
 var nodes = arrParent.getElementsByTagName('LI');
 var string = "";
 for(var no=0;no<nodes.length;no++)
 {
  if(string.length>0)string = string + ',';
  string = string + nodes[no].id + ' ' + nodes[no].innerHTML;        
  }
 document.forms[0].hiddenNodeIds.value = string;
 // Just for testing
 document.getElementById('arrDebug').innerHTML = 'Ready to save these nodes:<br>' + string.replace(/,/g,',<BR />');    
 }
function initArrangableNodes()
{
 arrParent = document.getElementById('arrangableNodes');
 arrMoveCont = document.getElementById('movableNode').getElementsByTagName('UL')[0];
 arrInsertDiv = document.getElementById('arrDestInditcator');
 leftPosArrangableNodes = getLeftPos(arrParent);
 arrInsertDiv.style.left = leftPosArrangableNodes - 5 + 'px';
 widthArrangableNodes = arrParent.offsetWidth;
 var subs = arrParent.getElementsByTagName('LI');
 for(var no=0;no<subs.length;no++)
 {
  subs[no].onmousedown = initMoveNode;
  subs[no].onselectstart = cancelEvent;
  arrSwitch[no] = true;    
  }
 document.documentElement.onmouseup = arrangeNodeStopMove;
 document.documentElement.onmousemove = arrangeNodeMove;
 document.documentElement.onselectstart = cancelEvent;
 }
function edit_text(obj,n)
{
 var n = n.substr(1);
 if(arrSwitch[n] == true)
 {
  arrSwitch[n] = false;
  obj.style.border = "1px solid #000";
  obj.readOnly = false;
  obj.select();
  }
 else if(arrSwitch[n] == false)
 {
  arrSwitch[n] = true;
  obj.style.border = "none";
  obj.readOnly = true;
  obj.blur();
  }
 }
window.onload = initArrangableNodes;
</script>
</head>
<body>
<div class="konaBody"><H2>Arrange the Articles below by drag'n drop</H2></div>
<form>
<ul id="arrangableNodes">    
    <li id="node11"><input id="i0" type="text" value="This is the title of an article" readonly /></li>
    <li id="node2"><input id="i1" type="text" value="Lorem ipsum dolor sit amet" readonly /></li>
    <li id="node5"><input id="i2" type="text" value="Excepteur sint occaecat" readonly /></li>
    <li id="node15"><input id="i3" type="text" value="Duis aute irure dolor in" readonly /></li>
    <li id="node3"><input id="i4" type="text" value="Sed do eiusmod tempor incididunt" readonly /></li>        
    <li id="node6"><input id="i5" type="text" value="Lorem ipsum dolor sit amet" readonly /></li>
    <li id="node14"><input id="i6" type="text" value="voluptatem sequi nesciunt" readonly /></li>    
    <li id="node7"><input id="i7" type="text" value="This is the title of an article" readonly /></li>
    <li id="node12"><input id="i8" type="text" value="This is the title of an article" readonly /></li>    
    <li id="node1"><input id="i9" type="text" value="Lorem ipsum dolor sit amet" readonly /></li>
    <li id="node8"><input id="i10" type="text" value="Duis aute irure dolor in" readonly /></li>        
    <li id="node10"><input id="i11" type="text" value="Sed do eiusmod tempor incididunt" readonly /></li>
    <li id="node13"><input id="i12" type="text" value="voluptatem sequi nesciunt" readonly /></li>    
    <li id="node4"><input id="i13" type="text" value="Excepteur sint occaecat" readonly /></li>
    <li id="node9"><input id="i14" type="text" value="Duis aute irure dolor in" readonly /></li>        
</ul>
</form>    
<p><a href="#" onclick="saveArrangableNodes();return false">Save</a></p>
<div id="movableNode"><ul></ul></div>    
<div id="arrDestInditcator"><img src="http://www.hotscripts.com/forums/images/insert.gif"></div>
<div id="arrDebug"></div>
<form><input type="hidden" name="hiddenNodeIds"></form>
</body>
</html>
__________________
Jerry Broughton

Last edited by job0107; 10-11-09 at 02:02 AM.
Reply With Quote
The Following User Says Thank You to job0107 For This Useful Post:
End User (10-11-09)
  #9 (permalink)  
Old 10-11-09, 08:07 AM
End User's Avatar
End User End User is offline
Level II Curmudgeon
 
Join Date: Dec 2004
Posts: 3,027
Thanks: 14
Thanked 35 Times in 33 Posts
Thank you again for your work on this! I'll have a look at it later today. It is a difficult script to work with, I can attest to that.

FWIW, I was working along a similar route with this, but with a different idea. Like you, I was also putting text input elements in the LI items, but I was trying to find a way to toggle the script on and off, essentially killing or suspending the draggability feature. I sort of got it working, but not to the point where I could use it. Oddly enough it worked well in IE but was inconsistent in Firefox, sometimes it worked, sometimes it wouldn't, sometimes it would leave an element orphaned in limbo.

I found one other script that looks promising, and that was the DnD script by Walter Zorn:

Drag, Snap and Sort

This one works except for one issue that should be a minor thing, but has me stymied. It allows putting input elements in the divs nicely and has a lot of great built-in options through the API....the thing that's stopping me is so silly I figure I must be an idiot: if I change the height and spacing of the divs, the snap feature gets all hammered and starts overlaying the divs. There are two parameters in that page that control the snap-to effect ('dy' and 'margTop'), but hell if I can figure out what they should be set to if the divs are made, say, 30px tall with a 3px spacing. It should be simple, but apparently I'm simpler. If you (or someone) could figure out the spacing issue on that, I'd name my next child after you.



Quote:
Originally Posted by job0107 View Post
This script is kind of difficult to work with.
But I have managed to get it to work.
It works very well in IE and works, but is a little clumsy in other browsers.

The way it works is like this:
When you click on a list item it goes into edit mode, at which time you can edit the contents.
When you click on it again it drops out of edit mode and retains the changes.
If you hold the mouse down on a list item, you will be able to move it.
You can change the sensitivity by changing the timer value of the setTimeout('timerMoveNode()',30); function in the timerMoveNode(obj) function.

The way I accomplished this is by putting your list items text in input elements.
Each input element must have a numeric id prefixed with the letter i.
__________________
I don't live on the edge, but sometimes I go there to visit.
-------------------------------------------------------------------------
Sanitize Your Data | Oracle Date & Substring Functions | Code Snippet Library | [url=http://www.codmb.com/Call Of Duty[/url]
Reply With Quote
  #10 (permalink)  
Old 10-14-09, 02:12 AM
job0107's Avatar
job0107 job0107 is offline
Community Liaison
 
Join Date: Dec 2006
Location: Tacoma, Washington USA
Posts: 3,454
Thanks: 0
Thanked 140 Times in 137 Posts
Hello again End User,
I found a solution for you.
This program will let you drag-&-drop and edit items in a <ul>.
It requires several javascript libraries which I will include as attachments.

Grab an item in the list and drag it to the desired position.
DoubleClick on an item and you will be able to edit it.
DoubleClick on the item again and the changes will be saved.

Here is a list of the javascript libraries:
builder.js
controls.js
dragdrop.js
effects.js
prototype.js
scriptaculous.js
slider.js

I put these files in the same directory as the program.
So if you put them in a different directory, then you will have to specify the directory path in these script declarations.
HTML Code:
<script src="prototype.js" type="text/javascript"></script>
<script src="scriptaculous.js" type="text/javascript"></script>
The only other javascript you will have to change is the script that selects the <ul> you want to use.
Use the attach_list() function to attach a <ul> by it's id.
And it is located at the end of the document.
HTML Code:
<script type="text/javascript" language="javascript" charset="utf-8">
attach_list('myList');
attach_list('myList2');
</script>
Ok, here is the program:
HTML Code:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>Edit in Place with JavaScript and CSS</title>
<style>
#myList
{
 padding:0px;
 margin:0px;
 width:300px;
 }
#myList li
{
 list-style-type:none;
 cursor:default;
 height:20px;
 border:1px solid #999;
 background-color:#ddf;
 margin-bottom:2px;
 padding:5px;
 }
#myList2
{
 padding:0px;
 margin:0px;
 width:300px;
 }
#myList2 li
{
 list-style-type:none;
 cursor:default;
 height:20px;
 border:1px solid #999;
 background-color:#cfc;
 margin-bottom:2px;
 padding:5px;
 }
#in
{
 position:absolute;
 width:285px;
 height:20px;
 padding:5px;
 display:none;
 }
</style>
<script src="prototype.js" type="text/javascript"></script>
<script src="scriptaculous.js" type="text/javascript"></script>
<script type="text/javascript">
function attach_list(list)
{
 Sortable.create(list,
 {
  ghosting:false, constraint:true, hoverclass:'over',onChange:function(element)
  {
   var totElement = document.getElementById("myList").getElementsByTagName("li");
   var newOrder = Sortable.serialize(element.parentNode);
   for(i=1; i<=totElement; i++)
   {
    newOrder = newOrder.replace("myList[]=","");
    newOrder = newOrder.replace("&",",");
    }
   }
  });
 }
var listObj = false;
var inputObj = false;
var listItemTop = false;
function editListItem(obj)
{
 listObj = obj;
 listItemTop = obj.offsetTop;
 inputObj = document.getElementById("in");
 inputObj.style.display = "inline";
 inputObj.style.top = listItemTop+"px";
 inputObj.value = obj.innerHTML;
 inputObj.focus();
 inputObj.select();
 }
function saveChanges()
{
 listObj.innerHTML = inputObj.value;
 inputObj.style.display = "none";
 }
</script>
</head>
<body>
<ul id="myList">
 <li id="item_1" ondblclick="editListItem(this);">Item 1a</li>
 <li id="item_2" ondblclick="editListItem(this);">Item 2a</li>
 <li id="item_3" ondblclick="editListItem(this);">Item 3a</li>
 <li id="item_4" ondblclick="editListItem(this);">Item 4a</li>
 <li id="item_5" ondblclick="editListItem(this);">Item 5a</li>
 <li id="item_6" ondblclick="editListItem(this);">Item 6a</li>
 <li id="item_7" ondblclick="editListItem(this);">Item 7a</li>
</ul>
<p>
<ul id="myList2">
 <li id="item_1" ondblclick="editListItem(this);">Item 1b</li>
 <li id="item_2" ondblclick="editListItem(this);">Item 2b</li>
 <li id="item_3" ondblclick="editListItem(this);">Item 3b</li>
 <li id="item_4" ondblclick="editListItem(this);">Item 4b</li>
 <li id="item_5" ondblclick="editListItem(this);">Item 5b</li>
 <li id="item_6" ondblclick="editListItem(this);">Item 6b</li>
 <li id="item_7" ondblclick="editListItem(this);">Item 7b</li>
</ul>
<input id="in" type="text" ondblclick="saveChanges();">
<script type="text/javascript">
attach_list('myList');
attach_list('myList2');
</script>
</body>
</html>
Attached Files
File Type: zip js_files.zip (63.1 KB, 10 views)
__________________
Jerry Broughton

Last edited by job0107; 10-14-09 at 02:23 AM.
Reply With Quote
Reply

Bookmarks


Currently Active Users Viewing This Thread: 1 (0 members and 1 guests)
 
Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are On

Forum Jump

Similar Threads
Thread Thread Starter Forum Replies Last Post
[SOLVED] Multi script PayPal add to cart order form Tito1 JavaScript 5 02-23-09 04:21 AM
Read from file, add to list Saturn Job Offers & Assistance 10 02-08-09 10:00 PM
Add images & search boxes in header & body to pulldowns hightechredneck JavaScript 0 09-17-08 12:11 PM
Add another two fields blinn_shade JavaScript 1 10-15-07 10:35 PM
Alter Table Help DDRcasey PHP 0 06-14-05 12:08 AM


All times are GMT -5. The time now is 01:57 AM.
vBulletin® Copyright ©2000 - 2012, Jelsoft Enterprises Ltd.