Forum Moderators: open

Message Too Old, No Replies

Assign z-index values to list items with javascript

         

maya

2:09 pm on Jun 11, 2009 (gmt 0)

10+ Year Member



Hi,

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!

Jesdisciple

3:41 am on Jun 12, 2009 (gmt 0)

10+ Year Member



I'm confused what this is about menus; can you show a working page without the new feature?

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]

maya

2:14 pm on Jun 15, 2009 (gmt 0)

10+ Year Member



Thanks for the reply.

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

Jesdisciple

4:11 pm on Jun 15, 2009 (gmt 0)

10+ Year Member



=\ You still didn't give a working page.

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.
};

Fotiman

4:28 pm on Jun 15, 2009 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



How do you define the "base" z-index values? That is, where does the value for the smallest value come from?

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?

maya

6:47 pm on Jun 15, 2009 (gmt 0)

10+ Year Member



@Fotiman:
Sounds great, thanks! I have no idea how gp about doing that though...do you have any examples?

@Jesdisciple:
I will post a working sample.

maya

8:56 pm on Jun 15, 2009 (gmt 0)

10+ Year Member



Here is a working sample. I've put in a z-index value for each LI so it decreases in value and the dropdowns work fine. If you move the one from the bottom to the top row you'll see that the dropdown goes behind the bottom two LI. I just need to figure out how to create that zindex value with a javascript so that it updates upon each move.

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>

Jesdisciple

5:51 am on Jun 16, 2009 (gmt 0)

10+ Year Member



I think you may be confused about what a z-index is. I actually requested the page to make sure before trying to correct you. While thinking about z-indices, I was uncertain that an array was appropriate in the finished solution, but the array fits what I see much better. In fact, we don't need to make an array because the DOM already does it.

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...]

DrDoc

4:53 pm on Jun 19, 2009 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Also, remember that
z-index
only works on positioned content. The default (
position: static
) won't work. Simply throwing in
position: relative
should work.

Jesdisciple

5:14 pm on Jun 19, 2009 (gmt 0)

10+ Year Member



Erm, I think I may have lost the OP with my long-winded explanation. *sigh* Oh well, I guess that means he would've never gotten through a page of the documentation either.