Dojo FAQ: How can I add filtering controls to dgrid?

By on September 6, 2013 10:48 am

As dgrid’s adoption continues to rise, one of the most common questions developers ask is how to add filtering controls. Unlike some grid implementations, dgrid does not include an out-of-the-box component implementing a user interface for filtering. This leaves some developers unsure of where to begin.

dgrid does not include a filtering module because it’s impossible to build a one-size-fits-all solution. Requirements for a filtering UI can vary widely, and advanced implementations may rely on features specific to a certain dojo/store implementation.

Creating a simple filtering interface is as easy as creating an HTML form, and updating the query property of the grid based on its input.

HTML:

<form id="filterForm">
	Filter by Last Name: <input type="text" name="filter">
	<button type="submit">Filter</button>
</form>
<div id="grid"></div>

JavaScript:

require([
	"dojo/dom",
	"dojo/on",
	"dojo/store/Memory",
	"dgrid/OnDemandGrid"
], function (dom, on, Memory, OnDemandGrid) {
	var form = dom.byId("filterForm"),
		store = new Memory({ data: [
			{ id: 1, firstName: "Bryan", lastName: "Forbes" },
			{ id: 2, firstName: "Kenneth", lastName: "Franqueiro" },
			{ id: 3, firstName: "Colin", lastName: "Snover" },
			{ id: 4, firstName: "Kris", lastName: "Zyp" }
		] }),
		grid = new OnDemandGrid({
			columns: {
				"firstName": "First Name",
				"lastName": "Last Name"
			},
			sort: "lastName",
			store: store
		}, "grid");
	
	on(form, "submit", function (event) {
		var value = form.elements.filter.value;

		// Filter lastName, matching against the input text
		grid.set("query", { lastName: value });

		// Since we're using a form, prevent normal submission
		event.preventDefault();
	});
});

The focal point of this example is the call to grid.set("query", ...). Supported by both OnDemandList and the Pagination extension, this instructs the grid to send the indicated query to the store’s query method.

Different stores support different types of query arguments; the most common format is an object containing key/value pairs, where the key indicates the field to filter by, and the value indicates what to match against. In this example, the Memory store will perform exact matches only. That doesn’t seem terribly useful, but we have a few other options, because Memory uses SimpleQueryEngine. We can update line 27 above as follows:

grid.set("query", { lastName: new RegExp(value, "i") });

This will perform a case-insensitive search for items containing the entered text anywhere within lastName. At the same time, this illustrates just how quickly a particular filtering solution can become specific to the store implementation the grid is paired with.

The simple API that dgrid provides is just the starting point — where to go from there is limited only by your imagination.

Comments

  • Curt Williams

    When using the tree plugin for dgrid, I think the query must be used to select just the root records and exclude all children. i.e. query: {type: “continent”} So what do you do when you want to filter certain child records out of the grid entirely (i.e. not shown when parent is expanded). The query does not prevent children from being shown when their parent is expanded.

  • Ken Franqueiro

    Using the query property to properly filter the root level of a grid
    displaying hierarchical data is indeed a common approach when
    relationships are recorded from the bottom up. You’re right that this
    presented a significant roadblock to filtering child items.

    As of
    dgrid 0.3.11, the tree plugin will forward the query property’s value to getChildren calls via options.originalQuery, making it possible to use the query property to filter child
    items.
    This still leaves the question of the root query. Given that each
    hierarchical store is likely to have its own implementation details, it
    makes sense to tackle this on the store end. The store
    used in dgrid’s tree test pages has been updated to follow this
    approach:
    https://github.com/SitePen/dgrid/blob/master/test/data/base.js#L213-236

    Thanks for raising this issue in https://github.com/SitePen/dgrid/issues/732 – it was long overdue to be addressed.

  • Deepak

    I tried to used originalQuery to to bae able to use the query property to filter the children. But the children nodes are now being rendered under root. Could you please comment on this behavior ?

    Thanks

  • anand kr jha

    How can we query on multiple columns with OR logical implementation, here if we apply query for multiple columns say — grid.set(“query”, { lastName: new RegExp(value, “i”) , firstName: new RegExp(value, “i”) }); — it returns
    rows having value in both the columns (lastName,firstName)

  • Laurence

    Is this filtering still working with the latest version (V0.4) of dgid?

    grid.set(“query”, { lastName: value });

  • See the migration guide at https://github.com/SitePen/dgrid/blob/v0.4.0/doc/migrating/0.4-Migration.md for the API updates (basically you will switch from setting a query to setting a collection as a filter against your store)

  • Anand M

    Awesome post Ken! Thank You!

    Based on Ken’s post and some and some other people’s ideas I have a jsfiddle example here if anyone is interested. Hope people will improve upon it and we will have better interface.

    https://jsfiddle.net/AnandMatam/9vp8zj27/