DataTables edit Locally

Currently, the app reloads the entire data set after every addition and every row edit. Not a problem with small sets, but a significant performance penalty when dealing with large ones. Let’s fix that by interacting directly with local DataTables data set in the browser.

Our first step is to switch from the dataTable() constructor to the DataTable() constructor. This gives us read/write access to pages, rows, cells, … (also available via the new api() method added to the dataTable object).

1
2
3
4
5
6
7
8
9
10
11
12
13
diff --git a/src/main/webapp/index.html b/src/main/webapp/index.html
index 4cbbd99..3c50411 100644
--- a/src/main/webapp/index.html
+++ b/src/main/webapp/index.html
@@ -94,7 +94,7 @@
userMap = userMap + window.location.search;
}
$(document).ready(function() {
- $('#users').dataTable({
+ $('#users').DataTable({
"ajax": userMap,
"columns": [
{ "data": "email" },

Adding the new row to the table is easy - simply update the userPost function to add the new data row and redraw the table instead of reloading the data. Passing false to the DataTables draw function keeps the current paging position.

1
2
3
4
5
6
7
8
9
@@ -132,7 +132,7 @@
},
success: function(data,status,xhr){
form[0].reset();
- $('#users').dataTable().api().ajax.reload();
+ $('#users').DataTable().row.add(JSON.parse(data)).draw(false);
}
});
}

Updating the edit function is a bit more involved. First, update the edit anchor function to make the click context available to the setUserEdit function. The setUserEdit function will use that context to set the selected class on the row containing the edit anchor for easy identification after the edit succeeds on the back end.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
@@ -104,7 +104,7 @@
"orderable": false,
"searchable": false,
"render": function(data,type,row,meta) {
- var a = '<a onclick="setUserEdit(\''+row.email+'\',\'' + row.givenName + '\',\'' + row.surname + '\')"><i class=
"fa fa-edit"></i></a>';
+ var a = '<a onclick="setUserEdit.call(this,\''+row.email+'\',\'' + row.givenName + '\',\'' + row.surname + '\')"
><i class="fa fa-edit"></i></a>';
return a;
}
}
@@ -162,6 +164,7 @@
}
});
function setUserEdit(email, givenName, surname ) {
+ $(this).closest('tr').addClass('selected');
var form = $('form#add-user')[0];
form.reset();
form.elements['email'].value = email;

When the edit succeeds on the back end, update the selected row with the data returned from the server and remove the selected class. If the edit fails on the back end, then remove the selected class from the row.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
@@ -146,10 +146,12 @@
contentType: "application/json; charset=utf-8",
error: function(xhr,status,error) {
bootbox.alert(xhr.responseText);
+ $('#users tbody tr.selected').removeClass('selected');
},
success: function(data,status,xhr){
form[0].reset();
- $('#users').dataTable().api().ajax.reload();
+ $('#users').DataTable().row('.selected').data(JSON.parse(data)).draw(false);
+ $('#users tbody tr.selected').removeClass('selected');
}
});
}

Finally, add a cleanup action to the cancel button on the modal - removing the selected class off of the row.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
@@ -77,7 +77,7 @@
<div class="form-actions">
<p>
<button type="submit" class="btn btn-primary" data-dismiss="modal" id="user-post">Submit</button>
- <button type="button" class="btn" data-dismiss="modal">Cancel</button>
+ <button type="button" class="btn" data-dismiss="modal" id="cancel-post">Cancel</button>
</p>
</div>
</form>
@@ -154,6 +154,7 @@
});
}
$('button#user-post').click(userPost);
+ $('button#cancel-post').click(cancelPost);
$('#add-user-modal').on('shown.bs.modal',function(e){
if ( modeAdd ) {
$('#add-user-email').focus();
@@ -180,6 +182,9 @@
$('#user-post').bind('click',userPost);
$('#add-user-modal').modal('show');
}
+ function cancelPost() {
+ $('#users tbody tr.selected').removeClass('selected');
+ }
</script>
</body>
</html>

The full source for this version of Jersey, Gson and Datatables is on github.

21 Jun: JQuery Ajax and Selenium
16 Aug: DataTables, Bootstrap and Text Overflow