Wednesday, March 11, 2009

Working with JQuery Tablesorter Parser Input Fields

I've recently had to deal with JQuery's tablesorter. the trouble was, it had a problem sorting form input fields in columns. The columns sorted fine when they were static text, but when each column was a form entry field of <input type="text" ...> it wouldn't sort. this is because it was trying to sort the HTML of "<input ..." instead of the field value.

The solution to this took a little googleing and a bit of creative coding. My first solution was to use a regex to recognize the value="aaaa" and replace it to have the parser work on that text. The yucky factor was big.

Instead, I found the concept of using a val function on the text. This ended up being two parsers, because one of my input fields was a numeric value.

Here's the text:

$.tablesorter.addParser({
id: "textbox_text",
is: function(s) {
return false;
},
format: function(s) {
return $($.trim(s)).val().toLowerCase();
},
type: "text"
});

$.tablesorter.addParser({
id: "textbox_numeric",
is: function(s) {
return false;
},
format: function(s) {
return $($.trim(s)).val().toLowerCase();
},
type: "numeric"
});

$.tablesorter.addParser({
id: "checkbox_parser",
is: function(s) {
return false;
},
format: function(s) {
ret = $($.trim(s)).attr('checked');
return ret
},
type: "numeric"
});

$(document).ready(function()
{
$("#docReqTable").tablesorter(
{ widgets: ['zebra'],
sortColumn: 1,
sortClassAsc: 'headerSortUp', // class name for ascending sorting action to header
sortClassDesc: 'headerSortDown', // class name for descending sorting action to header
headerClass: 'header', // class name for headers (th's)
stripingRowClass: ['even','odd'], // class names for striping supplyed as a array.
stripRowsOnStartUp: true,
sortList: [[1, 0]],
headers: {
0 : { sorter : 'checkbox_parser' },
1 : { sorter : 'textbox_text' },
3 : { sorter : 'checkbox_parser' },
4 : { sorter : 'textbox_numeric' },
5 : { sorter : 'textbox_numeric' },
},
debug: true,
});
});


I'm having trouble now because I type in the input fields, and then click on a header to re-sort the data, and it doesn't sort to the top. That is, dynamically updating the values in the table doesn't allow a sorton operation in JQuery tablesorter to recognize the new values.

We already had a method to change the mouse pointer to a 'hand' when it mouseover'd the table header, so it looked like a clickable link there (a good visual clue to the user that the table really is sortable).

So, I tried adding a couple of methods I found online to the mouseover code to see if they would update the cache and allow resort based on the dynamically changed values inside the textbox. I even put some code in the tablesorter.js file for reSort_A and reSort_B that tried some things, to no avail.

The code for that is:

...
th onMouseOver="setPointerHand(this);" onMouseOut="setPointerDefault(this);" class="{sorter: 'text'}"
...
function setPointerHand(method)
{
document.body.style.cursor = 'hand';
$(docReqTable).trigger("appendCache");
$(docReqTable).trigger("update");
$(docReqTable).trigger('reSort_B');
$(docReqTable).trigger('applyWidgets');
return false;
}

function setPointerDefault(method)
{
document.body.style.cursor = 'default';
$(docReqTable).trigger("appendCache");
$(docReqTable).trigger("update");
//$(docReqTable).trigger("log", "doing stuff");
$(docReqTable).trigger('reSort_B');
$(docReqTable).trigger('applyWidgets');
return false;
}



That's as far as I've gotten. If anyone has clues for how to make the update / re-sort work well, please reply on this blog or otherwise post it!

5 comments:

dthollis said...

Hey this is exactly what we were looking for. Could you post a zip file of an example. We are unable to get it to work with a text_numeric. Any advice?

Our sample code:
$.tablesorter.addParser({
id: "textbox_numeric",
is: function(s) {
return false;
},
format: function(s) {
return $($.trim(s)).val().toLowerCase();
},
type: "numeric"
});

$(document).ready(function()
{
$(".tbl").tablesorter(
{
widgets: ['zebra'],
headers: {
1 : { sorter : 'textbox_numeric' }
}
});
}
);

abbot said...

thank you so much!!!

abbot said...

The re-sort after data change:
I used this:
$(".allocation").change(function() {
$("#GridView2").trigger("update");
$("#GridView2").trigger("appendCache");
});
.allocation is a class I have added to each textbox in the table called GridView2.
This worked i.e would sort by newly changed textbox values

mammuskitchen said...

I added a hidden field inside td tag:
(input type="hidden" value="actualTextBoxValue) before adding the input field.
This works well for sorting input fields.
actualTextBoxValue is the actual value the text box holds.

Parag said...

The solution provided by abbot worked for me. Thanks