Client Side filtering with filterExpression builder

10 posts, 0 answers
  1. Irvine
    Irvine avatar
    6 posts
    Member since:
    May 2016

    Posted 23 May Link to this post

    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

  2. Irvine
    Irvine avatar
    6 posts
    Member since:
    May 2016

    Posted 25 May Link to this post

    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.

  3. UI for ASP.NET Ajax is Ready for VS 2017
  4. Maria Ilieva
    Admin
    Maria Ilieva avatar
    4017 posts

    Posted 26 May Link to this post

    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.
  5. Irvine
    Irvine avatar
    6 posts
    Member since:
    May 2016

    Posted 27 May Link to this post

    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.
  6. Irvine
    Irvine avatar
    6 posts
    Member since:
    May 2016

    Posted 27 May in reply to Irvine Link to this post

    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
  7. Maria Ilieva
    Admin
    Maria Ilieva avatar
    4017 posts

    Posted 31 May Link to this post

    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.
  8. Irvine
    Irvine avatar
    6 posts
    Member since:
    May 2016

    Posted 09 Jun in reply to Maria Ilieva Link to this post

    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.

  9. Maria Ilieva
    Admin
    Maria Ilieva avatar
    4017 posts

    Posted 14 Jun Link to this post

    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.
  10. Irvine
    Irvine avatar
    6 posts
    Member since:
    May 2016

    Posted 14 Jun Link to this post

    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?
  11. Maria Ilieva
    Admin
    Maria Ilieva avatar
    4017 posts

    Posted 17 Jun Link to this post

    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.
Back to Top
UI for ASP.NET Ajax is Ready for VS 2017