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

Filtering an ObservableArray

4 Answers 508 Views
MVVM
This is a migrated thread and some comments may be shown as answers.
Jeff
Top achievements
Rank 1
Jeff asked on 03 Sep 2012, 05:00 PM
I've been struggling to find a better way to filter an ObservableArray to a subset of values.  At first glance it seems like this should be easy.  Simply add a function to the view model to create an array with only those items I want and then set the binding source to that function.

Here's an example:

<ul class="items" data-template="row-template" data-bind="source: itemsFiltered"></ul>

 itemsFiltered : function () {
       var iFlt = [];
       var iCurr = this.get("Items");
       for (var i = 0; i < iCurr.length; i++) {
           if (iCurr[i].get("State") != "CA") { //Ex: filter out all items in CA
               iFlt.push(iCurr[i]);
           }
       }
       return iFlt;
   }

This sort of works, but I'm getting some strange Focus and Blur behaviors in IE when binding to the Filter function.  These behaviors go away if I bind directly to the array.

I can't help but think that IE doesn't like the fact that I'm replacing the entire array each time the view model changes.  I know KnockOut has a utility function to handle filtering like this (ko.utils.arrayFilter), and such a function is more ideal than returning a new array.

Does Kendo MVVM contain an equivalent to ko.utils.arrayFilter?  If so, what is it?  If not, I'd like to recommend adding such a function.  Ideally the binding features of kendo should call always call a filter function (default implementation would return a value of true) when evaluating the binding of each item.

Is there another way to accomplish filtering in kendo MVVM?  I know I could theoretically add an binding for invisible and point to a function that evaluates whether or not to display the item, but this is only a partial solution as the item itself would still be in the DOM.

4 Answers, 1 is accepted

Sort by
0
Alex Gyoshev
Telerik team
answered on 06 Sep 2012, 01:38 PM
Hello Jeffrey,

We could not reproduce the problem you are describing -- here is a jsbin sample of what we tried. Please elaborate on the problem.

Kind regards,
Alex Gyoshev
the Telerik team
Join us on our journey to create the world's most complete HTML 5 UI Framework - download Kendo UI now!
0
Jeff
Top achievements
Rank 1
answered on 06 Sep 2012, 04:53 PM
I apologize Alex.  Your simplified test case worked.  I then tried a similar simplified test case of my own, which did not work (despite the fact that the code was nearly the same as yours).

Eventually I tracked the problem down to a jQuery "live" binding in one of my javascript libraries that was only supposed to attach itself to elements with that have a specific HTML attribute.  Example: $("[data-prompt]").live("keydown"... On this particular page there are no elements that have that attribute and so it should have done nothing.  In fact it did do nothing in all browsers including IE.  Except that in IE it produced some wacky focus/blur behaviors.

Strangest of all the weird behaviors only happened when I bound my view to a filtered observable array.  If I bound to the original array, everything worked fine, which is what had originally led me to think that the way I was filtering it was the problem.

I admit I'm still scratching my head as to why this occurred.  Changing the "live" to a simple "bind" corrected it.
0
Jeff
Top achievements
Rank 1
answered on 31 Jan 2013, 04:49 PM
Alright I've noticed a rather strange behavior when filtering ObservableArrays.

If you bind a filtered array to a set of text boxes, blur/focus/change on the textboxes starts to get a bit wonky.

Here's a jsbin sample so you can see what I mean: http://jsbin.com/uvixec/3/edit

The only work-around I can find for this is to maintain two observable arrays; one with the full content and one with the filtered content.  That approach is rather messy though.

I modified my jsbin to demonstrate the full issue with the blur/focus/change problems.  Suppose you have some javascript functions that enforce numeric entry or in some other way modify the text of a textbox prior to hitting your view model.  These functions do not get called correctly on a filtered observable array. They do however work using the synchronization approach.

To demonstrate this, if you change some text on an item, I append "-Change" to your edit.  In the real world this might make sure your input is numeric and if it isn't set it back to the old value.
0
Alex Gyoshev
Telerik team
answered on 05 Feb 2013, 09:49 AM
Hello Jeff,

The problem with the first example is that the returned array is not observable, and the source binding does not know when to refresh it. This functionality is currently not supported.

An alternative approach would be to use the DataSource component and create a custom widget (e.g. a repeater) that will bind to it. This should result in cleaner code, but will be slightly different from your current approach. The DataSource will also automatically handle the filtering, through the filter configuration options.

Kind regards,
Alex Gyoshev
the Telerik team
Join us on our journey to create the world's most complete HTML 5 UI Framework - download Kendo UI now!
Tags
MVVM
Asked by
Jeff
Top achievements
Rank 1
Answers by
Alex Gyoshev
Telerik team
Jeff
Top achievements
Rank 1
Share this question
or