Creating custom filter widget

If you need to create custom user interface to filter specific grid columns - you can do it with Grid.Mvc.
To do this you need:
  1. Create specific javascript object, that will render your interface;
  2. Setup custom filter widget name with 'SetFilterWidgetType' function;
  3. Register custom filter on the client side

Introduce

Image that you display the column with customer names. By default Grid.Mvc render filter interface for text column and she will looks like:

widget-1.png

By you want to provide more specific filter interface for this column. For example, you want that user picks customer from customer's list, like:

widget-2.png

Creating javascript widget object

Your javascript object should have the following functions:
  1. getAssociatedTypes - returns the array of filter types, that associated with current widget;
  2. showClearFilterButton - returns true/false and specify whether render 'Clear filter' button for this widget;
  3. onRender - this function invokes by Grid.Mvc and tell that you need to render your widget, This method invokes once, when user first time click on filter button;
  4. onShow - this function invokes by Grid.Mvc and tell that you widget was shown to user (open popup window);

Below is the example of filter widget (you can find it in the sample web app in the source):


/***
* CustomersFilterWidget - Provides filter user interface for customer name column in this project
* This widget onRenders select list with avaliable customers.
*/

function CustomersFilterWidget() {
    /***
    * This method must return type of registered widget type in 'SetFilterWidgetType' method
    */
    this.getAssociatedTypes = function () {
        return ["CustomCompanyNameFilterWidget"];
    };
    /***
    * This method invokes when filter widget was shown on the page
    */
    this.onShow = function () {
        /* Place your on show logic here */
    };

    this.showClearFilterButton = function () {
        return true;
    };
    /***
    * This method will invoke when user was clicked on filter button.
    * container - html element, which must contain widget layout;
    * lang - current language settings;
    * typeName - current column type (if widget assign to multipile types, see: getAssociatedTypes);
    * values - current filter values. Array of objects [{filterValue: '', filterType:'1'}];
    * cb - callback function that must invoked when user want to filter this column. Widget must pass filter type and filter value.
    * data - widget data passed from the server
    */
    this.onRender = function (container, lang, typeName, values, cb, data) {
        //store parameters:
        this.cb = cb;
        this.container = container;
        this.lang = lang;

        //this filterwidget demo supports only 1 filter value for column column
        this.value = values.length > 0 ? values[0] : { filterType: 1, filterValue: "" };

        this.renderWidget(); //onRender filter widget
        this.loadCustomers(); //load customer's list from the server
        this.registerEvents(); //handle events
    };
    this.renderWidget = function () {
        var html = '<p><i>This is custom filter widget demo.</i></p>\
                    <p>Select customer to filter:</p>\
                    <select style="width:250px;" class="grid-filter-type customerslist form-control">\
                    </select>';
        this.container.append(html);
    };
    /***
    * Method loads all customers from the server via Ajax:
    */
    this.loadCustomers = function () {
        var $this = this;
        $.post("/Home/GetCustomersNames", function (data) {
            $this.fillCustomers(data.Items);
        });
    };
    /***
    * Method fill customers select list by data
    */
    this.fillCustomers = function (items) {
        var customerList = this.container.find(".customerslist");
        for (var i = 0; i < items.length; i++) {
            customerList.append('<option ' + (items[i] == this.value.filterValue ? 'selected="selected"' : '') + ' value="' + items[i] + '">' + items[i] + '</option>');
        }
    };
    /***
    * Internal method that register event handlers for 'apply' button.
    */
    this.registerEvents = function () {
        //get list with customers
        var customerList = this.container.find(".customerslist");
        //save current context:
        var $context = this;
        //register onclick event handler
        customerList.change(function () {
            //invoke callback with selected filter values:
            var values = [{ filterValue: $(this).val(), filterType: 1 /* Equals */ }];
            $context.cb(values);
        });
    };

}


This example loads customer's list from the server via ajax, build and render layout in 'onRender' method (when users first time clicking on filter button).

Setup custom filter type

Filter type - is a string, that specify, which filter widget should render on the column. By default he's setup to field .Net type. If you want to override this type you need to use SetFilterWidgetType function:

columns.Add(o => o.Customers.CompanyName).Titled("Company Name")
                                   .Sortable(true)
                                   .Filterable(true)
                                    .SetFilterWidgetType("CustomCompanyNameFilterWidget");

Filter type must contains in getAssociatedTypes array of your JS object in the step 1.

Register filter widget

In the last step you need to add custom widget in the Grid.Mvc filters collection. You can do this by using 'addFilterWidget'. Adds the following script after gridmvc.min.js:

<script>
        pageGrids.ordersGrid.addFilterWidget(new CustomersFilterWidget());
</script>

Where CustomersFilterWidget - object defined in step 1.

You can look at this example: Online demo page or research in the source code.

Read more: Localization

Last edited Sep 25, 2013 at 10:07 AM by Bukharin, version 6