Click here to Skip to main content
15,868,141 members
Articles / Programming Languages / Javascript

JavaScript Filtering with JSON and Filter Management

Rate me:
Please Sign up or sign in to vote.
4.80/5 (6 votes)
16 Sep 2010CPOL2 min read 131.7K   1K   20   6
Part 1 of creating a dynamical filtering mechanism in C#
xFilter.jpg

Introduction

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

Background

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:

JavaScript
colModel:[
   	{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:

JavaScript
{ "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:

JavaScript
(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:

JavaScript
{ "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:

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

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

JavaScript
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.

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

var expression = '(eq(item.name, "John") && gt(item.age, "30")) || 
	(eq(item.name, "Doe") && lt(item.age, "30")) || eq(item.name, "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){
		newJsonItems.push(item);
	}
}

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.

JavaScript
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 =	
			this.toUserFriendlyString();

		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.

Conclusion

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.

Link

Part 2 of creating a dynamical filtering mechanism in C#

License

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


Written By
Engineer
Romania Romania
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
QuestionGreat! Pin
Member 765759626-Aug-13 10:33
Member 765759626-Aug-13 10:33 
GeneralMy vote of 5 Pin
Manoj Kumar Choubey9-Aug-12 21:22
professionalManoj Kumar Choubey9-Aug-12 21:22 
Nice
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
JohanJAM13-Jan-11 16:18 
QuestionIs this implementable in jqGrid? Pin
JohanJAM13-Jan-11 16:16
JohanJAM13-Jan-11 16:16 
AnswerRe: Is this implementable in jqGrid? Pin
strofo4-Mar-11 9:04
strofo4-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.