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

filtering a listview with multiple range sliders

11 Answers 498 Views
General Discussions
This is a migrated thread and some comments may be shown as answers.
Dd
Top achievements
Rank 1
Dd asked on 18 Dec 2012, 01:06 AM
Hi,

I've seen a few examples of filtering, but never with a listview using range sliders. Pretty much all of the examples I've seen involve filtering a grid with a dropdown. I am curious about filtering a listview with multiple range sliders. I know how to filter a listview but don't know how to hook up the range sliders to do the filtering (on change, on slide). Could someone please point me in the right direction?

This is what I have so far:
<!DOCTYPE html>
<head id="Head1" runat="server">
    <title></title>
 
    <link rel="Stylesheet" href="search.css" type="text/css" />
     
    <link href="examples-offline.css" rel="stylesheet">
    <link href="kendo.common.min.css" rel="stylesheet">
    <link href="kendo.default.min.css" rel="stylesheet">
 
    <script src="jquery.min.js"></script>
    <script src="kendo.web.min.js"></script>
    <script src="console.js"></script>
 
</head>
 
 
<body>
     <form id="form1" runat="server">
     <div  class="content">
      
     <div class="menuholder">
        <div class="menu"></div>
     </div>
 
      
     <div class="holder">
      
      
     <div class="params">
 
                <div id="rangeslider" class="humidity">
                    <input />
                    <input />
                </div>
 
    </div>
     
     <div class="vspacer"></div>
      
     <div class="display">
 
         <div id="example" class="k-content">
 
    <div id="listView"></div>
 
 
    <script type="text/x-kendo-tmpl" id="template">
        <div class="product">
            <img src="myimg.jpg" alt="${ProjectName} image" />
            <h3>${ProjectName}</h3>
            <div class="edit-buttons">
                <a class="k-button k-button-icontext k-update-button" href="\\#">Btn1</a>
                <a class="k-button k-button-icontext k-cancel-button" href="\\#">Btn2</a>
 
            </div>
        </div>
    </script>
 
    <script>
     
        $(document).ready(function() {
         
            var dataSource = new kendo.data.DataSource({
                    transport: {
                        read: {
                            url: "jsonfile.json",
                            dataType: "json"
                        }
                    },
                     
                    filter: {
                            logic: "or",
                            filters: [ {field: "ProjectName", operator: "startswith", value: "C" },
                            {field: "ProjectName", operator: "startswith", value: "A" } ]
                    },
                     
 
                });
 
 
            $("#listView").kendoListView({
                dataSource: dataSource,
                selectable: "multiple",
                template: kendo.template($("#template").html())
            });
             
            $(".k-add-button").click(function(e) {
                listView.add();
                e.preventDefault();
            });
             
 
                    $("#rangeslider").kendoRangeSlider({
                        min: 0,
                        max: 10,
                        smallStep: 1,
                        largeStep: 2,
                        tickPlacement: "both"
                    });                
        });
         
         
    </script>
 
</div>
     </div>
      
     </div>
     </div>
     </form>
</body>
</html>
All I've done is look at the examples and try to apply them, as you can see above. The filtering, as is, works - except it isn't hooked up to any range sliders. Would appreciate any help.
TIA

11 Answers, 1 is accepted

Sort by
0
Accepted
Alexander Valchev
Telerik team
answered on 19 Dec 2012, 12:42 PM
Hello,

You should hook up to the change event of the RangeSlider as it fires after the user stops sliding. At the change please construct the filter object and filter the DataSource. As an example:
$("#rangeslider").kendoRangeSlider({
  min: 1,
  max: 100,
  change: function (e) {
    var filter = {
      logic: "and",
      filters: [
        {field: "ProductID", operator: "gt", value: e.values[0]},
        {field: "ProductID", operator: "lt", value: e.values[1]}
      ]
    };
    dataSource.filter(filter);
  }
});

Here is a working example: http://jsbin.com/uvitog/4/edit

Kind regards,
Alexander Valchev
the Telerik team
Join us on our journey to create the world's most complete HTML 5 UI Framework - download Kendo UI now!
0
Dd
Top achievements
Rank 1
answered on 19 Dec 2012, 04:39 PM
Thank you very much, that works perfectly.

EDIT:
How would I go about applying to filters simultaneously?
I'd like for the filters from each rangeSlider to be applied, not one or the other. As it is right now, if I move one slider, it filters the results fine. If I move the second slider, it overwrites the previous filtering and only uses the last filtering.

For example:
$("#rangeslider").kendoRangeSlider({
    min: 0,
    max: 40,
    smallStep: 1,
    largeStep: 2,
    tickPlacement: "both",
    change: function (e) {
        var filter = {
        logic: "and",
        filters: [
            {field: "Width", operator: "gt", value: e.values[0]},
            {field: "Width", operator: "lt", value: e.values[1]}
            ]
        };
    dataSource.filter(filter);
    }
});        
 
$("#rangeslider2").kendoRangeSlider({
    min: 36,
    max: 80,
    smallStep: 1,
    largeStep: 2,
    tickPlacement: "both",
    change: function (e) {
        var filter = {
        logic: "and",
        filters: [
            {field: "Length", operator: "gt", value: e.values[0]},
            {field: "Length", operator: "lt", value: e.values[1]}
            ]
        };
    dataSource.filter(filter);
    }
});
0
Alexander Valchev
Telerik team
answered on 19 Dec 2012, 06:14 PM
Hello,

When the filter method is called without parameters it will return the currently applied filters. In your case you should get the filter object and extend it with the new rules. 
change: function (e) {
    var filters = dataSource.filter();
    //extend the filters object and add the new rules
    dataSource.filter(filters);
}


Kind regards,
Alexander Valchev
the Telerik team
Join us on our journey to create the world's most complete HTML 5 UI Framework - download Kendo UI now!
0
Dd
Top achievements
Rank 1
answered on 19 Dec 2012, 10:53 PM
Thanks for the reply.
I tried the following:

$("#rangeslider").kendoRangeSlider({
    min: 0,
    max: 40,
    smallStep: 1,
    largeStep: 2,
    tickPlacement: "both",
    change: function (e) {
      var curFilters = dataSource.filter(); // also tried var curFilters = dataSource.filter().filters;
      var newFilter = {field: "Width", operator: "gte", value: e.values[0]};
      //var newFilter2 = {field: "Width", operator: "lte", value: e.values[1]};
     curFilters.push(newFilter);
    dataSource.filter(filter);
    }
});
It did not work. What am I doing incorrectly above?
0
Alexander Valchev
Telerik team
answered on 21 Dec 2012, 02:12 PM
Hello,

As far as I can see the dataSource is being filtered by object named "filter".
dataSource.filter(filter);

Where is that variable defined? Didn't you receive a JavaScript error?

If you need further assistance it would be best if you edit the jsBin example from my first post and send me back a link. In this way I would be able to inspect the current implementation and help you resolve the issues faster.
Thank you in advance.

Kind regards,
Alexander Valchev
the Telerik team
Join us on our journey to create the world's most complete HTML 5 UI Framework - download Kendo UI now!
0
Dd
Top achievements
Rank 1
answered on 05 Jan 2013, 12:44 AM
Thanks for your reply.

http://jsbin.com/uvitog/9/edit

The above is the link you posted, with my edits.
The left slider is the original one you included in the example. The right slider is for UnitPrice.

If you leave the left range slider as is, and adjust the right one (price) to something like 21 and 41, and then after that, move the left range slider, items that are below $21 or over $41 will be displayed. I'd like them to not be displayed since the price slider did not move - the id slider did. So if the price slider is set as-is (21 to 41) and the left slider is moved AFTER the price is adjusted, items with prices outside of the 21 to 41 range should NOT be displayed.

Does this make sense?
0
Alexander Valchev
Telerik team
answered on 07 Jan 2013, 06:40 PM
Hello,

If you leave the left range slider as is, and adjust the right one (price) to something like 21 and 41, and then after that, move the left range slider, items that are below $21 or over $41 will be displayed.

The filter method of the dataSource will filter the data and will replace all the currently applied filters. To achieve the desired behaviour you should at first retrieve the currently applied filters and add the new ones to them.
var currentFilters = dataSource.filter().filters;
currentFilters.push({field: "ProductID", operator: "gte", value: e.values[0]});
currentFilters.push({field: "ProductID", operator: "lte", value: e.values[1]});
 
var filter = {
  logic: "and",
  filters: currentFilters
};
 
dataSource.filter(filter);

In your current implementation the dataSource is being filtered only by one of the sliders at a time. This is because at the change event of the slider the previous filters are not re-applied.

Kind regards,
Alexander Valchev
the Telerik team
Join us on our journey to create the world's most complete HTML 5 UI Framework - download Kendo UI now!
0
Dd
Top achievements
Rank 1
answered on 07 Jan 2013, 09:54 PM
Hi,

Thanks for your reply.

I tried that, and it did not work. Also, the range sliders behave funny now. When you click on a pointer to drag, it doesn't lock when you let go of the mouse button. It locks after a second click.

http://jsbin.com/uvitog/12/edit
0
Accepted
Alexander Valchev
Telerik team
answered on 09 Jan 2013, 03:14 PM
Hello,

I found an easier for implementation solution. Instead of adding new filter rules to the current one you may filter each time according to the values of both sliders.
change: function (e) {
  var filters = [],
      filter;
   
  filters.push({field: "ProductID", operator: "gte", value: slider1.values()[0]});
  filters.push({field: "ProductID", operator: "lte", value: slider1.values()[1]});
  filters.push({field: "UnitPrice", operator: "gte", value: slider2.values()[0]});
  filters.push({field: "UnitPrice", operator: "lte", value: slider2.values()[1]});
   
  filter = {
    logic: "and",
    filters: filters
  };
 
  dataSource.filter(filter);
}

Here is a link to the updated example: http://jsbin.com/uvitog/17/edit

Regards,
Alexander Valchev
the Telerik team
Join us on our journey to create the world's most complete HTML 5 UI Framework - download Kendo UI now!
0
Dd
Top achievements
Rank 1
answered on 09 Jan 2013, 09:44 PM
Thanks, that did it!

Any idea why the other method you posted previously did not work?
If I have many rangesliders, this can get quite messy - a lot of code.
Would prefer a solution where I only have to deal with one slider in the function vs dealing with all sliders in every function.
0
Alexander Valchev
Telerik team
answered on 10 Jan 2013, 01:03 PM
Hello,

The other approach is valid but requires a more complex custom logic to build the filters. Once again, filter method of the DataSource replaces all previously applied filters. This is why you have to extend (add rules to) previously applied filters or simply retrieve the values of all sliders like in the last example.

Regards,
Alexander Valchev
the Telerik team
Join us on our journey to create the world's most complete HTML 5 UI Framework - download Kendo UI now!
Tags
General Discussions
Asked by
Dd
Top achievements
Rank 1
Answers by
Alexander Valchev
Telerik team
Dd
Top achievements
Rank 1
Share this question
or