How to implement DataTables with knockout observables.

How to implement DataTables with knockout observables.

RpiechuraRpiechura Posts: 98Questions: 3Answers: 14
edited June 2014 in Free community support

@allan So I've seen your post http://datatables.net/forums/discussion/16160/knockout-observables-and-datatables-1-10-pre-beta-feedback-please and the example that you've posted with it. My question is just how much further you've gotten into this and if there is anything new that you can provide that I can take a look at.

I got a proof of concept project working well enough, however now we are really looking into if we still want to use DataTables or go with something else because of the desire for the items being knockout observable objects. The desire is to have an item in the table be updated if a details side panel is changed (which obviously ko observables would do for us) but I'm not sure if it can be done.

This question has an accepted answers - jump to answer

Answers

  • RpiechuraRpiechura Posts: 98Questions: 3Answers: 14
    edited June 2014

    I guess this question may be a bit too open ended. I'm looking for more information on making dataTables work with ko observables. The hardest time I've had so far is how supply 'data' with a ko observable array of observable objects and get it to work. If I could figure that out, I imagine I could get my old project to work correctly. However right now I'm failing pretty miserably at getting it to do even the most simple things. Here is an example of the data that is being returned when I make my Ajax call.

    {"count": 64, "items": [{"personID":"468c6d00-e5ea-11e3-8e2e-b8ca3ab75681","displayName":"Kurt Roemer","firstName":"Kurt","lastName":"Roemer","isMale":true,"imageUrl":"http://www.principalfocus.com/images/unknown.gif","alert":false,"doNotContact":false,"createdByID":"72aac0fe-f512-46ef-8bc2-a32b01698d67","updatedByID":"72aac0fe-f512-46ef-8bc2-a32b01698d67","createdOn":"2012-08-01 12:00 AM","updatedOn":"2014-05-27 03:00 PM"},{"personID":"468c6e00-e5ea-11e3-8e2e-b8ca3ab75681","displayName":"James Creamer","firstName":"James","lastName":"Creamer","isMale":true,"imageUrl":"http://www.principalfocus.com/images/unknown.gif","alert":false,"doNotContact":false,"createdByID":"468c6d18-e5ea-11e3-8e2e-b8ca3ab75681","updatedByID":"468c6d18-e5ea-11e3-8e2e-b8ca3ab75681","createdOn":"2004-02-16 12:00 AM","updatedOn":"2009-07-23 11:07 AM"},{"personID":"468c6d04-e5ea-11e3-8e2e-b8ca3ab75681","displayName":"Sid Agnew","firstName":"Sid","lastName":"Agnew","isMale":true,"imageUrl":"http://www.principalfocus.com/images/unknown.gif","alert":false,"doNotContact":false,"createdByID":"72aac0fe-f512-46ef-8bc2-a32b01698d67","updatedByID":"72aac0fe-f512-46ef-8bc2-a32b01698d67","createdOn":"2010-10-22 12:00 AM","updatedOn":"2014-05-27 03:00 PM"},{"personID":"468c6f07-e5ea-11e3-8e2e-b8ca3ab75681","displayName":"Robert Aisenbrey","firstName":"Robert","lastName":"Aisenbrey","isMale":true,"imageUrl":"http://www.principalfocus.com/images/unknown.gif","alert":false,"doNotContact":false,"createdByID":"468c6d48-e5ea-11e3-8e2e-b8ca3ab75681","updatedByID":"468c6d48-e5ea-11e3-8e2e-b8ca3ab75681","createdOn":"2004-02-26 12:00 AM","updatedOn":"2008-09-04 08:13 AM"},{"personID":"468c6d08-e5ea-11e3-8e2e-b8ca3ab75681","displayName":"Amy Totten","firstName":"Amy","lastName":"Totten","isMale":false,"imageUrl":"http://www.principalfocus.com/images/unknown.gif","alert":false,"doNotContact":false,"createdByID":"72aac0fe-f512-46ef-8bc2-a32b01698d67","updatedByID":"72aac0fe-f512-46ef-8bc2-a32b01698d67","createdOn":"2010-11-14 12:00 AM","updatedOn":"2014-05-27 03:00 PM"},{"personID":"468c6d0c-e5ea-11e3-8e2e-b8ca3ab75681","displayName":"Anthony McIntosh","firstName":"Anthony","lastName":"McIntosh","isMale":true,"imageUrl":"http://www.principalfocus.com/images/unknown.gif","alert":false,"doNotContact":false,"createdByID":"72aac0fe-f512-46ef-8bc2-a32b01698d67","updatedByID":"72aac0fe-f512-46ef-8bc2-a32b01698d67","createdOn":"2009-05-18 12:00 AM","updatedOn":"2014-05-27 03:00 PM"},{"personID":"468c6e0e-e5ea-11e3-8e2e-b8ca3ab75681","displayName":"William Griffin","firstName":"William","lastName":"Griffin","isMale":true,"imageUrl":"http://www.principalfocus.com/images/unknown.gif","alert":false,"doNotContact":false,"createdByID":"468c6d18-e5ea-11e3-8e2e-b8ca3ab75681","updatedByID":"468c6d18-e5ea-11e3-8e2e-b8ca3ab75681","createdOn":"2004-02-16 12:00 AM","updatedOn":"2009-07-22 02:26 PM"},{"personID":"468c6d10-e5ea-11e3-8e2e-b8ca3ab75681","displayName":"Chris Cornwell","firstName":"Chris","lastName":"Cornwell","isMale":true,"imageUrl":"http://www.principalfocus.com/images/unknown.gif","alert":false,"doNotContact":false,"createdByID":"72aac0fe-f512-46ef-8bc2-a32b01698d67","updatedByID":"72aac0fe-f512-46ef-8bc2-a32b01698d67","createdOn":"2005-09-01 12:00 AM","updatedOn":"2014-05-27 03:00 PM"},{"personID":"468c6d15-e5ea-11e3-8e2e-b8ca3ab75681","displayName":"Kevin Ewing","firstName":"Kevin","lastName":"Ewing","isMale":true,"imageUrl":"http://www.principalfocus.com/images/unknown.gif","alert":false,"doNotContact":false,"createdByID":"72aac0fe-f512-46ef-8bc2-a32b01698d67","updatedByID":"72aac0fe-f512-46ef-8bc2-a32b01698d67","createdOn":"2007-11-10 12:00 AM","updatedOn":"2014-05-27 03:00 PM"},{"personID":"468c6d19-e5ea-11e3-8e2e-b8ca3ab75681","displayName":"Jamie Miller","firstName":"Jamie","lastName":"Miller","isMale":false,"imageUrl":"http://www.principalfocus.com/images/unknown.gif","alert":false,"doNotContact":false,"createdByID":"72aac0fe-f512-46ef-8bc2-a32b01698d67","updatedByID":"72aac0fe-f512-46ef-8bc2-a32b01698d67","createdOn":"2009-02-01 12:00 AM","updatedOn":"2014-05-27 03:00 PM"}]}

  • taliesinstaliesins Posts: 1Questions: 0Answers: 1
    edited June 2014 Answer ✓

    Here is some snippets I am using for knockout 3 and datatable. It binds to changes to observable array and to changes in values of the properties of items in observable array.

    Strip out the editor code. Key thing to note is databindFunction

    Manage catalogs

    Id Name
    <script>
        $(document).ready(function () {
            require(['view.catalogs'],
            function (view) {
                view.render();
            });
        });
    </script>
    
    define('view.catalogs', ['vm.catalogs', 'jquery', 'knockout', 'datatables'], function (viewModel, $, ko) { function CatalogsView(viewModel, $, ko){ var self = this; self.viewModel = viewModel; self.editor = null; self.render = function() { var databindFunction = function(dataTable, keyColumn, databoundColumns, changes) { if (changes.length > 0) { changes.forEach(function(change) { if (change.status === 'added') { console.log("The added element is:", change.value); dataTable.row.add(change.value); $.each(databoundColumns, function(i, prop) { change.value[prop].subscribe(function(val) { console.log("The property '" + prop + "' has changed to:", val); var rowIdx = dataTable.column(0).data().indexOf(change.value[keyColumn]); dataTable.row(rowIdx).invalidate().draw(); }); }); } else if (change.status === 'deleted') { console.log("The removed element is:", change.value); var rowIdx = dataTable.column(0).data().indexOf(change.value[keyColumn]); dataTable.row(rowIdx).remove(); } }); dataTable.draw(); } } self.editor = new $.fn.dataTable.Editor({ table: "#CatalogsGrid", fields: [ { label: "Id:", name: "id" }, { label: "Name:", name: "name" } ] }); var dtOptions = { columns: [ { data: 'id'}, { data: 'name()' } ], columnDefs: [ { targets: 0, visible: false, searchable: false } ], tableTools: { sRowSelect: "os", aButtons: [ { sExtends: "editor_create", editor: self.editor }, { sExtends: "editor_edit", editor: self.editor }, { sExtends: "editor_remove", editor: self.editor } ] } } var catalogsGrid = $("#CatalogsGrid").DataTable(dtOptions); self.viewModel.Catalogs.subscribe(function(changes) { databindFunction(catalogsGrid, 'id', ['name'], changes); }, null, "arrayChange"); self.viewModel.Get(); ko.applyBindings(self.viewModel, document.getElementById('content')); }; } return new CatalogsView(viewModel, $, ko); }); define('vm.catalogs', ['dataservice', 'knockout'], function (dataservice, ko) { function CatalogsViewModel(dataservice, ko) { var self = this; /** * Child models */ var Catalog = function (data) { this.id = data; this.name = ko.observable(data); }; /** * Observables */ self.IsUpdating = ko.observable(false); self.Catalogs = ko.observableArray(); /** * Computed Observables */ /** * Actions */ self.mapCatalogs = function (catalogs) { var catalogObjects = []; $.each( catalogs, function( index, value ) { var catalogObject = new Catalog(value); catalogObjects.push(catalogObject); }); self.Catalogs(catalogObjects); } self.Get = function () { dataservice.user.getUser({ success: function (data) { if (data) { self.mapCatalogs(data.Catalogs); } }, error: function (data, status) { console.log("data: " + data); console.log("status: " + status); } }); }; }; return new CatalogsViewModel(dataservice, ko); });
  • RpiechuraRpiechura Posts: 98Questions: 3Answers: 14

    Thanks for the code. We looked over it and it makes sense (more or less) to us. We've decided that we're going to use client side processing and use the datatables stuff to just do some pretty simple styling / display modification instead of trying to get the server side processing to work correctly.

This discussion has been closed.