Page 1 of 1

Having trouble moving list items up and down

Posted: Mon Jul 19, 2010 9:03 am
by UncleNinja
Hi DevNetwork people! :D
I try to google my fingers off before I post here, but I think I'm doing this wrong.

My goal is to simply move list items up and down. I have a simple solution - use insertBefore(). However, this does not seem to be working in Webkit browsers (Android, Safari, Chrome, etc) or Firefox. Sometimes you have to click one of the buttons up to three times before the list item actually moves! :?

Here's my JavaScript:

Code: Select all

function shift(direction, id) {
	var btn = document.getElementById(id);

	if (direction == "up") {

		var theParentNode = btn.parentNode;
		var thePrevSibling = btn.previousSibling;

		if (!thePrevSibling) {
			alert("Can't go up any higher!");
			return;
		}

		theParentNode.insertBefore(btn, thePrevSibling);

	} else if (direction == "down") {

		var theParentNode = btn.parentNode;
		var theNextSibling = btn.nextSibling;

		if (!theNextSibling) {
			alert("Can't go down any lower!");
			return;
		}

		theParentNode.insertBefore(theNextSibling, btn);

	}

}
and here's a relevant snippet of my HTML:

Code: Select all

	<ul>
		<li>I'm a special little list item.</li>
		<li id="exampleItem">
			<strong>Shift me!</strong>&emsp;
			<a class="shiftBtn" href="#" onclick="shift('up', 'exampleItem')">˄</a>&nbsp;
			<a class="shiftBtn" href="#" onclick="shift('down', 'exampleItem')">˅</a>
		</li>
		<li>I'm a list item.</li>
		<li>Another list item!</li>
	</ul>
Am I doing something wrong here? I'd like to avoid using JQuery or other JavaScript library and just learn how to write the right code.

An example is attached.

Thanks! :)

Re: Having trouble moving list items up and down

Posted: Mon Jul 19, 2010 3:42 pm
by kaszu

Code: Select all

<li>...</li>
<li id="qqq">...</li>
see line break after </li>, that's textNode and it's #qqq previousSibling, that's why nothing happens when you click button (it only looks like nothing is happening, actually it inserts LI before whitespace when you click link for first time).

See for nodeType https://developer.mozilla.org/en/nodeType
To make this work you need to get previous/next element instead of sibling.

Code: Select all

function previousElement(node) {
    while(node && node.nodeType != 1) node = node.previousSibling;  // 1 == Element, 3 == Text node
    return node;
}
function nextElement(node) {
    while(node && node.nodeType != 1) node = node.nextSibling;  // 1 == Element, 3 == Text node
    return node;
}

function shift(direction, id)  {
        var btn = document.getElementById(id);

        if (direction == "up") {

                var theParentNode = btn.parentNode;
                var thePrevSibling = previousElement(btn); //Changed this

                if (!thePrevSibling) {
                        alert("Can't go up any higher!");
                        return;
                }

                theParentNode.insertBefore(btn, thePrevSibling);

        } else if (direction == "down") {

                var theParentNode = btn.parentNode;
                var theNextSibling = nextElement(btn); //Changed this

                if (!theNextSibling) {
                        alert("Can't go down any lower!");
                        return;
                }

                theParentNode.insertBefore(theNextSibling, btn);

        }

}

Re: Having trouble moving list items up and down

Posted: Mon Jul 19, 2010 10:26 pm
by UncleNinja
Thanks! :D
I forgot about text nodes, naughty boogers.

That code is slick! Your website probably moves at like 5643 miles an hour! :D
That code works as long as you change the while to a do..while because the code inside the while must be run initially. :)

Thanks a grazillion kaszu! :D

Code: Select all

		function prevElement(node){
			do{
				node = node.previousSibling;
			}while(node && node.nodeType != 1);
			
			return node;
		}
		function nextElement(node){
			do{
				node = node.nextSibling;
			}while(node && node.nodeType != 1);
			
			return node;
		}