Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Refresh KnockoutJS Data In DataTables

I have the following table

<table class="datatable zebra-striped">
    <thead>
        <tr>
            <th>Name</th>
            <th>Issue</th>
            <th></th>
        </tr>
    </thead>
    <tbody data-bind="foreach: Publications">
        <tr>
            <td><span data-bind="text: Name" /></td>
            <td><span data-bind="text: IssueNumber" /></td>
            <td><button type="button" class="btn" data-bind="click: $parent.DeletePublication">Delete</button></td>
        </tr>    
    </tbody>
</table>

Here is a snippet of the viewmodel:

function EditReaderViewModel() {
    var self = this;

    self.Publications = ko.observableArray([]);

    self.OnAddPublicationSaveButtonClicked = function () {
        //.. code omitted.    
        self.Publications.push(new Publication(publication.value, publication.label, publication.issueNumber));
    };
};

}

and the Publication object binded to the table:

function Publication(id, name, issueNumber) {
    var self = this;

    self.Id = id;
    self.Name = name;
    self.IssueNumber = issueNumber;
    self.LoadedFromDatabase = false;
}

When the data is first loaded into the table, and the datatable initialisation e.g.

$(".datatable").dataTable({ // blahh });

Everything works fine - the data is loaded in the table, sorting and filtering is working, etc.

Now when I add a new item to the Publications array in the viewmodel things just fall apart. For example, say I originally have 1 item in the Publications array, when I add another item, it will appear in the table until I click on a column heading to sort.

It seems that the datatable has it's own internal data list somewhere which does not include the new Publication I created.

Can someone guide me on how to rebuild the datatable, taking into account that the data is from a KnockoutJS viewmodel?

Please note that I have looked at this binding plugin:

http://www.joshbuckley.co.uk/2011/07/knockout-js-datatable-bindings/

The problem is that when I use this, I get error messages such as:

Requested unknown parameter '0' from the data source for row 0.

EDIT:

I'm looking through the code and I think I see the problem. In jQuery.DataTables.js there is this function function _fnGetCellData( oSettings, iRow, iCol, sSpecific )

In that function there is this line:

if ( (sData=oCol.fnGetData( oData )) === undefined )

which in turn calls:

function _fnGetObjectDataFn( mSource )

Now, in function _fnGetObjectDataFn( mSource ) there is this code which is called:

else
{
    /* Array or flat object mapping */
    return function (data) {
         return data[mSource];
    };
} 

data is not an array, it's a JSON object which means that the above code will fail (return data[mSource];).

I'm really not sure what to do here.

EDIT - IMPORTANT:

As one of the commentators has noticed, and I've just confirmed, accessing

http://www.joshbuckley.co.uk/2011/07/knockout-js-datatable-bindings

will result in a Trojan warning. So please be aware that this url is now an big NO-NO.

like image 446
Jason Evans Avatar asked Jan 11 '12 16:01

Jason Evans


2 Answers

I know that´s an older thread but since I found it when I had the same problem I feel the need to post the solution so others might find it quicker.

When refreshing the Table you can simple .clear() and then .destroy() the table. After that just reinitialize the table using the already known .DataTable()

Although that's a little messy because you really tear down the structure and rebuild it it work very smoothly.

You just have to add a boolean identifier you set to true the first time you initialize the table. And of course you have to bind the Table to a variable to be able to work the DataTable API magic on the DOM Element.

    if (managementLoadedDone){
            userTable.clear();
            userTable.destroy();
        }

Fill data in your Table

    userTable = $("#userTable").DataTable({responsive: true});
            usersLoaded = true;
like image 97
Roman Schmidt Avatar answered Oct 06 '22 17:10

Roman Schmidt


You mention that you used datatable plugin and get "Requested unknown parameter '0' from the data source for row 0" error.

In my previous experineces using datatable without knockout plugin i got this error only using more columns than the header definitions or vice versa. You have to check your tbody and thead section and make it sure that both of them is the same size.

Or may be you are using "aoColumnDefs" option when you initialize the table.Again checked the option definiton and make sure that you havent try to reach unknown column :

For example if you have a definition like this

"aoColumnDefs": [{
         "bSearchable": false,
         "bVisible": false,
         "aTargets": [0]
     }, {
         "bSortable": false,
         "bSearchable": false,
         "sWidth": "45px",
         "aTargets": [2]
     }]

and if you have only 2 thead section this will give you that error. Because you are reaching third column with aTargets : [2]

like image 39
Luffy Avatar answered Oct 06 '22 18:10

Luffy