Code:
^ Here is the best way to see the code and how it works with the divs
But here is the code anyway:
function move(from, to) {
document.getElementById('progress').innerHTML = '...';
from = parseInt(from,10);
to = parseInt(to,10);
tbc = document.getElementById(from);
before = document.getElementById(to);
containr = document.getElementById('alldivs');
neworder = 'Order: <select><option onclick="move(' + to + ',1)">1</option><option onclick="move(' + to + ',2)">2</option><option onclick="move(' + to + ',3)">3</option></select> <br><a href="#" onclick="move(' + to + ',' + (to - 1) + ')">Send up</a> | <a href="#" onclick="move(' + to + ',' + (to + 1) + ')">Send down</a><br><a href="#" onclick="move(' + to + ',1)">Bring to front (#1)</a> | <a href="#" onclick="move(' + to + ',4)">Send to back (#4)</a>';
document.getElementById(from).getElementsByClassName('order')[0].innerHTML = neworder;
document.getElementById(from).getElementsByClassName('number')[0].innerHTML = to;
tempdiv = document.createElement('div');
tmphtml = document.getElementById(from).innerHTML;
tempdiv.className = 'holder';
tempdiv.innerHTML = tmphtml;
n = 0;
npieces = 4;
if (from < to) {
nochanges = to - from;
fromone = from + 1;
//alert(n+' '+to+' '+fromone);
for (n = fromone; n <= to; n++) {
//alert('down');
idnum = parseInt(document.getElementById(n).id,10);
//alert(idnum);
document.getElementById(n).getElementsByClassName('number')[0].innerHTML = (idnum - 1);
alert(document.getElementById(n).id);
document.getElementById(n).id = (idnum - 1);
//alert('down '+idnum+' to '+(idnum-1));
}
}
if (from > to) {
nochanges = from - to;
totone = to + 1;
for (n = to; n < from; n++) {
//alert('n is '+n+' going to '+to+' ends at '+totone);
//alert('up');
idnum = parseInt(document.getElementById(n).id,10);
//alert(idnum);
document.getElementById(n).getElementsByClassName('number')[0].innerHTML = (idnum + 1);
alert(document.getElementById(n).id);
document.getElementById(n).id = (idnum + 1);
//alert('up '+idnum+' to '+(idnum+1));
}
}
//tempdiv.id = 'span'+to;
if (from > to) {
containr.insertBefore(tempdiv, before);
}
if (from < to) {
before = to + 1;
containr.insertBefore(tempdiv, document.getElementById(before));
}
tbc.parentNode.removeChild(tbc);
tempdiv.id = to;
document.getElementById('progress').innerHTML = 'done';
}
The script works as you move a block (or div) up or down, but when you try to move a different block (e.g. the one at the top), it just switches around the first two blocks beneath it.
Could anyone give me any advice?
I don’t know whether it’s because of the order that the script was done in, or if it’s something else. It’s been confusing me for some time, and I’d really appreciate it if someone could look through it and give me some advice.
(I don’t want to code it in jQuery, this is really just me trying to learn more JavaScript by coding something. If it’s not the most efficient, secure, whatever, it’s still just something with which I’m trying to teach myself JavaScript.)
Thank you for reading. (Please don’t edit the JS Fiddle itself, but rather post any edits/improvements here. Thank you.)
[Edit: I’m not really writing a cliche sci-fi, they’re just example divs because I couldn’t think of anything better]
In the statement
neworder =...you change the values of theonclickfunctions, but you only do this for the block that is about to be moved. The problem is that the other blocks also change positions. For instance, if you click on ‘Send up’ for block 2, then block 2 moves up to position 1 and block 1 moves down to position 2. But only the event handlers on block 2 are updated accordingly. So the next time you click on (what was originally) block 1, it will not behave correctly.One solution would be to update the event handlers on all of the blocks that are affected every time one of them is moved. For instance, make a function called
updateEventHandlers(blockNumber)and call it for all of the affected blocks.However relying on IDs to indicate the position of a block and then fiddling with the IDs after they are moved can lead to all sorts of confusion. It is better either to keep an array or dictionary recording the positions of the blocks, or loop through them to determine their positions in the DOM each time you want to move them.
For instance the following code provides moveup, movedown and moveto functions using the latter method (it finds where the element is in the DOM and swaps it with the holder before or after). (JSFIDDLE)
A few other points:
selects in your original code won’t do anything initially, because no event handler is assigned to it until after one of the elements has been moved</div>from the end of the htmlvarsomewhere in your code