Getting access to array index while binding an Array source

9 posts, 0 answers
  1. Sean
    Sean avatar
    7 posts
    Member since:
    Apr 2012

    Posted 23 Apr 2012 Link to this post

    Howdy All,
    While binding to an array source is it possible to determine the index of the current array element? 

    The documentation for using the Source binding gives the following example:

    <ul data-template="ul-template" data-bind="source: products">
    </ul>
    <script id="ul-template" type="text/x-kendo-template">
        <li>
            id: <span data-bind="text: id"></span>
            name: <span data-bind="text: name"></span>
        </li>
    </script>
    <script>
        var viewModel = kendo.observable({
            products: [
                { id: 1, name: "Coffee" },
                { id: 2, name: "Tea" },
                { id: 3, name: "Juice" }
            ]
        });
     
        kendo.bind($("ul"), viewModel);
    </script>


    What I'm trying to do is get a reference to the index of the current array element from within the template.
    For Example:

    <li>
            index: <span data-bind="text: index"></span>
            id: <span data-bind="text: id"></span>
            name: <span data-bind="text: name"></span>
    </li>

    Does anybody know if there's a way to get access to the index from within the template?

    Any insight would be greatly appreciated. 
    Thanks in advance
    Seamus
  2. Sean
    Sean avatar
    7 posts
    Member since:
    Apr 2012

    Posted 24 Apr 2012 Link to this post

    I created a fiddle to better illustrate the issue I'm running into.  I checked the source for kendo UI and it doesn't seem like the index value is easily accessible from within the template.  Can anyone more knowledgeable with the framework confirm that?

    JSFiddle: http://jsfiddle.net/seamuskc/G9PEp/1/
  3. Petur Subev
    Admin
    Petur Subev avatar
    1882 posts

    Posted 25 Apr 2012 Link to this post

    Hi Sean,

    Basically you cannot determine what is the index of the current object in the array. What you can do is to define new property (e.g. named index) and set its value each time you add new object to the people array.
    Here is an example.
    http://jsfiddle.net/subev/xt7ue/25/ 

    Kind regards,
    Petur Subev
    the Telerik team
    Join us on our journey to create the world's most complete HTML 5 UI Framework - download Kendo UI now!
  4. Sean
    Sean avatar
    7 posts
    Member since:
    Apr 2012

    Posted 25 Apr 2012 Link to this post

    Thank you Petur for the reply and the example.  Do you know if there are any plans to make the item index available within the template in a future release of Kendo UI?  The reason that I ask is that adding the index as a property of the item *does* solve the simple use case that I gave but when you need to add "Delete" functionality it gets a little more complex.  Whenever an item is deleted, each subsequent item would need to have it's index property manually adjusted in order to keep the index values contiguous and avoid duplicated indexes.  Additionally, If you are loading existing items from a server side datasource, the items would also need to have this index property previously set.  It's very possible to code it that way but having the array index property available in the template would greatly simplify the solution.  Thanks again for the replies!

    Sean

    Update: I put in a suggestion to make the index available within the template :)
  5. Sean
    Sean avatar
    7 posts
    Member since:
    Apr 2012

    Posted 25 Apr 2012 Link to this post

    Hi Petur,
    In your solution, you spit out the index property of the object using a span tag with the data-bind property like so:

    Index : <span data-bind="text:index"/> <br/>

    How would (or could) you bind that value following the markup from the original example I gave:

    <input name="person[currentIndexHere].name" type="hidden" data-bind="value:name">

    Using #:index# and #=index# expressions I can get it to bind correctly during the initial rendering but updates to the ViewModel aren't reflected in the template using those approaches.  Using a span w/ data-bind does but it's not possible to use that approach to dynamically change the "name" attribute.  I looked into using the attr binding attribute but I don't see how to "build" the attribute value with a mix of static and data-bound text.  Am I missing something? Thanks
    Sean
  6. S
    S avatar
    15 posts
    Member since:
    Apr 2012

    Posted 01 Jul 2013 Link to this post

    Sean,

    I was able to bind name attribute to my ViewModel index using something like:

    <span data-bind="source: People" data-template="PeopleTemplate"></span>

    <script id="PeopleTemplate" type="text/x-kendo-template">
    <input name="Person[#= index#].PersonID" />
    </script>

    The binding to the index is also updated when ViewModel is updated. This is achieved by using Source and Template above. Here's my index in the ViewModel looks like:

    var viewModel = kendo.observable({
    people: [],
    index: function() {
        var people = this.get("people");
        var indeces = [];
        for (var i = 0; i < people.length; i++) {
            var index = { PeopleID: people[i], index: i };
            indeces.push(index);
        }
        return indeces;
    }
    });

    This will also solve your Delete functionality issue. However, you will need to add 'sorting' on your index ViewModel. The sorting must be based on unique identifier just so that after a deletion, your model will still have same sequence.

    HTH.
  7. John
    John avatar
    2 posts
    Member since:
    Nov 2019

    Posted 21 Nov 2019 Link to this post

    I'm sorry to posting on older thread, but it is almost familiar to my query. So wondering, now if there is any possible to determine the index of the current array element while binding to an array source? 

    Any help would be greatly appreciated. 

    Thanks in advance

    John

  8. Alex Hajigeorgieva
    Admin
    Alex Hajigeorgieva avatar
    1082 posts

    Posted 26 Nov 2019 Link to this post

    Hello, John,

    You can check right within the template the index of each item:

     # var idx = viewModel.products.indexOf(data); #
        <li>
           Index: #=idx #

    Here is a runnable example demonstrating this:

    https://dojo.telerik.com/@bubblemaster/eBOtaSoj

    Let me know in case you have further questions.

    Kind Regards,
    Alex Hajigeorgieva
    Progress Telerik

    Get quickly onboarded and successful with your Telerik and/or Kendo UI products with the Virtual Classroom free technical training, available to all active customers. Learn More.
  9. John
    John avatar
    2 posts
    Member since:
    Nov 2019

    Posted 27 Nov 2019 in reply to Alex Hajigeorgieva Link to this post

    Thank you very much Alex for the reply and the example. The index problem resolved. 
Back to Top