Learning jQuery, Day 7 : Sortable Checked Lists
In Day 6 of Learning jQuery, I mentioned a project we had completed that dealt with work orders. Part of the job entails office staff processing completed work orders. In their line of business, they want certain staff members to process certain work order types -- and in a certain order. Let's use some jQuery to make this happen.
First, let me explain a bit more about the requirement. Let's say that our client has five types of work orders: initial, bid, initial bid, bid approval, reo, and recut. Our client has four office staff that process these work orders, but, as it turns out, not all of the staff can process all the work orders. Here's the logic behind their procedure:
Ann: handles reo, bid, and recut
Bob: handles bid and initial bid
Carla: handles recut and reo
Dan: handles bid approval and initial bid
That should be easy enough; we could just give the administrator a series of checkboxes for each office staff and let them select the work order types each staff member can handle. At processing time, we'll have a query that returns only those work order types that match the authorized ones. But there's a catch. They also want the work orders valid for each person to be processed in a specific order. Ann may handle reo, bid, and recut, but it's important that they be handled in that order. The problem is the intended order may not match the checkboxes on our page.
This is the sort of thing that makes complete sense to business people, but isn't often easy to implement. We've all seen the sort of UI that has checkboxes with accompanying text boxes into which the administrator is supposed to type the order number. Well, that works but what's that you say? You find it to be highly nonpulchritudinous? Well, I agree.
Instead of this ugly solution, let's create a more comely one: checkboxes that the administrator can slide to show ordering. Something like this, perhaps: http://dev.citymind.com:8500/test/blog_jquery/day7/form.processTypes.cfm. You can check the various work order types and slide them to the proper order. Here's how I did it.
I start with a basic HTML form, form.processTypes.cfm:
<form id="form_processor">
<input type="hidden" id="sorted_checked_types" />
<ul id="process_types_sorter">
<li class="process_type" id="bid">
<input class="workorder_type" type="checkbox" name="bid" value="bid"> Bid
</li>
<li class="process_type" id="initial_bid">
<input class="workorder_type" type="checkbox" name="initial_bid" value="initial_bid"> Initial Bid
</li>
<li class="process_type" id="bid_approval">
<input class="workorder_type" type="checkbox" name="bid_approval" value="bid_approval"> Bid Approval
</li>
<li class="process_type" id="reo">
<input class="workorder_type" type="checkbox" name="reo" value="reo"> REO
</li>
<li class="process_type" id="recut">
<input class="workorder_type" type="checkbox" name="recut" value="recut"> Recut
</li>
</ul>
<input type="submit" value="OK">
</form>
<cfinclude template="form.processTypes.pgm">
Notice the CFINCLUDE at the bottom that includes this JavaScript/jQuery code:
<link type="text/css" href="/fpp/jquery/jquery-ui-all-cupertino/css/cupertino/jquery-ui-1.7.custom.css" rel="Stylesheet">
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js"></script>
<script type="text/javascript" src="/fpp/jquery/jquery-ui-all-cupertino/js/jquery-ui-1.7.custom.min.js"></script>
<script type="text/javascript">
function sortTypes(){
var sortArray = new Array();
var sorts = $('##process_types_sorter').sortable('toArray');
for (var i=0; i<sorts.length; i++){
if ($('.workorder_type[name=' + sorts[i] + ']').attr('checked')){
sortArray.push(sorts[i]);
};
};
return sortArray.slice(',');
};
$('##process_types_sorter').sortable({
placeholder: 'ui-state-highlight',
cursor: 'move',
opacity: 0.6,
update: function(event, ui){
$('##sorted_checked_types').val(sortTypes());
}
});
$('.workorder_type').click(function(){
$('##sorted_checked_types').val(sortTypes());
});
</script>
</cfoutput>
I've linked to a stylesheet for a particular themed version of the jQuery UI library. (You can select your own theme and download the customized code at jquery.com.)
Next, I include the script files for the base jQuery library (which I've gotten from the Google repository) and the customized jQuery UI code.
This code makes the work order types sortable:
placeholder: 'ui-state-highlight',
cursor: 'move',
opacity: 0.6,
update: function(event, ui){
$('##sorted_checked_types').val(sortTypes());
}
});
I've included some options with the call to the "sortable" function, the most important of which is an "update" option -- a function to be run when the user completes a drag/drop operation. Within this function, I insert a value into the hidden field, "sorted_checked_types". That value is a comma-delimited string of the checked values in their correct sorting order.
The code that does the sorting is in the stand-alone function, "sortTypes". In that function, I create an array, "sortArray". Then, I make a call to the jQuery UI library, asking to to get the values of the LI elements' "id" attribute and place them in a variable called "sorts". At this point, we have all elements, checked or not. They're in the right order, but we only want the elements that have been checked.
I accomplish this by looping over the "sorts" array and seeing whether the corresponding checkbox is, in fact, checked. If it is, I "push" it into "sortArray". Finally, I use "sortArray.slice(',')" to turn "sortArray" into a comma-delimited list.
We're almost done, but we need to handle the possibility that the administrator might check the type boxes, but not sort them. This code handles that case:
$('##sorted_checked_types').val(sortTypes());
});
Now, our form is set and we can submit it either normally or through jQuery's Ajax methods.


There are no comments for this entry.
[Add Comment]