Find/Change a local DataSource element

9 posts, 1 answers
  1. Matt
    Matt avatar
    30 posts
    Member since:
    Mar 2008

    Posted 16 Jan 2012 Link to this post

    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!
  2. Answer
    John DeVight
    John DeVight avatar
    209 posts
    Member since:
    Jan 2010

    Posted 16 Jan 2012 Link to this post

    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
  3. Kendo UI is VS 2017 Ready
  4. Matt
    Matt avatar
    30 posts
    Member since:
    Mar 2008

    Posted 16 Jan 2012 Link to this post

    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!
  5. John DeVight
    John DeVight avatar
    209 posts
    Member since:
    Jan 2010

    Posted 16 Jan 2012 Link to this post

    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
  6. Gary
    Gary avatar
    14 posts
    Member since:
    Jan 2012

    Posted 28 Mar 2012 Link to this post

    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.
  7. Kevin
    Kevin avatar
    5 posts
    Member since:
    Jul 2012

    Posted 29 Aug 2012 Link to this post

    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.

  8. Jonas
    Jonas avatar
    33 posts
    Member since:
    Sep 2009

    Posted 21 Mar 2013 Link to this post

    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
  9. John DeVight
    John DeVight avatar
    209 posts
    Member since:
    Jan 2010

    Posted 22 Mar 2013 Link to this post

    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

  10. Roatin Marth
    Roatin Marth avatar
    65 posts
    Member since:
    Nov 2007

    Posted 29 Nov 2013 Link to this post

    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?
Back to Top
Kendo UI is VS 2017 Ready