Showing posts with label scriptaculous. Show all posts
Showing posts with label scriptaculous. Show all posts

Monday, August 18, 2008

Drag & Drop Sortable Lists

I'm working on the ROTA module of Taskerbot now, which I've started and stopped at least three times. Par for the course, I've mostly forgotten whatever the hell I was doing last time I was working on it, so I'm starting over. Again. On the bright side, three years of occasionally working on the idea finally seems to have gelled in the back of my little tiny brain, and now I actually think I can do it, and make it fairly simple in fact, unlike the complex coding behemoth it began.

Tonight the challenge was the basic creation of the sort. The manager takes a list of his members and using simple drag & drop javascript, puts them in the sequence that he wants for event-assignment (usually, tasking).

First of all, there are some precompiled javascripts that help do all kinds of things more easily and more cross-browser compatible, so I went and got those. They are Prototype and Scriptaculous. I got the latest .js (javascript) file from each of those and put it in my directory, and added a head call to each.

<script language="JavaScript" src="../tbotscripts/prototype.js"></script>
<script language="JavaScript" src="../tbotscripts/scriptaculous/scriptaculous.js"></script>

OK, so that is set. (Note that scriptaculous is actually a small library of files; you need to put them all in the same directory, then just call the one.)

Then after searching I found a script (and I can't recall the source or I'd link to it) for the "sortable" feature.

However I could not figure out how to make it work with DIVs as I allegedly can use. Nor could I figure out how to make it write to a hidden HTML form field. After screwing with both of them for quite some time, I finally thought, why am I making this so hard? Yes it would be nice if I had the neat canned javascript for that but I don't, and there is definitely a manual way around it. These items are going to be looped out from a cfquery after all so it's not rocket science.

So I formatted the LI list elements to look like DIVs. And then I put a hidden field inside each of the list elements that would carry the userid (UID) value. When I call the name of that form field, it will automatically give me a comma delimited list of all the values set with that field name, in the sequence they are shown on the HTML form. I tested it and it works just fine.

So I added this to my HEAD section:

<style>
li { list-style-type: none; border: 1px black solid; padding:3px; margin:4px;
margin-top:6px; background-color: FFFFCC; color: black; width: 300px; }
</style>

And then I added this to my HEAD section:

<script language="JavaScript">
function getOrder() {
var orderList = '';
orderedNodes = document.getElementById("sortable_list").getElementsByTagName("li");
for (var i=0;i < orderedNodes.length;i++) {
orderList += orderedNodes[i].getAttribute('recordid') + ', ';
}
alert(orderList);
}
</script>

And here is a simple static version of the code for the sortable list in the page. Note the little script in there -- it must come AFTER the sortable list.

<form name="myform" method="post" action="working1.cfm">
<ul class="sortlist" id="sortable_list" style="cursor: move">
<li id="1" class="sortlist"><input type="hidden" name="uid" value="1">name 1</li>
<li id="2" class="sortlist"><input type="hidden" name="uid" value="2">name 2</li>
<li id="3" class="sortlist"><input type="hidden" name="uid" value="3">name 3</li>
<li id="4" class="sortlist"><input type="hidden" name="uid" value="4">name 4</li>
<li id="5" class="sortlist"><input type="hidden" name="uid" value="5">name 5</li>
</ul>
<script language="JavaScript">
Sortable.create("sortable_list");
</script>
<input value="Submit" type="submit" name="sub">
</form>

Of course if it were dynamic, the output would be more like:

<cfoutput query="myqueryname">
<li id="#myqueryname.uid#" class="sortlist"><input type="hidden" name="uid"
value="#myqueryname.uid#">#trim(myqueryname.username)#</li>
</cfoutput>

(No wrap in the LI line above--the PRE code puts it outside the display is all.)

>> Here is a full simple demo <<


Anybody should be able to copy the view-source from that and make it work.

Of course, this is actually the EASY part. It's working out all the dates and the looping that is considerably more work. That comes next!

PJ