joequery/Stupid-Table-Plugin

Sorting on live-sortvalues

captain-rob opened this issue · 5 comments

Hey there,

I am in need of sorting the table based on live-sortvalues.

Background, I try to display a table which serves as an input mask. The table cell values are both, plain readonly values and input fields as well.
Something like:

<td data-sort-value="Some plain text">
    Some plain text
</td>
<td data-sort-value="5">
    <input id="sampleId" value="5" size="1">
</td>

The data-sort-values are updated properly by onchange-handlers which are connected to the input fields. However, changing input-field-values and sorting in that manner only works on the first sort step of the table. Every further update of the data-sort-value after the first process step doesnt influence sort behaviour.

The table instance seems to be bound/cached somewhere what causes to sort by original sort-values.

Is there some way to reset/reinitialize the instance to retrieve and sort by "live"-sort values? Debugged and fiddled somewhat around myself, added reset callbacks and so on, but didn't it get to work ...

Issue is reproducable on http://rawgit.com/joequery/Stupid-Table-Plugin/master/examples/complex.html

1: Change sort value of letter T (letter frequency) to 2 (live in html, tried it with firebug)
2: Change sort value of letter A to 1
3: Click letter frequency to sort once (changing sort of T to 2 forces T to appear in the middle and A above T)
4: Change sort values back (T back to 1 and A back to 2)
5: Click letter frequency again, letter T is expected to appear on its original position (as original sort value is being used again) and letter A in the middle
6: However, sort values after first sort step are not determined properly anymore what causes A and T to be sorted by their deprecated sort-values

This may be related to a discussion that occurs at the bottom of #122 (namely this comment here: #122 (comment))

Basically, as is, you have to set the .data of the table cell to the new value, as jQuery's .data only reads from the html data attributes initially. I'm open to changing this behavior since I agree it's fairly confusing.

Thanks for your quick reply, didn't have time to check this so far.

Ok I tinkered a bit with .data and .attr and found a solution which works for me (as you said).
E.g., the issue mentioned before (sorting of T and A in complex table on http://rawgit.com/joequery/Stupid-Table-Plugin/master/examples/complex.html) can be solved as follows:

// updating sort values before the first sort step:
$("td:contains('T')").attr('data-sort-value', '2');
$("td:contains('T')").data('sort-value', '2');
$("td:contains('A')").attr('data-sort-value', '1');
$("td:contains('A')").data('sort-value', '1');

// changing values back after the first sort step:
$("td:contains('T')").attr('data-sort-value', '1');
$("td:contains('T')").data('sort-value', '1');
$("td:contains('A')").attr('data-sort-value', '2');
$("td:contains('A')").data('sort-value', '2');

This solution seems to be reliable, double-executing update scripts is a bit painful though.

It's a bit painful, I agree. I haven't decided the best way to proceed yet.

Well, as you mentioned in the other issue,
var sort_val = $e.attr("data-sort-value");
should be a good kickoff.

You might sync internal data value to ensure consistency of both:
$e.data("sort-value", sort_val);

So developers should not be in need to update both, "data-sort-value" and "sort-value". This also fits more to your documentation as your "interface" only provides a "data-sort-value"-attribute ... we only know about jQueries internal "sort-value" because we got into trouble with a bug, or ... a weird feature ;-)

I am just progressing my code and want to let you know that, if you want to update sort-value with the actual data-sort-value of the cell, you need to be aware of event-orders.

E.g. (considering my example) if an input-field has the focus after changing its value and you immediately click on a table-header without explicitly leaving the input-field, the blur-handlers won't be fired in time before the sort-process starts (Firefox 34.0).

So i needed to add
$('#someId').stupidtable().bind('beforetablesort', function() {
if (document.activeElement != document.body) {
document.activeElement.blur();
}
});

Otherwise you might retrieve deprecated sort-values. I am convinced the same problem occurs with change-handlers.
Also take care of doing .blur() only on childrens of document.body. Internet Explorer 9 (if I remind correctly) shifts the entire window to background by some weird reason when document.body gets blurred (scratching hair).

I'll need to run some jsperf tests to test .attr speed vs .data speed for a large number of elements. The nice thing about .data is that you get a cache to work with, and we could provide a method to invalidate the cache when table values have been updated. If .data's cache is significantly faster than accessing the attribute/text value every time, this is probably the approach I'll take. If it's not significantly faster, the plugin will read directly from the attribute.