Advanced Kendo Filter Configurations

Advanced Kendo Filter Configurations

In this blog post, we will be looking at creating custom filters that can be applied to the DataSource of various TPC Widgets such as: TPC Grid, TPC ListView, and TPC LookUp. This article can be applied to any of the TPC widgets that utilize a DataSource object. 


Often when we display data, there are cases when we would like to limit the amount or type of data that specific users have access to. This could be for a variety of reasons including security or ease of use. If we are filtering data for security purposes, we must filter the data on the server side. This can be accomplished through the TPC FetchXML builder. Once data has been filtered on the server-side, there is no way we can access it on the client-side. Although, sometimes we would like to apply filters to the data temporarily, or on subsets of the original data based on user input or conditions. This is where Kendo Filters come into play. Kendo filters can be utilized to apply or remove a client-side filter from the DataSource with ease via JavaScript. 

The simplest filter requirement that we typically see is the addition of a textbox that can be used to filter a TPC Grid or TPC ListView by a search term. This type of filtering has been covered in a blog post by Adam Benoit, which can be found here. I would highly recommend reading this article to acquire a basic understanding of how filters can be applied to a TPC ListView or TPC Grid. In this blog post we will be covering some more advanced filter requirements.

Dropdown Filters

The next type of filter we will be looking at is the ability to filter a grid based on a dropdown menu selection. Usually this type of selection is used when we want to provide a user with different views. In this example we will be filtering accounts based on a custom field called Genre. Below is a snippet of the HTML and JavaScript required to make a simple dropdown which filters a Grid based on Genre.


<div class="row">
    <div class="col-sm-3 col-sm-offset-9">
        <div class="form-group">
            <div class="row">
                <div class="col-xs-12">
                    <input class="form-control" id='view-selector'/>
                </div>
            </div>
        </div>  
    </div>
</div>



$(document).ready(function() {

    //Get Account Grid
    var grid = tpc.page.TpcGridModel.get_grid();

    //Create Dropdown Selections
    var viewSelectionData = [
        {text: "Punk", value:"Punk"},
        {text: "Funk", value:"Funk"},
        {text: "Latin", value:"Latin"},
        {text: "Disco", value:"Disco"}
    ];

    //Initialize Dropdown Menu 
    $("#view-selector").kendoDropDownList({
        dataTextField: "text",
        dataValueField: "value",
        dataSource: viewSelectionData,
        height: 100,
        select: selectView
    })
    .closest(".k-widget")
    .attr("id", "view-selector_wrapper");

    var viewSelectionDropdownList = $("#view-selector").data("kendoDropDownList");

    //Select View Function
    function selectView(e) {

        //Get DataSource
        var dataSource = grid.dataSource;

        //Apply Filter
        if (e.dataItem) {
            dataSource.filter({
                logic: "and",
                filters: [
                    {field: "event_genre", operator: "eq", value: e.dataItem.value}
                ]
            });
        }
    };
});


Account Grid

Awesome! So now we have a dropdown filter that can be used to filter the Accounts based on Genre! Although, you may have noticed one small issue. When the grid initially loads, it will not be filtered based on the selected dropdown menu item. This is a common requirement, where the grid is to be filtered based on certain criteria when the data first loads. Below is a snippet which can be used to filter a grid one time, upon the fire of the Databound event which is when data is bound to the Datasource.


//Get DataSource
var dataSource = grid.dataSource;

//Filter Based on Selected Item
grid.one("dataBound", dataSource.filter({
    logic: "and",
        filters: [
            {field: "event_genre", operator: "eq", value: viewSelectionDropdownList.value()}
        ]
    })
);  



TPC Form Filters

When it comes to complicated filter requirements, often we are dealing with a variety of different filters, and a variety of different data types. For filtering requirements like these, one extremely efficient approach is to use a TPC Form as the means of filtering the Grid or ListView. The reason this approach is so effective, is because the TPC JavaScript API allows us to easily get the value of these difficult to handle fields such as Picklists, Lookups, and Status fields. 

Contacts Grid

The first step in this approach is to create a TPC Form with the entity that you would like to filter, in our case we will be using Contacts. On this form, you will need to make sure you display all the fields you would like to filter the grid on. In our configuration, most of the fields are simple TPC Form Widgets, with no additional customization. Although, for this example we will filter lookups using both a dropdown selection (Owner), and a text field (Company Name), so the second lookup is custom HTML markup. The other alteration is that to filter based on the birthdate, we need to add an additional dropdown selection that allows us to select the condition of the date filter. This custom date condition selector will be added to a custom “Write” template of the TPC DateTime widget. The last customization to this form configuration is a custom Filter and Clear button. The code for all these customizations are displayed below.


<!-- Custom Time - Filter Condition -->
<input class="form-control" id='date-condition' style="width: 50% !important; box-sizing: border-box !important; float: left; border: none;"/>

<!-- Company Name Textbox -->
<div class="form-group">
    <div class="row">
        <div class="col-xs-12">
            <label class="control-label">Company Name</label>
            <input class="form-control" id='parentcustomerid' data-tpc-role="text-field-input"/>
        </div>
    </div>
</div>
<!-- Submit/Clear Button -->
<div class="form-group">
    <div class="row">
        <div class="col-xs-12 text-right" style="min-height: 85px;">
            <button style="display: inline;" class="btn btn-primary" id="filter" type="button">Apply</button>
            <button style="display: inline; margin-left: 5px;" class="btn btn-secondary" id="reset" type="button">Clear</button>
        </div>
    </div>
</div>


DateTime Custom Template

Contact Filter Form Configuration

After the form has been configured, the last piece of this requirement is to create the custom JavaScript which will handle our filtering. Essentially the JavaScript is broken down into 3 main parts. The first part handles the initialization of the form, including the event handlers. The second part handles the application of the filters, which is trigger upon pressed “Enter” or the “Apply” button. The third part of this code handlers clearing the filters, which is triggered upon pressing the “Clear” button.


$(document).ready(function() {

    //Variables
    var filterButton = document.querySelector('#filter');
    var resetButton = document.querySelector('#reset');

    //This Section is Used to Initialize Dropdowns
    var timeConditionData = [
        {text: "", value:""},
        {text: "On", value:"on"},
        {text: "On or After", value:"onorafter"},
        {text: "On or Before", value:"onorbefore"},
        {text: "Any Time", value:"isnotnull"}
    ];

    $("#date-condition").kendoDropDownList({
        dataTextField: "text",
        dataValueField: "value",
        dataSource: timeConditionData,
        height: 100
    })
    .closest(".k-widget")
    .attr("id", "date_condition_wrapper");

    var timeDropdownList = $("#date-condition").data("kendoDropDownList");

    //Assign Event Listeners
    filterButton.addEventListener('click', applyFilter);
    document.addEventListener('keyup', function(event){
        event.preventDefault();
        //Enter Key
        if (event.keyCode === 13) {
            applyFilter();
        }
    })
    resetButton.addEventListener('click', clearFilter);

    //Functions

    /**
     * This function is used to apply the filters
     */
    function applyFilter(){

        //Get DataSource
        var dataSource = tpc.page.TpcGridModel.get_grid().dataSource;
        var filters = new Array();

        //Get Values from Form
        var firstName = tpc.forms.sf_contactfilters.firstname.get_value();
        var email = tpc.forms.sf_contactfilters.emailaddress1.get_value();
        var owner = tpc.forms.sf_contactfilters.ownerid.get_kendoInput().text();
        var status = tpc.forms.sf_contactfilters.statuscode.get_value();
        var companyName = document.querySelector('#parentcustomerid').value;
        var birthdateCondition = timeDropdownList.value();
        var birthdateValue = tpc.forms.sf_contactfilters.birthdate.get_value();

        //Create Filters
        if (firstName.trim() != ""){
            filters.push({
                field: "firstname", 
                operator: "contains", 
                value: firstName
            });
        };

        if (email.trim() != ""){
            filters.push({
                field: "emailaddress1", 
                operator: "contains", 
                value: email
            });
        };

        if (owner.trim() != ""){
            filters.push({
                field: "ownerid", 
                operator: "eq", 
                value: owner
            });
        };

        if (status.trim() != ""){
            filters.push({
                field: "statuscode", 
                operator: "eq", 
                value: status
            });
        };

        if (companyName.trim() != ""){
            filters.push({
                field: "parentcustomerid", 
                operator: "contains", 
                value: companyName
            });
        };

        if (birthdateCondition.trim() != ""){

            if (birthdateCondition != "isnotnull" && birthdateCondition != "isnull" && birthdateValue != null){
                filters.push({
                    field: "birthdate", 
                    operator: birthdateCondition, 
                    value: birthdateValue
                });
            }

            else if (birthdateCondition === "isnotnull" || birthdateCondition === "isnull" ){
                filters.push({
                    field: "birthdate", 
                    operator: birthdateCondition, 
                    value: undefined
                });
            }
        };

        //Add Filters to Data Source
        if (filters.length > 0){
            dataSource.filter({
                logic: "and",
                filters: filters
            });
        }

        else {
            dataSource.filter([]);
        }
    };

    /**
     * This function is used to clear the filters
     */
    function clearFilter(){

        //Get DataSource
        var dataSource = tpc.page.TpcGridModel.get_grid().dataSource;

        //Reset Form Values
        tpc.forms.sf_contactfilters.firstname.clear();
        tpc.forms.sf_contactfilters.emailaddress1.clear();
        tpc.forms.sf_contactfilters.ownerid.clear();
        tpc.forms.sf_contactfilters.statuscode.clear();
        document.querySelector('#parentcustomerid').value = "";
        timeDropdownList.select(0);
        tpc.forms.sf_contactfilters.birthdate.clear();

        //Clear Filters in Data Source
        dataSource.filter([]);
    };
});


Contacts Grid Final Filtering Results


There you have it! Enjoy, and happy filtering!

WANT TO TAKE YOUR WEB PORTAL TO THE NEXT LEVEL ? 

Stay informed of Web Portal Tips & Tricks from Portal Hero!

Sign up for our newsletter!

loading image
Become a Portal Hero!