Created
March 29, 2016 09:57
-
-
Save suvroc/981f45ccf152db3287fa to your computer and use it in GitHub Desktop.
Functionality to store grid filtering in query string
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(function () { | |
'use strict'; | |
angular.module('app.kendoState') | |
.service('kendoStateStore', function ($location, _) { | |
this.addFilterStoring = addFilterStoring; | |
this.rememberLocationParametersIn = rememberLocationParametersIn; | |
function rememberLocationParametersIn(callback) { | |
var locationParams = getLocationParameters(); | |
callback(); | |
setLocationParameters(locationParams); | |
} | |
function addFilterStoring(configuration, customFiltersBuilder) { | |
// filtering | |
var locationParams = filtersFromQueryString(); | |
configuration.dataSource.filter = megreConfigurations(configuration.dataSource.filter, locationParams ? locationParams.filters : []); | |
// sorting | |
var sortParams = sortFromQueryString(); | |
configuration.dataSource.sort = megreConfigurations(configuration.dataSource.sort, sortParams || []); | |
// dataSource.transport.read | |
var oldReadFunction = configuration.dataSource.transport.read; | |
configuration.dataSource.transport.read = function (optionsData) { | |
var data = oldReadFunction.call(this, optionsData); | |
setTimeout(function () { applyFilterInQueryString(data, customFiltersBuilder()); }, 500); | |
} | |
return configuration; | |
} | |
function megreConfigurations(parameters, queryParameter) { | |
var resultFilter = []; | |
for (var i = 0; i < parameters.length; i++) { | |
var userFilter = parameters[i]; | |
var matchedItems = queryParameter.filter(function (singleFilter) { return singleFilter.field === userFilter.field }); | |
if (matchedItems.length === 0) { | |
resultFilter.push(userFilter); | |
} | |
} | |
resultFilter = resultFilter.concat(queryParameter); | |
return resultFilter; | |
} | |
function setLocationParameters(params) { | |
$location.search(params); | |
} | |
function getLocationParameters() { | |
return $location.search(); | |
} | |
function filtersFromQueryString() { | |
if (!angular.equals($location.search(), {})) { | |
return parseFilterString($location.search().filter); | |
} | |
return null; | |
} | |
function sortFromQueryString() { | |
if (!angular.equals($location.search(), {})) { | |
return parseSortString($location.search().sort); | |
} | |
return null; | |
} | |
function applyFilterInQueryString(stringObject, additionalProps) { | |
var data = { | |
filter: stringObject.filter, | |
sort: stringObject.sort | |
}; | |
angular.extend(data, additionalProps); | |
$location.search(data); | |
} | |
function parseFilterString(filterString) { | |
// Remove all of the ' characters from the string. | |
filterString = filterString.replace(/[']/g, ''); | |
// Split the string into an array of strings, using the ~ as a delimiter. | |
var ss = filterString.split("~"); // ss stands for "split string". I'm clever. | |
var F = []; // Used to store all of the parsed filters. | |
var fIndex = -1; // Used to track filter index. | |
var cIndex = 0; // Used to track filter index within a composite filter object. | |
var isComposite = false; // Used to indicate if a composite filter is currently being parsed. | |
for (var i = 0; i < ss.length; i++) { | |
if (i % 4 == 0) { // Field. | |
if (ss[i].indexOf('(') > -1) { // If we're starting a composite object, create a composite object and add it to the parsed filters. | |
F.push({ | |
filters: [], | |
logic: "" | |
}); | |
fIndex++; // We added an object to the array, so increment the counter. | |
//F[fIndex] | |
F[fIndex].filters.push({ | |
field: ss[i].replace('(', ''), | |
operator: "", | |
value: "" | |
}); | |
cIndex = 0; // We added the first filter to the composite object, so set the counter. | |
isComposite = true; | |
} | |
else if (isComposite) { // If we're parsing the second filter in a composite filter object, then add the field to the child filter. | |
F[fIndex].filters.push({ | |
field: ss[i], | |
operator: "", | |
value: "" | |
}); | |
cIndex++; // We added the second filter to the composite object, so increment the counter. | |
} | |
else { // Add the field as normal. | |
F.push({ | |
field: ss[i], | |
operator: "", | |
value: "" | |
}); | |
fIndex++; // We added an object to the array, so increment the counter. | |
} | |
} | |
if (i % 4 == 1) { // Operator. | |
if (isComposite) { | |
F[fIndex].filters[cIndex].operator = ss[i]; | |
} | |
else { | |
F[fIndex].operator = ss[i]; | |
} | |
} | |
if (i % 4 == 2) { // Value. | |
if (ss[i].indexOf(')') > -1) { | |
F[fIndex].filters[cIndex].value = ss[i].replace(')', ''); | |
isComposite = false; | |
} | |
else if (isComposite) { | |
F[fIndex].filters[cIndex].value = ss[i]; | |
} | |
else { | |
F[fIndex].value = ss[i]; | |
} | |
} | |
if (i % 4 == 3) { // Logic. | |
if (isComposite) { | |
F[fIndex].logic = ss[i]; // Add the logic to the composite filter object. | |
} | |
// If the filter is not composite, the logic will always be "and". So, we just don't do anything if that's the case. | |
} | |
} | |
return { | |
filters: F, | |
logic: "and" | |
}; | |
}; | |
function parseSortString(sortString) { | |
// Split the string into an array of strings, using the ~ as a delimiter. | |
var ss = sortString.split("~"); // ss stands for "split string". I'm clever. | |
var S = []; // Array containing sort objects. | |
for (var i = 0; i < ss.length; i++) { | |
var sort = ss[i].split('-'); // Split sort string into field and direction. | |
S.push({ | |
compare: undefined, // This field exists in the sort objects, but is always undefined (as far as I can tell). I added it anyways, to minimize potential future issues. | |
dir: sort[1], // Direction. | |
field: sort[0] // Field. | |
}); | |
} | |
return S; | |
}; | |
}); | |
})(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment