Different Date Filter Operators when using Extra(true)

4 posts, 0 answers
  1. David
    David avatar
    4 posts
    Member since:
    Feb 2018

    Posted 09 May 2019 Link to this post

    I have a grid that contains a date. I would like to filter the grid based on a "start date" and an "end date" I can specify Extra(true) to get 2 date pickers in the menu filter. And I can specify "Greater Than or Equal To" and "Less Than or Equal To" as the operators. But what I would like is the first operator to only be "Greater Than or Equal To" and the second operator to only be "Less Than or Equal To"  Is there a way to do that?

    Thanks,

    Dave Shine


  2. Tsvetomir
    Admin
    Tsvetomir avatar
    757 posts

    Posted 13 May 2019 Link to this post

    Hi David,

    The elements which are located within the filter menu are actually Kendo UI widgets. In the relevant event handler any of the exposed widgets can be modified. If you would like to restrict the user to select only "Less than" or "Greater than" options, refer to the code snippets below:

    .Events(ev=>ev.FilterMenuOpen("onFilterMenuOpen"))

    <script>
        function onFilterMenuOpen(e) {
            if (e.field == "OrderDate") {
                var element = e.container.find("select[data-role=dropdownlist]:not(.k-filter-and)").eq(1);
                var ddl = element.getKendoDropDownList();
                ddl.value("lte"); // set the value of the second dropdown
                ddl.trigger("change");
            }
        }
    </script>

    Also, you might want to leave only these two options in the filter menu for the date columns:

    .Filterable(ftb =>
    {
        ftb.Mode(GridFilterMode.Menu);
        ftb.Operators(operators =>
        {
            operators.ForDate(options =>
            {
                options.Clear();
                options.IsGreaterThanOrEqualTo("From Date");
                options.IsLessThanOrEqualTo("To Date");
            });
        });
    })

    Give these suggestions a try and let me know in case further assistance is required.


    Kind regards,
    Tsvetomir
    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.
  3. David
    David avatar
    4 posts
    Member since:
    Feb 2018

    Posted 13 May 2019 in reply to David Link to this post

    Hello Tsvetomir,

    Thanks for your reply. After working with Georgi in Telerik Support, I have implemented the following solution to my issue.

     

    function onFilterMenuInit(e) {
        if (e.field !== 'DeliveryDate' && e.field !== 'PickupDate') return;
     
        var grid = this;
     
        // Set the Header Text
        var header = e.container.find('.k-filter-help-text');
        header[0].innerHTML = "Show items between dates";
     
        // Hide all the logic controls and buttons
        e.container.find('[data-bind="value: filters[0].operator"]').data('kendoDropDownList').wrapper.hide();
        e.container.find('[data-bind="value: filters[1].operator"]').data('kendoDropDownList').wrapper.hide();
        e.container.find('.k-filter-and').parents('.k-widget').hide();
        e.container.find('.k-action-buttons').hide();
     
        // Find the 2 date picker controls
        var picker1 = e.container.find('[data-role="datepicker"]:eq(0)').data('kendoDatePicker');
        var picker2 = e.container.find('[data-role="datepicker"]:eq(1)').data('kendoDatePicker');
     
        // Remove the data-bind attributes, I'll handle this myself
        picker1.element.removeAttr('data-bind');
        picker2.element.removeAttr('data-bind');
     
        // Set the on change events for the 2 date pickers
        picker1.bind('change',
            function() {
                proccessFilter(grid, 'gte', e.field, this.value());
            });
     
        picker2.bind('change',
            function() {
                proccessFilter(grid, 'lte', e.field, this.value());
            });
     
    }
     
    function proccessFilter(grid, operator, field, value) {
      
        var expression = grid.dataSource.filter();
     
        if (!expression) {
          expression = { logic: 'and', filters: [] };
        }
     
        removeFiltersForField(expression,field, operator);
     
        if (value) {
            expression.filters.push({ field: field, operator: operator, value: value });
        }
     
        grid.dataSource.filter(expression);
    }
     
    function removeFiltersForField(expression, field, operator) {
        if (expression.filters) {
            expression.filters = $.grep(expression.filters, function (filter) {
                removeFiltersForField(filter, field);
                if (filter.filters) {
                    return filter.filters.length;
                } else {
                    return filter.field != field || filter.operator != operator;
                }
            });
        }
    }

     

    Dave Shine

  4. Tsvetomir
    Admin
    Tsvetomir avatar
    757 posts

    Posted 15 May 2019 Link to this post

    Hi Dave,

    Thank you for sharing the solution with our community.

    Generally, the provided solution does filter the grid's data source manually and in case a filter has been applied, it gets overridden. Nevertheless, it is really up to one's preferences to which approach would be used, as the requirements might be to have a preselected filter operator, or a restriction for filtering with a different operator.

    As always, me and the team are available in case further questions arise. 


    Kind regards,
    Tsvetomir
    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.
Back to Top