So, a while ago I released a custom tag called Slush. It was a custom tag that would generate a Flash Form control allowing for left/right controls using select boxes. A user asked me if I had anything like that but with Up/Down type controls. In other words, he wanted to order items in a select box.

This isn't too hard to do. I'll show the code then talk about it a bit:

<cfform format="flash" width="600" height="200">

   <cfsavecontent variable="fix">
   var t2:Array = Array();
   for(var i=0; i < people.getLength();i++) {
      t2.push(people.getItemAt(i).data);
   }
   people_list.text = t2.join(",");
   </cfsavecontent>
   
   <cfsavecontent variable="moveUp">
      if(people.selectedIndex > 0) {
         var pos = people.selectedIndex;
         var temp = people.getItemAt(pos);
         people.addItemAt(pos-1,temp);
         people.removeItemAt(pos+1);
         people.selectedIndex = pos-1;
         <cfoutput>#fix#</cfoutput>
      }
   </cfsavecontent>

   <cfsavecontent variable="moveDown">
      if(people.selectedIndex+1 < people.length) {
         var pos = people.selectedIndex;
         var temp = people.getItemAt(pos+1);
         people.addItemAt(pos,temp);
         people.removeItemAt(pos+2);
         <cfoutput>#fix#</cfoutput>
      }
   </cfsavecontent>
   
   <cfformgroup type="horizontal">

      <cfselect name="people" multiple size="4" width="200">
      <option value="1">Apple</option>
      <option value="2">Beta</option>
      <option value="3">Caladium</option>
      <option value="4">Death Star</option>
      </cfselect>

      <cfformgroup type="vertical">
         <cfinput type="button" name="moveUp" value="Up" onClick="#moveUp#">
         <cfinput type="button" name="moveDown" value="Down" onClick="#moveDown#">
         <cfinput type="submit" name="submit" value="Save">
      </cfformgroup>
      
   </cfformgroup>

   <cfformgroup type="horizontal" visible=true height="0">
      <cfinput type="text" name="people_list" value="1,2,3,4">
   </cfformgroup>
      
</cfform>

<cfdump var="#form#">

First off - this isn't a custom tag version, but it could be changed into it. The first thing you should note is the cfselect box. This is the container for options that we will sort. Next note the Up and Down button. They use the code defined above in the moveUp and moveDown cfsavecontent blocks. The action script is, genrally, understandeable. It's pretty close to how you would do it in JavaScript.

So far - this is mostly trivial code. What isn't trivial is how you pass the order to the server. By default, a select box with the multiple option will pass no data if you don't select anything. I don't want to force the user to Select All before hitting submit, so I made a little hack. I added an invisible form field called people_list. Whenever the drop down is reordered, I repopulate the value property using the code defined in cfsavecontent block named "fix".

Thoughts? I'd be shocked if the folks at ASFusion.com don't have a much more elegant solution, so check there as well.