An example of how DataTables 1.10 can be used with Knockout.JS observables. The table below will automatically update as the values of the underlying data in the Knockout observableArray
is updated, new rows added and old rows deleted.
ID | Name | Age |
---|
// Helper function so we know what has changed // http://stackoverflow.com/questions/12166982 ko.observableArray.fn.subscribeArrayChanged = function(addCallback, deleteCallback) { var previousValue = undefined; this.subscribe(function(_previousValue) { previousValue = _previousValue.slice(0); }, undefined, 'beforeChange'); this.subscribe(function(latestValue) { var editScript = ko.utils.compareArrays(previousValue, latestValue); for (var i = 0, j = editScript.length; i < j; i++) { switch (editScript[i].status) { case "retained": break; case "deleted": if (deleteCallback) deleteCallback(editScript[i].value); break; case "added": if (addCallback) addCallback(editScript[i].value); break; } } previousValue = undefined; }); }; // Person object var Person = function(data, dt) { this.id = data.id; this.first = ko.observable(data.first); this.last = ko.observable(data.last); this.age = ko.observable(data.age); this.full = ko.computed(function() { return this.first() + " " + this.last(); }, this); // Subscribe a listener to the observable properties for the table // and invalidate the DataTables row when they change so it will redraw var that = this; $.each( [ 'first', 'last', 'age' ], function (i, prop) { that[ prop ].subscribe( function (val) { // Find the row in the DataTable and invalidate it, which will // cause DataTables to re-read the data var rowIdx = dt.column( 0 ).data().indexOf( that.id ); dt.row( rowIdx ).invalidate(); } ); } ); }; // Initial data set var data = [ { id: 0, first: "Allan", last: "Jardine", age: 86 }, { id: 1, first: "Bob", last: "Smith", age: 54 }, { id: 2, first: "Jimmy", last: "Jones", age: 32 } ]; $(document).ready(function() { var people = ko.mapping.fromJS( [] ); var dt = $('#example').DataTable( { columns: [ { data: 'id' }, { data: 'first()' }, { data: 'age()' } ] } ); // Update the table when the `people` array has items added or removed people.subscribeArrayChanged( function ( addedItem ) { dt.row.add( addedItem ).draw(); }, function ( deletedItem ) { var rowIdx = dt.column( 0 ).data().indexOf( deletedItem.id ); dt.row( rowIdx ).remove().draw(); } ); // Convert the data set into observable objects, and will also add the // initial data to the table ko.mapping.fromJS( data, { key: function(data) { return ko.utils.unwrapObservable(data.id); }, create: function(options) { return new Person(options.data, dt); } }, people ); // Examples: // Update a field people()[0].first( 'Allan3' ); // Add an item people.push( new Person( { id: 3, first: "John", last: "Smith", age: 34 }, dt ) ); // Remove an item people.shift(); } );