Click here to Skip to main content
14,040,568 members
Click here to Skip to main content
Add your own
alternative version


19 bookmarked
Posted 9 Sep 2010
Licenced CPOL

JavaScript Filtering with JSON and Filter Management

, 16 Sep 2010
Rate this:
Please Sign up or sign in to vote.
Part 1 of creating a dynamical filtering mechanism in C#


This article will explain a simple client-side filtering framework that can be implemented in any page to obtain easy-to-use filters.


I was looking for some controls that could help me create my application. The control which suited me the most was jqGrid - a jQuery plugin. jqGrid displays a JSON data source in tabular format, along with filtering and sorting. For this, we must define a columns model (see example) - in JSON format of course:

   	{name:'id',index:'id', width:60, sorttype:"int"},
   	{name:'name',index:'name', width:100, editable:true},
   	{name:'note',index:'note', width:150, sortable:false}		

Using the Code

Unfortunately, the filtering capability of the jqGrid is not as complex as I need. A filter is a JSON object with the following format type:

{ "groupOp": "and",
      "rules": [
        { "field": "name", "op": "eq", "data": "Romania" }, 
        { "field": "id", "op": "le", "data": "1"}

It's basically a set of rules grouped together using a logical operator: "OR" or "AND". For a simple search, this filter can be enough, but anything more complex requires a tree of such groups. So let's add an array of groups to this structure. Now we have the tree structure that we need and still maintain the support for normal jqGrid filters. Suppose we would need a filter like this:

(name == "John" AND age > 30) OR (name == "Doe" AND age < 30) OR name == "Joe"

Note first that between groups and also between groups and rules, we must have the same logical operator, otherwise we will have to isolate them in a subgroup. The above formula will map into:

{ "groupOp": "or",
      "groups": [
		{ "groupOp": "AND", 
		  "rules": [
		      { "field": "name", "op": "eq", "data": "John" },
			  { "field": "age", "op": "gt", "data": "30" }
		{ "groupOp": "AND", 
		  "rules": [
		      { "field": "name", "op": "eq", "data": "Doe" },
			  { "field": "age", "op": "lt", "data": "30" }
      "rules": [{ "field": "name", "op": "eq", "data": "Joe" }]

As I said, we have two types of operators: group operators and rule operators. The only group operators are "OR" and "AND". As rule operators, we have: eq (equal to), us (different to), lt (lower than), etc. as well as string operators: cn (contains), sw (starts with), etc. The above can be easily converted into a syntax closer to the JavaScript, by using functions:

(eq(, "John") && gt(item.age, "30")) || 
	(eq(, "Doe") && lt(item.age, "30")) || eq(, "Joe")

Note that all entity fields have are prefixed with "item.". Let's define the necessary JavaScript functions:

function eq(d1, d2) { return d1 == d2; }
function lt(d1, d2) { return d1 < d2; }
function gt(d1, d2) { return d1 > d2; }

Now we can loop through a JSON object and evaluate the above formula.

var jsonItems = [
	{"name": "John", "age": "18"},
	{"name": "Amanda", "age": "21"},
	{"name": "Dave", "age": "31"}

var expression = '(eq(, "John") && gt(item.age, "30")) || 
	(eq(, "Doe") && lt(item.age, "30")) || eq(, "Joe")';

var newJsonItems = [];
for(var index = 0; index < jsonItems.length; index++){
	var item = jsonItems[index]; // define the item that will be evaluated
	if(eval(expression) == true){

So far we have logic, but we need a web user interface to cofigure the filter. Luckily I wrote a JS class that does this: xFilter (see attachment). To use it, you only need to provide the DOM parent element and columns model.

var colModel = [
	{ "name": "id"},// we only need this field, jqGrid requires the rest
	{ "name": "name"},
	{ "name": "note"}
var items = [
	{ "name": "Romania", "id": "1", "note": "ro" },
	{ "name": "Franta", "id": "2", "note": "fr"},
	{ "name": "Anglia", "id": "3", "note": "uk"},
	{ "name": "Italia", "id": "4", "note": "it" },
	{ "name": "Germania", "id": "5", "note": "ge" }
var f = new xFilter(document.getElementById("fil"),
	columns: colModel,
	onchange: function() {
		document.getElementById("message").innerHTML =	

		var resItems = f.Apply(items);
		var s = "";
		for (var i = 0; i < resItems.length; i++) {
			s += "," + resItems[i].name;
		document.getElementById("message").innerHTML = s;

As you can see, the class has the "onchange" event that is triggered whenever a change to the filter occurs. Of course, one can use the method "Apply" - whose logic is presented above - to filter a JSON object.


Hope you enjoyed this. The next article will take this model on the server side (C#), where the filters we've created will become expression trees that can be used with LINQ implementations.


Part 2 of creating a dynamical filtering mechanism in C#


This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


About the Author

Romania Romania
No Biography provided

You may also be interested in...


Comments and Discussions

QuestionGreat! Pin
Member 765759626-Aug-13 10:33
memberMember 765759626-Aug-13 10:33 
GeneralMy vote of 5 Pin
Manoj Kumar Choubey9-Aug-12 21:22
professionalManoj Kumar Choubey9-Aug-12 21:22 
GeneralMy vote of 5 Pin
Manoj Kumar Choubey3-Feb-12 1:09
professionalManoj Kumar Choubey3-Feb-12 1:09 
GeneralMy vote of 5 Pin
JohanJAM13-Jan-11 16:18
memberJohanJAM13-Jan-11 16:18 
QuestionIs this implementable in jqGrid? Pin
JohanJAM13-Jan-11 16:16
memberJohanJAM13-Jan-11 16:16 
AnswerRe: Is this implementable in jqGrid? Pin
strofo4-Mar-11 9:04
memberstrofo4-Mar-11 9:04 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

Permalink | Advertise | Privacy | Cookies | Terms of Use | Mobile
Web02 | 2.8.190425.1 | Last Updated 16 Sep 2010
Article Copyright 2010 by strofo
Everything else Copyright © CodeProject, 1999-2019
Layout: fixed | fluid