• .NET Developer Tools DevTools

    UI controls for ASP.NET AJAX, MVC, WPF,
    Silverlight, Windows 8 and Windows Phone

  • Hybrid Mobile Development Icenium

    Cross-platform Mobile Development Tool
    with cloud-based architecture

  • HTML5 / JavaScript Development Kendo UI

    Everything you need to build sites and
    mobile apps with JavaScript and HTML5

  • Testing Tools TestStudio

    One easy tool for Functional, Performance,
    Load and Mobile software testing

  • Web Presence Platform Sitefinity CMS

    Everything for your online business - content
    management, ecommerce, emarketing

  • Agile Project Management TeamPulse

    Simple and intuitive project management
    and collaboration software

Contact us

We are here for you.
  • usa+1‒888‒365‒2779
  • uk+44‒20‒7291‒0580
  • bg+359‒2‒8099850
  • de+49‒89‒2441642‒70
  • au+61‒2‒8090‒1465
  • emailsales@telerik.com
Your account Access to your products, updates and support
Telerik Product Families
  • Your Account
    Your Account
    Log in
  • ABOUT US

    About Telerik

    • Company
    • Press Center
    • Customers
    • Community
    • Careers
    • Contacts
Kendo UI - The way of HTML5
Products ▼
Kendo UI Web Kendo UI Mobile Kendo UI DataViz Server Side Wrappers
Demos Purchase Download
Blogs Documentation
Support ▼
Premium Forums StackOverflow Forums
Resources ▼

Featured Resource

Kendo UI Dojo


Blogs Code Library Demos Documentation FAQ Testing
Premium Forums Roadmap User Voice Videos Webinars More Resources
Contact Us Search
 

Blogs

Adding And Removing Items In kendo.data.DataSource

Tuesday, January 29, 2013 by Kendo UI Team Blog | Comments 6

In my previous post I walked through the basic steps to use a kendo.data.DataSource to build a very simple "to do" list. That version of the app was mostly read-only, with the exception of being able to mark an item as done. You couldn't, however, add or remove any items. It turns out adding and removing is as easy as anything else that has been done in this app, though, and it only takes a few lines of markup and JavaScript to add these features.

The Todo App

Here's what my app looks like with the add / remove features in place:

The complete code can be found in this JSFiddle

Once again, I want to note that this application is inspired by the TodoMVC app demos, but it is not intended to be a complete or canonical representation of TodoMVC or Kendo UI. I'm building a demo that is meant to exercise the Kendo DataSource object in a meaningful way, so that I can learn more about this framework peice and hoepfully help others better understand what it can do for us.

Additional Markup

There have been a few changes to the markup, as you can see from the output. I've added a <frameset> to the page to provide an area to add new "to do" items. I've also adjusted the table slightly and added a "remove" button below it, to allow us to remove items that are already done.

Todo Markup

    <fieldset class=".add-new">
        <legend>Add A Todo</legend>
        <p>Enter a to do item description</p>
        <input name="description" />
        <button id="add">Add</button>
    </fieldset>

    <!-- ... -->

    <tr>
        <td>Actions: </td>
            <td colspan="2">
                <button id="remove-done">Remove Done Items</button>
        </td>
    </tr>

This is simple markup with no Kendo templates at this point. The important points are the input ID's, which we will use in our JavaScript so that we can add new "to do" items or remove the ones that are complete.

Adding A New To Do Item

Handling the addition of a "to do" item is done with a jQuery selector and a DOM "click" event for the "add" button. When we receive that event, we read the "to do" description from the input box. Then we build an object literal that contains all of the fields we need: an id, a "done" status and the description we entered.

Adding A To Do Item

  // Handle adding a new to do item
  $("#add").click(function(e){
    e.preventDefault();

    var $todo = $("input[name='description']");

    currentId += 1;
    dataSource.add({
      id: currentId,
      done: false,
      description: $todo.val()
    });

    $todo.val("");
    $todo.focus();
  });

Adding a "to do" item to the DataSource is very simple, as you can see. You only need to call the add method on the dataSource instance, and pass in the object to be added.

To create the "to do" items with a unique ID, I've added a "currentId" variable to this code. This is used as a simple counter to give me an incremental ID to attach to new "to do" items, which is used to determine the item that is being marked as done (see the previous post for more information on that) when clicking a "done" checkbox. The currentId variable increments prior to every use, ensuring that we have a unique ID for each item we add.

I'm also clearing out the description input box after the item has been added and then re-focusing the browser that input box. This allows me to add a number of "to do" items faster as it reduces the number of clicks needed to create one and re-focus on the text input field.

Clearing The Done Items

Clearing the items that are already "done" takes a little more work than adding an item. There are no methods on the dataSource to bulk-remove items, at this time. That means I need to call the .remove method to remove the individual items that are "done".

Now, the question is: How do I get the list of items that are done?

The first idea that I had was to use the .filter method to filter down the list, the way I am doing for the filtering drop list. However, this method doesn't return anything to me. It just sets up some filters and triggers some events so that I can call the view method to get the list of items that match the filter. This sounded like a good idea at first, until I remembered that calling .filter(...) would trigger the "change" event and cause the item list to re-render. The net result of that is the view would re-render itself with the list of "done" items. This doesn't sound too bad off-hand, until I account for the different filter states for the view. If I'm looking at "all" items, I don't want to filter down to just the "done" items so I can delete them. I want to just get rid of them without re-rendering the list down to the items that will be removed first.

The solution I cam up with needs a little more code, then, because of the way the filter method works. I have to read the raw data from the dataSource, iterate over the array that this method returns, and check the "done" status of each item in the array. As I find items that are "done", I can then remove them from the dataSource.

Removing "Done" To Do Items

  // Handle removing cleared items
  $("#remove-done").click(function(e){
    e.preventDefault();

    var raw = dataSource.data();
    var length = raw.length;

    // iterate and remove "done" items
    var item, i;
    for(i=length-1; i>=0; i--){

      item = raw[i];
      if (item.done){
        dataSource.remove(item);
      }

    }

  });

The .data() method, unlike .view() will return the raw data from the underlying data store, unfiltered, unsorted, un-paged. It just hands the array of objects back to me in order to let me do what I want with them. This gives me the ability to look at all of the items in the dataSource instead of just the filtered, sorted and paged list that .view() would return.

Once I have that raw list, I set up a loop to iterate the length of the array. Within that for-loop, I grab the "to do" item for the index that I'm currently on and check to see if it is "done" or not. If it is, I tell the dataSource to remove that item.

Iterating Backwards

Did you notice that I'm looping through the list backwards?

Inverse For-Loop

  var i, length=data.length;

  for (i=length-1; i>= 0; i--){
    // ...
  }

Instead of the usual for-loop counting from 0 to a length, I am counting from length-1 back down to 0. I'm doing this because as I iterate through the array, I am telling the dataSource to remove the items. Since the dataSource handed me a reference to the array that it holds, this means I'm removing items from the array that I'm iterating. If we count from 0 to length, removing an item would throw off the iteration and cause errors. We would skip every other item and we would end up counting past the end of the array due to the length being modified as I go. But by counting backwards - from the end of the list back to the beginning - I can avoid these problems. Counting down to zero will always get to zero, no matter how many items I remove.

Editing Items And Other Features

I havent set up an edit feature for the "to do" items yet, other than allowing them to be marked as "done". It should be fairly simple to put this in place, but I'll leave that up to you as an exercise to complete. How would you set up the edit form vs add form: would you re-use the same form, or have a different form for that? What would you have to do with the dataSource and the items within in to facilitate editing?

While this little "to do" application is not terribly feature-rich or beautiful, it is giving us a good idea of what the DataSource can do for us. But there's much more that it can do, than what we have seen so far. For example, the DataSource can manage remote data sources for us - reaching out to a server somewhere, to read, write and update data as needed. I'll dig in to remote data in a future post, and show the basics of what it takes to read and write data to a server.

About the Author
Derick Bailey is a Developer Advocate for Kendo UI, a developer, speaker, trainer, screen-caster and much more. He's been slinging code since the late 80’s and doing it professionally since the mid 90's. These days, Derick spends his time primarily writing javascript with back-end languages of all types, including Ruby, NodeJS, .NET and more. Derick blogs at DerickBailey.LosTechies.com, produces screencasts at WatchMeCode.net, tweets as @derickbailey and provides support and assistance for JavaScript, BackboneJS, MarionetteJS and much more around the web.

6 Comments

  1. 1 SE 10 Feb 2013
    I am keen learn editing DataSource in kendo ui. could you provide the details?
  2. 2 Derick Bailey 11 Feb 2013
    Hi SE,

    My first post covers this briefly: 

    http://www.kendoui.com/blogs/teamblog/posts/13-01-24/learning_kendo_data_datasource.aspx

    In that post, I show how to retrieve a model by it's ID and then change one of the values of the model. The same code would be applied to editing any field of the model.

    For a more robust app, though, I would recommend using the DataSource with the Kendo UI controls. They provide this capability with much less code for you to write. The intent of these blog posts is to provide learning and education for myself and readers, but not to be a replacement for any of the controls that Kendo UI provides.
  3. 3 Renan 25 Feb 2013
    Hi Derick... nice tutorial!

    I just started playing with Kendo last week, and I've been having a hard time understanding and using the datasource, specifically when it comes to bindings. I already figure out how to tie the datasource to an autocomplete and when an item is selected all fields tied to the datasource get updated with the selected value. But now the problem that I'm having is to create/add and item to the datasource. This is what I have for a create function inside the observable object:

    save: function() {

    this.dsMedication.sync();

    }

    (dsMedication is the datasource)

    The save function is tied to a click event of a button on the screen. It works when someone searches an item and make changes to it. What should I do if the user just opened the screen and wants to fill out the fields and save it?

    Please send me an email and I can send you the whole code, I'm sure it's something simple, but I couldn't yet figure it out.

    Thanks! Renan

  4. 4 Derick Bailey 25 Feb 2013
    Hi Renan,

    You can call the "add" method on the DataSource to add a new model:  http://docs.kendoui.com/api/framework/datasource#add

    Calling "sync" will force it to sync with your back-end, after that.

    Hope that helps.
  5. 5 sushi 27 Feb 2013
    Hi.. 
        I am student,i am doing a small project using kendo controls,I have one problem in this.In my project i have kendo tree-view with check-boxes and one grid.I wanna filter the grid based on the check-box selection...I am trying this but its not working properly.
    here is the fiddle..
    http://jsfiddle.net/RHh67/9/
     please help me..
  6. 6 dcam 08 May 2013
    Hi,

    I've implemented something similar to you and come across a bug that also appears to exist in your implementation. To reproduce do the following on your jsfiddle example.

    1. tick all as done
    2. remove done items
    3. select show complete from dropdown
    4. select all from dropdown

    Once you have removed all items from the datasource it rolls back the changes. This only happens once you have removed all items. 

    Any idea how to fix this?

Comment

  1. Click to add

  2. Click to add

  3. Click to add

  4.    
     
    •  
    •  
    •  
    •  
    •  
    •  
    •  
    •  
    •  
    •  
    •  
    •  
     
      
       
Blogs feed
Categories

  • Tutorials (26)
  • Release (33)
  • Browsers (7)
  • Extensions (3)
  • Tip of the Week (10)
  • Videos (5)
  • Concepts and Theory (13)
  • Misc. (25)
  • Framework Constructs (6)
  • Mobile (6)
  • UI Widgets (5)
  • Blogs (1)
Archive
  • 2013 May (6)
  • 2013 April (10)
  • 2013 March (9)
  • 2013 February (12)
  • 2013 January (10)
  • 2012 December (9)
  • 2012 November (11)
  • 2012 October (6)
  • 2012 September (7)
  • 2012 August (8)
  • 2012 July (10)
  • 2012 June (8)
  • 2012 May (10)
  • 2012 April (7)
  • 2012 March (13)
  • 2012 February (10)
  • 2012 January (6)
  • 2011 December (10)
  • 2011 November (4)
  • 2011 October (6)
  • 2011 September (5)
  • 2011 August (9)
Home Web Mobile DataViz Server Wrappers Whitepapers Surveys Chrome Icenium Contact Us

Kendo UI framework is developed by Telerik - a leading provider of UI components for web, desktop and mobile applications. Trusted by over 100,000 customers worldwide for our devotion to quality and industry-best technical support, Telerik helps professionals maximize their productivity and "deliver more than expected" every day.

kendoui - powered by html5, css3 & jquery
get social
  • Twitter
  • Facebook
  • Google plus
  • RSS
Privacy Policy | Branding Guidelines
Powered by Sitefinity CMS

Copyright © 2011 - 2013 Telerik Inc. All rights reserved.