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

Client Side filtering with filterExpression builder

9 Answers 209 Views
ListView
This is a migrated thread and some comments may be shown as answers.
Irvine
Top achievements
Rank 1
Irvine asked on 23 May 2016, 05:33 PM

I'm trying to use RadListView with client side binding, everything works well, including the filters, bu they are always concatenated as ANDs and I need some of them to be ORs, so I'm trying to use the builder() featured in this article:
http://www.telerik.com/blogs/client-side-databinding-with-radlistview-for-asp-net-ajax---part-3#filtering

Here's an example of the JSON source this is filtering:
[{"OpportunityId":1,"OpportunityTitle":"\r\nMainframe Programmer for Giftware, Jewellery & Tableware","OpportunityType":"Realocation","ClientImageUrl":"/Client/Images/intel.jpg","ClientName":"Intel","PublishDate":"2016-04-27T00:00:00","PublishDaysSince2000":5961,"ExpiryDaysSince2000":6046,"CountryName":"Portugal","CityName":"Braga","SkillsList":[11,12,13],"Skills":"-11-12-13-","Salary":15000,"ContractTypeId":6,"ScheduleTypeId":2,"CityId":9,"ClientId":7,"ExperienceLevelId":null,"AcademicLevelId":3,"Reference":"AI5MU5PK3CWD","RequestDateDays":5961,"OpportunityStateId":4,"ManagerId":123,"RecruiterId":123,"CategoryId":20},{"OpportunityId":2,"OpportunityTitle":"Microprocessor Researcher","OpportunityType":"Project","ClientImageUrl":"/Client/Images/intel.jpg","ClientName":"Intel","PublishDate":"2016-04-27T00:00:00","PublishDaysSince2000":5961,"ExpiryDaysSince2000":6046,"CountryName":"Portugal","CityName":"Algarve","SkillsList":[11],"Skills":"-11-","Salary":15000,"ContractTypeId":4,"ScheduleTypeId":2,"CityId":10,"ClientId":7,"ExperienceLevelId":null,"AcademicLevelId":3,"Reference":"6PPH62GCRGWP","RequestDateDays":5961,"OpportunityStateId":3,"ManagerId":123,"RecruiterId":123,"CategoryId":21}

...

if I use the add: filterExpressions.add("OpportunityId", Telerik.Web.UI.RadListViewFilterFunction.Contains, 2); the filtering works as expected with ANDs, but no matter what expression i put using the builder, no records ever show.

i.e. if I use this filter: filterExpressions.add("OpportunityId", Telerik.Web.UI.RadListViewFilterFunction.GreaterThanOrEqualTo, 2);

all items with id > 2 show up, but if I use this filter: filterExpressions.build().greaterThan("OpportunityId", 2);

nothing shows up, and the same items should be showing up because its the same expression

attached is a print of what chrome shows as the tree for the filterExpressions object, when using a composite builder expression with one OR

9 Answers, 1 is accepted

Sort by
0
Irvine
Top achievements
Rank 1
answered on 25 May 2016, 12:05 PM

More info on filter expressions(might be bugs or by design, i cant tell):

If I'm filtering the same JSON to find out if ExperienceLevelId is null, I can't get the filters to work with filterExpressions.add("ExperienceLevelId", Telerik.Web.UI.RadListViewFilterFunction.IsNull);

the javascript object of filterExpressions shows the IsNull expression but every record shows up, regardless of its ExperienceLevelId being null or not. Could it have something to do with ExperienceLevelId being a numeric field?

I can get the desired behaviour by using filterExpressions.add("ExperienceLevelId", Telerik.Web.UI.RadListViewFilterFunction.EqualTo, null); instead.

0
Maria Ilieva
Telerik team
answered on 26 May 2016, 11:17 AM
Hi,


I would suggest you to try using ClientDataSource for binding the RadListView on the client and modify the filter expression like shown in the demo below:
http://demos.telerik.com/aspnet-ajax/listview/examples/client/client-data-source-binding/defaultcs.aspx?product=listview


Regards,
Maria Ilieva
Telerik
Do you need help with upgrading your ASP.NET AJAX, WPF or WinForms projects? Check the Telerik API Analyzer and share your thoughts.
0
Irvine
Top achievements
Rank 1
answered on 27 May 2016, 08:56 AM
Hi Maria, thank you for the answer but I've been following that demo since the beginning. I'm already using the client data source in the demo and it works well for binding data. The problem is in the behavior of the expression building methods as explained above.
0
Irvine
Top achievements
Rank 1
answered on 27 May 2016, 09:01 AM
And to clarify, the expressions in that demo are the ones that I'm saying work correctly, its the build() ones that are failing, and there is no example of those in the demo
0
Maria Ilieva
Telerik team
answered on 31 May 2016, 01:34 PM
Hello,

Can you please share your ListView declaration as well as the related coded behind and client code? Thus we will be able to revise it locally and do our best to advise you further.

Regards,
Maria Ilieva
Telerik
Do you need help with upgrading your ASP.NET AJAX, WPF or WinForms projects? Check the Telerik API Analyzer and share your thoughts.
0
Irvine
Top achievements
Rank 1
answered on 09 Jun 2016, 06:17 PM

Hi Maria, Thanks for the help,I went on to debug the telerik methods themselves and found what I think is something that might help on the flow the rebind method.

if you debug a listview.rebind() call, you'll be able to drill down through:
rebind -> _autoDataBind() -> _bindClientDataSource();

in there you'll have some instructions:
d.get_filterExpressions().clear();
d.get_filterExpressions().add(e);

if you enter that last one you'll see:
get_filterExpressions: function() {
            var w = this;
            var u = w._filterExpressions;
            var v = u instanceof b.FilterExpression || u instanceof b.FilterEntry;
            if (u === Object(u) && !v && (u.filters || u.logicOperator)) {
                w._filterExpressions = c.translateFiltersRecursive(u);
            } else {
                if (!u || a.isEmptyObject(u)) {
                    w._filterExpressions = new b.FilterExpression();
                }
            }
            return w._filterExpressions;
        }

A group filter will evaluate to true at this line:             var v = u instanceof b.FilterExpression || u instanceof b.FilterEntry;
So it will not satisfy all the next if's clauses:             if (u === Object(u) && !v && (u.filters || u.logicOperator)) {
and will not call c.translateFiltersRecursive(u);, which sounds like something a group filter would do...
ALSO, "u" is a non null object, so it wont be returned as an empty filter in the else, it will just be returned as a FilterEntry of field:undefined, operation:undefined, value:undefined...
just a hint though, it might not mean anything.

Declaration:
<telerik:RadListView ID="RadListView1" ClientDataSourceID="RadClientDataSource2"
                                    AllowPaging="true" PageSize="12" runat="server" RenderMode="Lightweight"
                                    Skin="Bootstrap" ClientIDMode="Static">
                                    <LayoutTemplate>
                                        <div class="container">
                                            <div class="main">
                                                <ul id="itemPlaceholder" runat="server" class="jobs-listing grid">
                                                    <asp:PlaceHolder ID="offersContainer" runat="server"></asp:PlaceHolder>
                                                </ul>
                                            </div>
                                            <br />
                                            <div class="text-center">
                                                <telerik:RadButton runat="server" CssClass="pagePrev"
                                                    ID="pagePrev" ButtonType="SkinnedButton" CausesValidation="False"
                                                    Skin="Bootstrap" Text="Prev" AutoPostBack="False">
                                                </telerik:RadButton>
                                                <telerik:RadButton runat="server" CssClass="pageNext"
                                                    ID="pageNext" ButtonType="SkinnedButton" CausesValidation="False"
                                                    Skin="Bootstrap" Text="Next" AutoPostBack="False">
                                                </telerik:RadButton>
                                            </div>
                                        </div>
                                    </LayoutTemplate>
                                    <ClientSettings>
                                        <DataBinding>
                                            <ItemTemplate>
                                            <li class="col-lg-3 col-md-3 col-sm-6 col-xs-12">
                                                <div class="jobs-content">
                                                    <div class="cs-media">
                                                        <figure>
                                                            <img alt="" style="width: auto; height: 100%;" src="#= ClientImageUrl #">
                                                        </figure>
                                                    </div>
                                                    <div class="cs-text" style="height: 225px">
                                                        <div class="cs-categories cs-color">#= ClientName #</div>
                                                        <div class="cs-post-title" style="width: 100%">
                                                            <h6><a href="/offers/Detail.aspx?id=#= OpportunityId #">#= OpportunityTitle #</a></h6>
                                                        </div>
                                                        <div class="cs-grid-job-type"><a href="" class="jobtype-btn">#= OpportunityType #</a></div>
                                                        <div class="post-options">
                                                            <span class="cs-location">#= CityName #, #= CountryName #</span>
                                                            <span class="cs-post-date">#= PublishDate #</span>
                                                        </div>
                                                        <div class="wish-list">
                                                            <button type="button" class="heart-btn shortlist" data-toggle="tooltip" data-placement="top" title="" data-original-title="Add to Shortlist"><i class="icon-heart-o"></i></button>
                                                        </div>
                                                    </div>
                                                </div>
                                            </li>
                                            </ItemTemplate>
                                        </DataBinding>
                                    </ClientSettings>

                                </telerik:RadListView>

Data Source
<telerik:RadClientDataSource runat="server" ID="RadClientDataSource2">
                                    <ClientEvents OnCommand="dataSourceCommand" OnRequestStart="requestStart" />
                                    <DataSource>
                                        <WebServiceDataSourceSettings>
                                            <Select Url="/api/opportunities" RequestType="Get" />
                                            <Insert Url="api/opportunities" RequestType="Post" />
                                            <Update Url="api/opportunities" RequestType="Put" />
                                            <Delete Url="api/opportunities" RequestType="Delete" />
                                        </WebServiceDataSourceSettings>
The JSON this /api/opportunity brings is sampled in the posts above

the declarations on pageLoad() and radcodeblock
    <script type="text/javascript">
        function pageLoad() {
            demo.initialize(
                "<%= RadListView1.ClientID%>");
        }
    </script>
    <telerik:RadCodeBlock runat="server" ID="RadCodeBlock1">
        <script>

            var updatedIDs = [], deletedIDs = [];

            function requestStart(sender, args) {
                var type = args.get_type();
                var transport = sender.get_dataSourceObject().options.transport;
                switch (type) {
                    case "read":
                        transport.read.url = "/api/opportunities/";
                        break;

                    case "create":
                        transport.create.url = "api/opportunities/";
                        break;

                    case "update":
                        transport.update.url = "api/opportunities/" + updatedIDs.shift();
                        break;

                    case "destroy":
                        transport.destroy.url = "api/opportunities/" + deletedIDs.shift();
                        break;

                    default: break;
                }
            }

            function dataSourceCommand(sender, args) {
                var commandName = args.get_commandName();
                var id = args.get_commandArgument().id;
                switch (commandName) {
                    case "update":
                        updatedIDs.push(id);
                        break;

                    case "remove":
                        deletedIDs.push(id);
                        break;

                    default: break;
                }
            }

        </script>
    </telerik:RadCodeBlock>
                                    </DataSource>

                                </telerik:RadClientDataSource>

demo.initialize:
demo.initialize = function (listViewId) {
        listView = $find(listViewId);
        filterExpressions = listView.get_filterExpressions();

        jQuery(".pageNext").click(function () {
            listView.page(listView.get_currentPageIndex() + 1);
        });

        jQuery(".pagePrev").click(function () {
            listView.page(listView.get_currentPageIndex() - 1);
        });
    }

and finally, the function that gets called to pdate the listview filters:
window.pageFilterChanging = function () {

        filterExpressions
          .clear()
          .build()
          .greaterThan("OpportunityId", 25)
          .and()
          .lessThan("OpportunityId", 30)
          .or()
          .group(function (builder) {
              builder.notEqualTo("OpportunityTitle", "y")
              .and()
              .startsWith("OpportunityTitle", "F");
          });

        filterExpressions.add("OpportunityId", Telerik.Web.UI.RadListViewFilterFunction.GreaterThan, 0);

        listView.rebind();
}

that last line is the one i debugged.

0
Maria Ilieva
Telerik team
answered on 14 Jun 2016, 10:53 AM
Hi,

Client-side filtering is demonstrated in the RadListView Client-Side Web Service DataBinding Demo and explained in detail in the RadListView Client-Side Sorting and Filtering help topic.

Regards,
Maria Ilieva
Telerik
Do you need help with upgrading your ASP.NET AJAX, WPF or WinForms projects? Check the Telerik API Analyzer and share your thoughts.
0
Irvine
Top achievements
Rank 1
answered on 14 Jun 2016, 11:01 AM
That demo is the reference I've been using and I'm building my expressions already according to that help topic. Did you get correct filtering by implementing the declarations I've sent?
0
Maria Ilieva
Telerik team
answered on 17 Jun 2016, 01:41 PM
Hi,

I have tested your approach in the online demo below and it works as expected:
http://demos.telerik.com/aspnet-ajax/listview/examples/client/webservicedatabinding/defaultcs.aspx

Regards,
Maria Ilieva
Telerik
Do you need help with upgrading your ASP.NET AJAX, WPF or WinForms projects? Check the Telerik API Analyzer and share your thoughts.
Tags
ListView
Asked by
Irvine
Top achievements
Rank 1
Answers by
Irvine
Top achievements
Rank 1
Maria Ilieva
Telerik team
Share this question
or