This is a migrated thread and some comments may be shown as answers.

Find/Change a local DataSource element

8 Answers 1336 Views
Data Source
This is a migrated thread and some comments may be shown as answers.
Matt
Top achievements
Rank 1
Matt asked on 16 Jan 2012, 09:21 PM
Hi All,

I have a local datasource bound to an array of objects.  This array looks something like (peopleData is a global object in this example):
peopleData = [
    { Id: "jaaron", FirstName: "John", LastName: "Aaron", Age: 46 },
    { Id: "agent2", FirstName: "Jayne", LastName: "Smith", Age: 13 }];

I am able to create a datasource using this local array with the following code (peopleDS is a global object in this example):
peopleDS = new kendo.data.DataSource({
    data: peopleData,
    change: function (e) {
        console.log(this.data().length + ' records');
    }
});

Now, I want to edit one of elements of the array.  My current approach is to just iterate over the array and change the element I am looking for, like this:
for (var i = 0; i < peopleData.length; i++) {
    if (peopleData[i].Id === "jaaron") {
        peopleData[i].Age = 55;
        break;
    }
}
peopleDS.read(peopleData);

My question is - is there a more efficient way to do this?  This array may grow to 1000 elements, which change frequently and I would rather not iterate over the entire array each time I need to change an element (although I realize it may be my only option).

On a side note:
The optimal solution, for me, would be to somehow bind an associative array to the datasource (although since it isn't really an array, I imagine isn't possible).  For instance, I would like to be able to display the FirstName, LastName, and Age of the following object using a KendoUI datasource:
peopleData = {};
peopleData["jaaron"] = { FirstName: "John", LastName: "Aaron", Age: 46 };
peopleData["agent2"] = { FirstName: "Jayne", LastName: "Smith", Age: 13 };

As always, thanks in advance for any help!

8 Answers, 1 is accepted

Sort by
0
Accepted
John DeVight
Top achievements
Rank 1
answered on 16 Jan 2012, 10:30 PM
Hi Matt,

I'm still learning Kendo UI, but I don't think that the dataSource has any functions to support updating.  However, an alternative would be to extend the dataSource and add the necessary functionality.  The benefit of extending the dataSource is that you can reuse the same functions for any dataSource.

Extending the dataSource is pretty simple.  You can use the jQuery.extend function.  Simply define the functions that you want to add to the dataSource object in a variable, and then extend the dataSource.

Here is an example of adding a new function to the dataSource called updateField:

var dataSourceExtensions = {
    updateField: function(e) {
        var ds = this;
        $.each(ds._data, function(idx, record) {
            if (record[e.keyField] == e.keyValue) {
                ds._data[idx][e.updateField] = e.updateValue;
                ds.read(ds._data);
                return false;
            }
        });
    }
};
  
$.extend(true, kendo.data.DataSource.prototype, dataSourceExtensions);

updateField takes a JSON object with 4 attributes, keyField, keyValue, updateField and updateValue.

All you would need to do to update the Age would be this:

peopleDS.updateField({ keyField: 'Id', keyValue: 'jaaron', updateField: 'Age', updateValue: 55 });

Attached is the sample code.

Hope this helps.

Regards,

John DeVight
0
Matt
Top achievements
Rank 1
answered on 16 Jan 2012, 10:45 PM
Thanks John!  That does the trick - while it is not really much more efficient than my original approach (we are both still looping - I am ultimately in search of some indexed method that wouldn't require a possible full iteration of the array), it is much more flexible and as you mentioned, applicable to the other datasources I will eventually have in my app.  Thanks again for your help!
0
John DeVight
Top achievements
Rank 1
answered on 16 Jan 2012, 10:45 PM
Matt,

One note about the updateField function; it calls the dataSource.read() to refresh the grid.  If you have a lot of updates, you probably want to take that out and call it after all your updates are done.

Regards,

John DeVight
0
Gary
Top achievements
Rank 1
answered on 28 Mar 2012, 11:26 PM
The problem with this solution is that the grid will completely re-render.

How can you update a DataSource value without causing the grid to completely re-render thus losing the current selection, expanded row, etc?

Also, I need to potentially update ALL the fields of the dataItem since I'm polling with REST and every field may have changed. I can fix this by extending DataSource with an updateItem method.  Seems like basic stuff that is missing.
0
Kevin
Top achievements
Rank 1
answered on 29 Aug 2012, 11:35 AM
I'm using a modified version of this extension, but I found using ds.sync(); instead of ds.read(ds._data); stops the entire grid redrawing.

0
Jonas
Top achievements
Rank 1
answered on 21 Mar 2013, 10:56 PM
nice extension! 

to update the datasource you could also do 
ds.data()[idx].set(e.updateField,e.updateValue); 

which should refresh the bound widgets automatically
0
John DeVight
Top achievements
Rank 1
answered on 22 Mar 2013, 02:04 PM
Thanks Jonus :)  Good suggestion.

BTW - I'm creating a Kendo Extended API library that has some new Kendo UI Web widgets that can be found at: https://github.com/jsExtensions/kendoui-extended-api

I'll probably extend the dataSource as well in the library.

Regards,

John DeVight

0
Roatin Marth
Top achievements
Rank 1
answered on 29 Nov 2013, 08:23 PM
is there a way to update the entire object at the index?
can I say ds.data()[idx].set(updatedObject) or something? or do I have to go through each of the properties one by one?
Tags
Data Source
Asked by
Matt
Top achievements
Rank 1
Answers by
John DeVight
Top achievements
Rank 1
Matt
Top achievements
Rank 1
Gary
Top achievements
Rank 1
Kevin
Top achievements
Rank 1
Jonas
Top achievements
Rank 1
Roatin Marth
Top achievements
Rank 1
Share this question
or