Forum Moderators: open
How can you specify the z-index for a sortable list so that the first
list element is the highest z-index and the last list element is the
lowest. I would also like the z-index to update itself as the user
resorts each list item. So if the bottom list element is moved to the
top, it's z-index would update to be the highest number and so on.
Is this possible?
I have a dropdown menu in each list item so when list items are moved up the dropdown will fall behind the list item below it.
Thanks!
But the general mechanics you describe are very simple. Maintain an array with all your items; when the user moves an item, you also move the array value and keep the array index consistent with the item's z-index.
[edited by: Jesdisciple at 3:42 am (utc) on June 12, 2009]
Basically it's just a list of records and each record/list item has information about the record ie: Name & description, then there is a small dropdown menu/button within that record that lists the options to edit the record. I need to use the dropdown menu/buton as there isn't enough room horizontally to fit in all the editing option links.
<ul id="list_to_sort">
<cfoutput query="getList">
<li id="item_#ID#>[item name] [item description][drop down menu here] <li>
</cfoutput>
</ul>
So for each list item I need to specify a z-index so as you go down the list items the z-index value decreases. When a list item is moved up or down by the user I need the z-index to automatically adjust based on it's new position.
I am not clear on how to maintain an array value with my items? Do you have any suggestions?
Thanks again
But the array can't be the entire implementation, because it only maps from the index to the item and we need to go in the other direction.
var elements = [];
//Add your items to the array and set their 'index' properties.
element.onclick = function(){
var value = elements[this.index];
//Umm... not sure what goes here.
};
Here's how I'd approach it.
When you "drop" an item, that event should trigger the following:
1. Get the parent <ul> element
2. Walk the ul's childNodes NodeList and store a reference to each child that is a <li> element in an array. As you store each item, perhaps also find the lowest z-index value.
3. When you have walked them all and you have stored the lowest z-index, you can now iterate back through the array, starting with the last item, setting the z-index and incrementing it with each loop iteration.
Note, you'll need to set the z-index as in inline style.
Does that help any?
I really appreciate your help!
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head><title>Sortable list</title>
<script type="text/javascript" src="/javascript/scriptaculous/prototype.js"></script>
<script type="text/javascript" src="/javascript/scriptaculous/scriptaculous.js?load=effects"></script>
<script type="text/javascript" src="/javascript/scriptaculous/dragdrop.js"></script>
<script type="text/javascript" src="/javascript/scriptaculous/effects.js"></script>
<!--DROP DOWN MENU--->
<script type="text/javascript">
<!--
var timeout = 500;
var closetimer= 0;
var ddmenuitem = 0;
// open hidden layer
function mopen(id)
{
// cancel close timer
mcancelclosetime();
// close old layer
if(ddmenuitem) ddmenuitem.style.visibility = 'hidden';
// get new layer and show it
ddmenuitem = document.getElementById(id);
ddmenuitem.style.visibility = 'visible';
}
// close showed layer
function mclose()
{
if(ddmenuitem) ddmenuitem.style.visibility = 'hidden';
}
// go close timer
function mclosetime()
{
closetimer = window.setTimeout(mclose, timeout);
}
// cancel close timer
function mcancelclosetime()
{
if(closetimer)
{
window.clearTimeout(closetimer);
closetimer = null;
}
}
// close layer when click-out
document.onclick = mclose;
// -->
</script>
<style>
#dragDrop { width: 30%;}
#dragDrop ul { list-style-type: none; margin: 0; padding: 0;}
#dragDrop li { width: 100%; margin: 0; padding: 0;}
#dragDrop li.sortlist {border-bottom: 1px solid #999999;}
#sddm{margin: 0;padding: 0;z-index: 30;}
#sddm li{margin: 0;padding: 0;list-style: none;float: left; font-size: 11px;}
#sddm li a{display: block; margin: 0 1px 0 0; background-color: none; text-align: left; text-decoration: none;}
#sddm li a:hover{color:8CB1BF; }
#sddm div {position: absolute;visibility: hidden;margin: 0;padding: 0; width: 184px;}
#sddm div ul { width: 184px; height: auto; list-style: none; margin: 0; padding: 0;text-align: left; position: absolute; background: #f4f0e9; border: 1px solid #DCD0B5; }
#sddm div li { width: 170px;padding: 6px; display: block; border-bottom: 1px solid #DCD0B5; list-style: none;float: left; }
#sddm div a
{position: relative;display: block;margin: 0; width: auto;white-space: nowrap;text-align: left;text-decoration: none; font-size: 11px; width: 180px; }
#sddm div a:hover {color: #8CB1BF}
</style>
</head>
<body>
<div id="dragDrop">
<ul class="sortlist" id="list_to_sort">
<li id="item_1" class="sortlist" style="position: relative; z-index:1000;">
<div style="float:left;">Item Name - Date - Detail - <span id="thehandle">REORDER</span></div>
<div style="float:right;">
<!--drop down menu--->
<ul id="sddm" style="width:130px;margin:0 auto">
<li><a href="#" onmouseover="mopen('mm1')" onmouseout="mclosetime()">EDIT</a>
<div id="mm1" onmouseover="mcancelclosetime()" onmouseout="mclosetime()">
<ul>
<li><a href="">Edit option 1</a></li>
<li><a href="">Edit option 2</a></li>
<li><a href="">Edit option 3</a></li>
</ul>
</div>
</li>
</ul>
<!--end drop down menu--->
</div>
<div style="clear:both;"></div>
</li>
<li id="item_2" class="sortlist" style="position: relative; z-index:999">
<div style="float:left;">Item Name - Date - Detail - <span id="thehandle">REORDER</span></div>
<div style="float:right;">
<!--drop down menu--->
<ul id="sddm" style="width:130px;margin:0 auto">
<li><a href="#" onmouseover="mopen('mm2')" onmouseout="mclosetime()">EDIT</a>
<div id="mm2" onmouseover="mcancelclosetime()" onmouseout="mclosetime()">
<ul>
<li><a href="">Edit option 1</a></li>
<li><a href="">Edit option 2</a></li>
<li><a href="">Edit option 3</a></li>
</ul>
</div>
</li>
</ul>
<!--end drop down menu--->
</div>
<div style="clear:both;"></div>
</li>
<li id="item_3" class="sortlist" style="position: relative; z-index:998">
<div style="float:left;">Item Name - Date - Detail - <span id="thehandle">REORDER</span></div>
<div style="float:right;">
<!--drop down menu--->
<ul id="sddm" style="width:130px;margin:0 auto">
<li><a href="#" onmouseover="mopen('mm3')" onmouseout="mclosetime()">EDIT</a>
<div id="mm3" onmouseover="mcancelclosetime()" onmouseout="mclosetime()">
<ul>
<li><a href="">Edit option 1</a></li>
<li><a href="">Edit option 2</a></li>
<li><a href="">Edit option 3</a></li>
</ul>
</div>
</li>
</ul>
<!--end drop down menu--->
</div>
<div style="clear:both;"></div>
</li>
</ul>
</div>
<script language="JavaScript">
Sortable.create("list_to_sort", {
elements:$$('#list_to_sort li.sortlist'),
handles:$$('#list_to_sort #thehandle'),
onUpdate: function() {
new Ajax.Request("updateRowOrder.cfm", {
method: "post",
parameters: { data: Sortable.serialize("list_to_sort") }
});
}
});
</script>
</body>
</html>
When you're standing on a sidewalk and a car passes between you and a building, the car has a higher z-index, relative to you, than the building. A z-index list would be rather odd because some items would be (partially) hidden from view. The page you sent has items with different y-indices (vertical) but identical z-indices (front-to-back).
Fotiman: I don't think we need to bother looping through the parent at all. For putting an element to the bottom of the list, we can
this.parentNode.appendChild(this); and the DOM will automatically remove the node before appending it. Throw in insertBefore, previousSibling and nextSibling and we can move anywhere we want in relation to other elements. If you want to go to a specific index, use childNodes to find the element that's already there and insertBefore to take its place. [developer.mozilla.org...]
[msdn.microsoft.com...]
[w3.org...]