The idea is simple: filter data in JavaScript using the native filtering (Array.prototype.filter) in a descriptive/declarative way uxing JSON. The implementation is less trivial.
- {} objects are implicitly ANDs. An empty array will keep "truthy" items.
- [] arrays are implicitly ORs. An empty object will keep "falsey" items.
This is useful in an OR-clause to filter objects on property values where the property might not exist. true
will keep all results. Provided as a fallback for degenerate cases.false
will keep no results. Provided as a fallback for degenerate cases.- 'and' is an array of clauses. Provided to inspect the same property more than once.
- 'count' checks the 'length' property of the list.
- 'is' is an array or object. Provided to allow for complex clauses.
Allows nested clauses without implicitly "drilling" into the data. - 'length' checks the 'length' property of each item.
- 'not' is either an array or object. The results are negated.
- 'op' is a string (from BooleanBinaryComparator) to allow for a comparison other than (strict) equality, including (serialized) regular expressions.
- 'or' is an object of clauses. Provided to truncate deep conditions.
- 'subClause' is an array or object. This is a sub-filter on nested data.
This is invaluable when the real filtering needs to be done deeper than the root element without affecting ancestor (or ancestor sibling) filtering. - The query-by-example 'this' object is expected to be an anonymous/Object object. This requirement might be removed in the future.
- Provide a
DataFilter.dataFilter( data, whereClause )
to handle array boxing and unboxing of non-array data. - Provide a
DataFilter.jQueryWhereClauseDataFilter( response_data, content_type )
for use withjQuery.ajax
.
var original =
[
{
'list':
[
{'a':{'b':'3', 'c':"hi"}},
null,
{'a':{'c':"bye"}},
{'a':null}
],
'sibling':"property"
}
];
Statically define, build from user input, retrieve from a web service, etc. a where clause.
var whereClause =
{
// #2: The clause digs into the object's 'list' property.
"list":
{
// #3: Wrap predicates in a 'subClause' so ancestor filtering is not affected.
"subClause":
{
// #4: Not any of the following.
"not":
[
// #4a: "falsey".
[],
// #4b: Containing a "falsey" 'a'.
{"a":[]},
// #4c: Containing an 'a' which contains a 'c' having value 'bye'.
{"a":{"c":"bye"}}
]
}
}
};
Perform the filtering.
// #5: Wrap the object in an anonymous array so it can be processed in a list.
var filtered = original.filter( DataFilter.resultsWhere, whereClause );
Filtered results now contains (serialized for clarity):
[
{
"list":
[
{
"a":
{
"b": "3",
"c": "hi"
}
}
],
"sibling": "property"
}
]
Set jQuery.ajax
dataFilter
option to DataFilter.jQueryWhereClauseDataFilter
and add whereClause
query definition.
var getOptions =
{
'method':'GET',
'dataFilter':DataFilter.jQueryWhereClauseDataFilter,
'whereClause':{"list":{"subClause":{"not":[[],{"a":[]},{"a":{"c":"bye"}}]}}},
};
$.ajax( url, getOptions )
.done( function( responseData, status_text, jqXHR )
{})
.fail( function( jqXHR, status_text, error_thrown )
{});