Skip to content
Snippets Groups Projects
Commit f415eec1 authored by Sebastian Listl's avatar Sebastian Listl :speech_balloon:
Browse files

JditoFilter_lib improved

parent eae2402c
No related branches found
No related tags found
No related merge requests found
......@@ -4,35 +4,41 @@ import("Sql_lib");
import("Util_lib");
import("system.datetime");
//@TODO: add support for permissions to the lib
/**
* object for filtering records
*
* @param {Array} pColumns the column names
* @param {Object} pFilter the filter object
* @param {Object} pCustomCheckFns
* @param {Object} pCheckFnThisArg
* @param {Object} [pFilter] the filter object
* @param {Array} [pFieldOrder] the fields
*/
function JditoFilter (pFilter, pFieldOrder)
{
this._fieldInfos = {};
this.fieldOrder(pFieldOrder);
this._filter = null;
this.filter(pFilter);
this._ignoreCase = JditoFilterUtils.isUserIgnoreCase();
this._lookupFields = [];
}
/**
* Sets the filter of the object
*
* @private
* @param {Object} pFilter the filter object that should be used (e.g. vars.get("$local.filter"))
* @return {JditoFilter} current object
*/
function JditoFilter (pColumns, pFilter, pCustomCheckFns, pCheckFnThisArg)
JditoFilter.prototype.filter = function (pFilter)
{
var columnMap = {};
for (let i = 0, l = pColumns.length; i < l; i++)
if (pFilter)
{
let col = pColumns[i];
if (col)
columnMap[col] = {
index : i,
checkFn : (pCustomCheckFns ? pCustomCheckFns[col] : null)
};
if (!Utils.isObject(pFilter))
throw new TypeError("JditoFilter: Wrong type for the filter, expected 'object' but got '" + (typeof pFilter) + "'");
this._filter = "filter" in pFilter ? pFilter.filter : pFilter;
if (this._filter && this._filter.childs.length !== 0)
_removeEmptyGroups(this._filter.childs);
}
this.columnMap = columnMap;
if (pFilter && pFilter.childs.length !== 0)
_removeEmptyGroups(pFilter.childs);
this.filter = pFilter;
this.checkFnThisArg = pCheckFnThisArg || null;
return this;
function _removeEmptyGroups (pCurrentArray)
{
......@@ -49,6 +55,104 @@ function JditoFilter (pColumns, pFilter, pCustomCheckFns, pCheckFnThisArg)
}
}
/**
* Sets the filter of the object
*
* @param {String} pFilter the filter object that should be used as JSON string
* @return {JditoFilter} current object
*/
JditoFilter.prototype.filterJSON = function (pFilter)
{
return this.filter(JSON.parse(pFilter));
}
/**
* Sets the order of the columns
*
* @param {Array} pFields array containing the field names in the right order
* @return {JditoFilter} current object
*/
JditoFilter.prototype.fieldOrder = function (pFields)
{
for (let i = 0, l = pFields.length; i < l; i++)
{
let fieldName = pFields[i];
if (fieldName)
{
//remove .value if present
if (fieldName.endsWith(".value"))
fieldName = fieldName.slice(0, -6);
this._fieldInfos[fieldName] = {
index: i
};
}
}
return this;
}
/**
* Sets a custom check-function for the given field. This can be used to handle the value of the field differently, making more complex
* filters possible.
*
* @param {String} pFieldName column the function should be used for
* @param {Function} pCheckFn custom check function, it will be called with these arguments: (rowValue, filterValue, operator), and it should
* return true if the row meets the filter-condition and false if it doesn't
* @param {Object} [pThisArg] this-value for the check-function
* @return {JditoFilter} current object
*/
JditoFilter.prototype.addSpecialCheckFn = function (pFieldName, pCheckFn, pThisArg)
{
if (!this._fieldInfos[pFieldName])
this._fieldInfos[pFieldName] = {};
this._fieldInfos[pFieldName].checkFn = pCheckFn;
this._fieldInfos[pFieldName].thisArg = pThisArg || null;
return this;
}
/**
* Sets the fields that should be used for lookup filter
*
* @param {Array} pFields the fields
* @return {JditoFilter} current object
*/
JditoFilter.prototype.lookupFilterFields = function (pFields)
{
this._lookupFields = pFields;
var lookupFilterFn = function (pRecordValue, pFilterValue, pOperator, pRow)
{
if (pOperator == "CONTAINS")
{
var filterValues = pFilterValue.split(" ").filter(function (val) {return val.trim();});
return filterValues.every(function (filterValue)
{
return this._lookupFields.some(function (fieldName)
{
var fieldIndex = this._fieldInfos[fieldName].index;
return (new RegExp(filterValue, "i")).test(pRow[fieldIndex]);
}, this);
}, this);
}
return false;
}
this.addSpecialCheckFn("$$$LOOKUPFIELD$$$", lookupFilterFn, this);
return this;
}
/**
* Changes whether the condition should be case-insensitive for text
*
* @param {boolean} [pIgnoreCase=true] if it should be case-insensitive
* @return {JditoFilter} current object
*/
JditoFilter.prototype.ignoreCase = function (pIgnoreCase)
{
//"", 0 , false -> false, everything else is considered true
this._ignoreCase = pIgnoreCase != false;
return this;
}
/**
* tests the given row if it matches the filter
*
......@@ -58,12 +162,12 @@ function JditoFilter (pColumns, pFilter, pCustomCheckFns, pCheckFnThisArg)
*/
JditoFilter.prototype.checkRecord = function (pRow)
{
if (!this.filter || this.filter.childs.length === 0)
if (!this._filter || this._filter.childs.length === 0)
return true;
var regexFlags = JditoFilterUtils.isUserIgnoreCase() ? "i" : undefined;
return _testRecord.call(this, this.filter);
return _testRecord.call(this, this._filter);
/**
* recursive function to test the row against the condition
......@@ -72,9 +176,10 @@ JditoFilter.prototype.checkRecord = function (pRow)
{
if (pCondition.type == "row")
{
let value = pRow[this.columnMap[pCondition.name].index];
let testFn = this.columnMap[pCondition.name].checkFn || _testValue;
return testFn.call(this.checkFnThisArg, value, (pCondition.key || pCondition.value), pCondition.operator, pRow);
let columnInfo = this._fieldInfos[pCondition.name];
let value = "index" in columnInfo ? pRow[columnInfo.index] : null;
let testFn = columnInfo.checkFn || _testValue;
return testFn.call(columnInfo.thisArg, value, (pCondition.key || pCondition.value), pCondition.operator, pRow);
}
else if (pCondition.type == "group")
{
......@@ -125,6 +230,12 @@ JditoFilter.prototype.checkRecord = function (pRow)
}
}
/**
* Filters the given records by the criteria defined by the filter object.
*
* @param {Array} pRecords 2d-array containing the records
* @return {Array the filtered records
*/
JditoFilter.prototype.filterRecords = function (pRecords)
{
return pRecords.filter(this.checkRecord, this);
......@@ -178,7 +289,16 @@ JditoFilterUtils.filterRecords = function (pColumns, pRecords, pFilter, pCustomC
if (!pFilter)
return pRecords;
return new JditoFilter(pColumns, pFilter, pCustomCheckFns, pCheckFnThisArg).filterRecords(pRecords);
var filterObj = new JditoFilter(pFilter, pColumns);
if (pCustomCheckFns)
{
for (let fieldName in pCustomCheckFns)
{
filterObj.addSpecialCheckFn(fieldName, pCustomCheckFns[fieldName], pCheckFnThisArg);
}
}
return filterObj.filterRecords(pRecords);
}
/**
......@@ -263,7 +383,7 @@ function FilterSqlTranslator (pFilter, pTable)
/**
* Sets the filter of the object
*
* @param {Object} pFilter the filter object that should be used
* @param {Object} pFilter the filter object that should be used (e.g. vars.get("$local.filter"))
* @return {FilterSqlTranslator} current object
*/
FilterSqlTranslator.prototype.filter = function (pFilter)
......@@ -272,7 +392,7 @@ FilterSqlTranslator.prototype.filter = function (pFilter)
{
if (!Utils.isObject(pFilter))
throw new TypeError("FilterSqlTranslator: Wrong type for the filter, expected 'object' but got '" + (typeof pFilter) + "'");
this._filter = pFilter.filter || pFilter;
this._filter = "filter" in pFilter ? pFilter.filter : pFilter;
}
return this;
}
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment