Open josephpoff opened 11 years ago
Client side sorting will be implemented in the future. But, for now, I don't know an easy way for that, sorry.
I suppose an easy solution would be for jTable to provide the current page size and sort method when inserting a row and to accept another parameter on the result object called "goToPage" where the server would return what page to display. That way it would be up to the developer to figure out a good way to do it.
Sidenote: there really isn't a great way to do it server side. But, it would look something like this:
// assuming that $pageSize and $sortMethod are already set with what was provided by jTable
mysql_insert("insert into bla bla bla"); // assuming the row was successfully inserted $id = mysql_insert_id(); // id of new row
$res = mysql_query('select id from my_table order by' . $sortMethod); $rowPosition = 0; while ($row = mysql_fetch_assoc($res)) { if ($row['id'] == $id) { break; } $rowPosition ++; }
$pageToDisplay = floor($rowPosition / $pageSize);
die(json_encode(array('Result' => 'OK', 'goToPage' => $pageToDisplay)));
Note: if you've got a large table, this isn't a good thing.
Thanks OHB, but I'm not inserting rows. I'm updating values within currently visible rows using...
.jtable('updateRecord', { record: record, clientOnly: true });
This is called from the server using SignalR. I am passing the updated record from the server to the client (called "record" in the above example). Then I perform the update. This works flawlessly to update the already available record. Also, with this setup, I have turned of pagination (for now).
I'm currently looking at using the jtable-applied "data-record-key" attribute to compare positions between my updated record index and the client index as well as using something like $rowa.insertBefore($rowb). This general functionality works but I have to get the indexes right because they are changing with each position change. I'm still wrapping my head around it....I need more coffee. I'll update here if I get a solution.
Ok I have a solution to fulfill my need. I'll share here in case anyone else wishes to fix (use) it or make it better. =)
I'm storing sort parameters and posting them back to the server so that the SignalR process can order the incrementally returned record list. So there is a post to update the sort parameter. All columns are sortable in this table.
$('.jtable-column-header').click(function (e) {
var columnName = columnNameify(this.innerText);
var replaceMe = false;
if (!e.ctrlKey) {
sortValue = "";
}
else {
if (sortValue.indexOf(columnName) !== -1) {
replaceMe = true;
}
}
if ($(this).hasClass('jtable-column-header-sorted-asc')) {
if (sortValue == "") {
sortValue = columnName + " ASC";
} else {
if (replaceMe) {
sortValue = sortValue.replace(columnName + " DESC", columnName + " ASC");
} else {
sortValue = sortValue + "," + columnName + " ASC";
}
}
}
if ($(this).hasClass('jtable-column-header-sorted-desc')) {
if (sortValue == "") {
sortValue = columnName + " DESC";
} else {
if (replaceMe) {
sortValue = sortValue.replace(columnName + " ASC", columnName + " DESC");
} else {
sortValue = sortValue + "," + columnName + " DESC";
}
}
}
replaceMe = false;
$.post('@Url.Action("SetSortParameters")', { sort: sortValue });
});
function columnNameify(columnName) {
var regex = new RegExp(" ", 'g');
columnName = columnName.replaceAt(0, columnName.charAt(0).toLowerCase());
columnName = columnName.replace(regex, '');
return columnName;
}
String.prototype.replaceAt = function (index, character) {
return this.substr(0, index) + character + this.substr(index + character.length);
}
Then when the periodic SignalR process completes, I send the records to the client in the new order. They are compared to what is currently shown in the table, and the rows are moved.
hub.client.updateComplete = function (records) {
var $table = $('.jtable');
var $rows = $('tbody > tr', $table);
var $rowa;
var $rowb;
var indicesStringA = "";
var indicesStringB = "";
for (var i = 0; i < records.length; i++) {
if (records[i].symbolicName != $rows.eq(i).attr('data-record-key')) {
$rowa = $("tr[data-record-key='" + records[i].symbolicName + "']");
if (indicesStringA == "" && indicesStringB == "") {
indicesStringA = $rowa.index();
indicesStringB = i;
}
else {
indicesStringA = $rowa.index() + "," + indicesStringA;
indicesStringB = i + "," + indicesStringB;
}
}
}
if (indicesStringA != "") {
var indicesA = indicesStringA.split(',');
var indicesB = indicesStringB.split(',');
for (var i = 0; i < indicesA.length; i++) {
$rowa = $("tr[data-record-key='" + $rows.eq(indicesA[i]).attr('data-record-key') + "']")
$rowb = $("tr[data-record-key='" + $rows.eq(indicesB[i]).attr('data-record-key') + "']")
if (indicesB[i] == 0) {
$table.prepend($rowa);
$rowa.effect("highlight", {}, 3000);
}
else {
$rowa.insertBefore($rowb).effect("highlight", {}, 3000);
}
}
}
};
It's not perfect but it works well for what I was looking for.
Thanks for sharing @josephpoff
Dear Josephpoff,
I'm quite lost on how and where to use updateRecord. Perhaps you can show me a little. I just don't get it how does it work.
Thanks.
@kjoye I used the updateRecord function to dynamically update records on the page. I integrated this with signalR which is a real-time push messaging framework. I would enable some auto-update funcitonality that I wrote. When a record gets updated (from a server-side webservice call in my case), the client would get the newly updated record and call the updateRecord function. This invokes the normal update effect (color fade in/fade out) on the record.
Here is the documentation on how to use the updateRecord function.
Guys, what I'm trying to do is to have another column, which the content is only available if certain creteria met. What have I missing here? I'm getting this console error message. jTable WARNING: options parameter in updateRecord method must contain a record that contains the key field property.
fields: { id: { key: true, title: 'ID', list: true, edit: false }, StaffID: { title: 'ID', width: '1%', create: false, input: function (data) { return ''; } }, StaffName: { title: 'Name', width: '10%', create: false, edit: false }, leaveCanceled: { title: 'leaveCanceled', //create: false, //edit: false, //list: false }, flagMark: { title: 'Status', width: '0.5%', create: false, edit: false, display: function (data) { if (data.record.flagMark == "0") { var $img = $(''); $img.tooltip({ track: true }); return $img; } else if (data.record.flagMark == "1") { var $img = $(''); $img.tooltip({ track: true }); return $img; } else if (data.record.flagMark == "2") { var $img = $(''); $img.tooltip({ track: true }); return $img; } else if (data.record.flagMark == "3") { var $img = $(''); $img.tooltip({ track: true }); return $img; } else if (data.record.flagMark == "4") { var $img = $(' '); $img.tooltip({ track: true }); return $img; } } }, edtRec: { title: 'test', sorting: false, width: '0.2%', display: function (data) { var $img2 = $(''); //if(data.record.edtRec=="4"){ // return 'test'+data.record.edtRec; //} $img2.click(function () { $('#tblUserView').jtable('updateRecord', { fields: { id: { key: true, title: 'ID', list: true, edit: false }, StaffID: { title: 'ID', width: '1%', create: false, edit: false }, StaffName: { title: 'Name', width: '10%', create: false, edit: false }, leaveCanceled: { title: 'leaveCanceled' //create: false, //edit: false, //list: false } }, record: { id: data.id, StaffID: data.StaffID, StaffName: data.StaffName, leaveCanceled: data.leaveCanceled } }); }); return $img2; } } }
I think I got it. Thanks anyway.
I am curious if there is a way to apply the currently set sort after an updateRecord has been performed.
I have a site which lists web service status information. These will be sorted by active/down status showing the down web services at the top. This is being updated periodically with signalR. It works very well except when a record is updated from an "Active" status to a "Down" status, it does not automatically move to its proper location. This may fall in line with client-side sorting mentioned in another thread. See example...
Records before: D A A A A
Records after: D A A D ----> Out of order now. A
With all of the signalr code and automatic row updates, I don't want to simply do a table refresh and force a callback to obtain the entire list again. Is there a trick anyone can think of to apply the active sort to an updated record/row?