UNPKG

devextreme

Version:

HTML5 JavaScript Component Suite for Responsive Web Development

817 lines (701 loc) • 26.3 kB
"use strict"; var _deferred = require("../../core/utils/deferred"); var dataErrors = require("../../data/errors").errors, domAdapter = require("../../core/dom_adapter"), errors = require("../widget/ui.errors"), filterUtils = require("../shared/filtering"), formatHelper = require("../../format_helper"), extend = require("../../core/utils/extend").extend, inflector = require("../../core/utils/inflector"), between = require("./between"), messageLocalization = require("../../localization/message"), DataSource = require("../../data/data_source/data_source").DataSource, filterOperationsDictionary = require("./ui.filter_operations_dictionary"); var DEFAULT_DATA_TYPE = "string", EMPTY_MENU_ICON = "icon-none", AND_GROUP_OPERATION = "and", EQUAL_OPERATION = "=", NOT_EQUAL_OPERATION = "<>", DATATYPE_OPERATIONS = { "number": ["=", "<>", "<", ">", "<=", ">=", "isblank", "isnotblank"], "string": ["contains", "notcontains", "startswith", "endswith", "=", "<>", "isblank", "isnotblank"], "date": ["=", "<>", "<", ">", "<=", ">=", "isblank", "isnotblank"], "datetime": ["=", "<>", "<", ">", "<=", ">=", "isblank", "isnotblank"], "boolean": ["=", "<>", "isblank", "isnotblank"], "object": ["isblank", "isnotblank"] }, DEFAULT_FORMAT = { "date": "shortDate", "datetime": "shortDateShortTime" }, LOOKUP_OPERATIONS = ["=", "<>", "isblank", "isnotblank"], AVAILABLE_FIELD_PROPERTIES = ["caption", "customizeText", "dataField", "dataType", "editorTemplate", "falseText", "editorOptions", "filterOperations", "format", "lookup", "trueText", "calculateFilterExpression"]; function getFormattedValueText(field, value) { var fieldFormat = field.format || DEFAULT_FORMAT[field.dataType]; return formatHelper.format(value, fieldFormat); } function isNegationGroup(group) { return group && group.length > 1 && group[0] === "!" && !isCondition(group); } function getGroupCriteria(group) { return isNegationGroup(group) ? group[1] : group; } function setGroupCriteria(group, criteria) { if (isNegationGroup(group)) { group[1] = criteria; } else { group = criteria; } return group; } function convertGroupToNewStructure(group, value) { var isNegationValue = function isNegationValue(value) { return value.indexOf("!") !== -1; }, convertGroupToNegationGroup = function convertGroupToNegationGroup(group) { var criteria = group.slice(0); group.length = 0; group.push("!", criteria); }, convertNegationGroupToGroup = function convertNegationGroupToGroup(group) { var criteria = getGroupCriteria(group); group.length = 0; [].push.apply(group, criteria); }; if (isNegationValue(value)) { if (!isNegationGroup(group)) { convertGroupToNegationGroup(group); } } else if (isNegationGroup(group)) { convertNegationGroupToGroup(group); } } function setGroupValue(group, value) { convertGroupToNewStructure(group, value); var criteria = getGroupCriteria(group), i, getNormalizedGroupValue = function getNormalizedGroupValue(value) { return value.indexOf("!") === -1 ? value : value.substring(1); }, changeCriteriaValue = function changeCriteriaValue(criteria, value) { for (i = 0; i < criteria.length; i++) { if (!Array.isArray(criteria[i])) { criteria[i] = value; } } }; value = getNormalizedGroupValue(value); changeCriteriaValue(criteria, value); return group; } function getGroupMenuItem(group, availableGroups) { var groupValue = getGroupValue(group); return availableGroups.filter(function (item) { return item.value === groupValue; })[0]; } function getCriteriaOperation(criteria) { if (isCondition(criteria)) { return AND_GROUP_OPERATION; } var value = ""; for (var i = 0; i < criteria.length; i++) { var item = criteria[i]; if (!Array.isArray(item)) { if (value && value !== item) { throw new dataErrors.Error("E4019"); } value = item; } } return value; } function getGroupValue(group) { var criteria = getGroupCriteria(group), value = getCriteriaOperation(criteria); if (!value) { value = AND_GROUP_OPERATION; } if (criteria !== group) { value = "!" + value; } return value; } function getFilterOperations(field) { var result = field.filterOperations || field.lookup && LOOKUP_OPERATIONS || DATATYPE_OPERATIONS[field.dataType || DEFAULT_DATA_TYPE]; return extend([], result); } function getCaptionByOperation(operation, filterOperationDescriptions) { var operationName = filterOperationsDictionary.getNameByFilterOperation(operation); return filterOperationDescriptions && filterOperationDescriptions[operationName] ? filterOperationDescriptions[operationName] : operationName; } function getOperationFromAvailable(operation, availableOperations) { for (var i = 0; i < availableOperations.length; i++) { if (availableOperations[i].value === operation) { return availableOperations[i]; } } throw new errors.Error("E1048", operation); } function getCustomOperation(customOperations, name) { var filteredOperations = customOperations.filter(function (item) { return item.name === name; }); return filteredOperations.length ? filteredOperations[0] : null; } function getAvailableOperations(field, filterOperationDescriptions, customOperations) { var filterOperations = getFilterOperations(field); customOperations.forEach(function (customOperation) { if (!field.filterOperations && filterOperations.indexOf(customOperation.name) === -1) { var dataTypes = customOperation && customOperation.dataTypes; if (dataTypes && dataTypes.indexOf(field.dataType || DEFAULT_DATA_TYPE) >= 0) { filterOperations.push(customOperation.name); } } }); return filterOperations.map(function (operation) { var customOperation = getCustomOperation(customOperations, operation); if (customOperation) { return { icon: customOperation.icon || EMPTY_MENU_ICON, text: customOperation.caption || inflector.captionize(customOperation.name), value: customOperation.name, isCustom: true }; } else { return { icon: filterOperationsDictionary.getIconByFilterOperation(operation) || EMPTY_MENU_ICON, text: getCaptionByOperation(operation, filterOperationDescriptions), value: operation }; } }); } function getDefaultOperation(field) { return field.defaultFilterOperation || getFilterOperations(field)[0]; } function createCondition(field, customOperations) { var condition = [field.dataField, "", ""], filterOperation = getDefaultOperation(field); updateConditionByOperation(condition, filterOperation, customOperations); return condition; } function removeItem(group, item) { var criteria = getGroupCriteria(group), index = criteria.indexOf(item); criteria.splice(index, 1); if (criteria.length !== 1) { criteria.splice(index, 1); } return group; } function createEmptyGroup(value) { return value.indexOf("not") !== -1 ? ["!", [value.substring(3).toLowerCase()]] : [value]; } function isEmptyGroup(group) { var criteria = getGroupCriteria(group); if (isCondition(criteria)) { return false; } var hasConditions = criteria.some(function (item) { return isCondition(item); }); return !hasConditions; } function addItem(item, group) { var criteria = getGroupCriteria(group), groupValue = getGroupValue(criteria); criteria.length === 1 ? criteria.unshift(item) : criteria.push(item, groupValue); return group; } function getField(dataField, fields) { for (var i = 0; i < fields.length; i++) { if (fields[i].dataField.toLowerCase() === dataField.toLowerCase()) { return fields[i]; } } var extendedFields = getItems(fields, true).filter(function (item) { return item.dataField.toLowerCase() === dataField.toLowerCase(); }); if (extendedFields.length > 0) { return extendedFields[0]; } throw new errors.Error("E1047", dataField); } function isGroup(criteria) { if (!Array.isArray(criteria)) { return false; } return criteria.length < 2 || Array.isArray(criteria[0]) || Array.isArray(criteria[1]); } function isCondition(criteria) { if (!Array.isArray(criteria)) { return false; } return criteria.length > 1 && !Array.isArray(criteria[0]) && !Array.isArray(criteria[1]); } function convertToInnerGroup(group, customOperations) { var groupOperation = getCriteriaOperation(group).toLowerCase() || AND_GROUP_OPERATION, innerGroup = []; for (var i = 0; i < group.length; i++) { if (isGroup(group[i])) { innerGroup.push(convertToInnerStructure(group[i], customOperations)); innerGroup.push(groupOperation); } else if (isCondition(group[i])) { innerGroup.push(convertToInnerCondition(group[i], customOperations)); innerGroup.push(groupOperation); } } if (innerGroup.length === 0) { innerGroup.push(groupOperation); } return innerGroup; } function conditionHasCustomOperation(condition, customOperations) { var customOperation = getCustomOperation(customOperations, condition[1]); return customOperation && customOperation.name === condition[1]; } function convertToInnerCondition(condition, customOperations) { if (conditionHasCustomOperation(condition, customOperations)) { return condition; } if (condition.length < 3) { condition[2] = condition[1]; condition[1] = EQUAL_OPERATION; } return condition; } function convertToInnerStructure(value, customOperations) { if (!value) { return [AND_GROUP_OPERATION]; } value = extend(true, [], value); if (isCondition(value)) { return [convertToInnerCondition(value, customOperations), AND_GROUP_OPERATION]; } if (isNegationGroup(value)) { return ["!", isCondition(value[1]) ? [convertToInnerCondition(value[1], customOperations), AND_GROUP_OPERATION] : convertToInnerGroup(value[1], customOperations)]; } return convertToInnerGroup(value, customOperations); } function getNormalizedFields(fields) { return fields.reduce(function (result, field) { if (typeof field.dataField !== "undefined") { var normalizedField = {}; for (var key in field) { if (field[key] && AVAILABLE_FIELD_PROPERTIES.indexOf(key) > -1) { normalizedField[key] = field[key]; } } normalizedField.defaultCalculateFilterExpression = filterUtils.defaultCalculateFilterExpression; result.push(normalizedField); } return result; }, []); } function getConditionFilterExpression(condition, fields, customOperations, target) { var field = getField(condition[0], fields), filterExpression = convertToInnerCondition(condition, customOperations), customOperation = customOperations.length && getCustomOperation(customOperations, filterExpression[1]); if (customOperation && customOperation.calculateFilterExpression) { return customOperation.calculateFilterExpression.apply(customOperation, [filterExpression[2], field, target]); } else if (field.calculateFilterExpression) { return field.calculateFilterExpression.apply(field, [filterExpression[2], filterExpression[1], target]); } else { return field.defaultCalculateFilterExpression.apply(field, [filterExpression[2], filterExpression[1], target]); } } function getFilterExpression(value, fields, customOperations, target) { if (value === null) { return null; } var criteria = getGroupCriteria(value); if (isCondition(criteria)) { return getConditionFilterExpression(criteria, fields, customOperations, target) || null; } else { var result = [], filterExpression, groupValue = getGroupValue(criteria); for (var i = 0; i < criteria.length; i++) { if (isGroup(criteria[i])) { filterExpression = getFilterExpression(criteria[i], fields, customOperations); if (filterExpression) { i && result.push(groupValue); result.push(filterExpression); } } else if (isCondition(criteria[i])) { filterExpression = getConditionFilterExpression(criteria[i], fields, customOperations, target); if (filterExpression) { i && result.push(groupValue); result.push(filterExpression); } } } return result.length ? result : null; } } function getNormalizedFilter(group, fields) { var criteria = getGroupCriteria(group), i; if (criteria.length === 0) { return null; } var itemsForRemove = []; for (i = 0; i < criteria.length; i++) { if (isGroup(criteria[i])) { var normalizedGroupValue = getNormalizedFilter(criteria[i], fields); if (normalizedGroupValue) { criteria[i] = normalizedGroupValue; } else { itemsForRemove.push(criteria[i]); } } else if (isCondition(criteria[i])) { var field = getField(criteria[i][0], fields); if (!isValidCondition(criteria[i], field)) { itemsForRemove.push(criteria[i]); } } } for (i = 0; i < itemsForRemove.length; i++) { removeItem(criteria, itemsForRemove[i]); } if (criteria.length === 1) { return null; } criteria.splice(criteria.length - 1, 1); if (criteria.length === 1) { group = setGroupCriteria(group, criteria[0]); } if (group.length === 0) { return null; } return group; } function getCurrentLookupValueText(field, value, handler) { if (value === "") { handler(""); return; } var dataSource = new DataSource(field.lookup.dataSource); dataSource.filter(field.lookup.valueExpr, value); dataSource.load().done(function (result) { if (result && result.length > 0) { var data = result[0]; handler(field.lookup.displayExpr ? data[field.lookup.displayExpr] : data); } else { handler(""); } }).fail(function () { handler(""); }); } function getPrimitiveValueText(field, value, customOperation, target) { var valueText; if (value === true) { valueText = field.trueText || messageLocalization.format("dxDataGrid-trueText"); } else if (value === false) { valueText = field.falseText || messageLocalization.format("dxDataGrid-falseText"); } else { valueText = getFormattedValueText(field, value); } if (field.customizeText) { valueText = field.customizeText.call(field, { value: value, valueText: valueText, target: target }); } if (customOperation && customOperation.customizeText) { valueText = customOperation.customizeText.call(customOperation, { value: value, valueText: valueText, field: field, target: target }); } return valueText; } function getArrayValueText(field, value, customOperation, target) { return value.map(function (v) { return getPrimitiveValueText(field, v, customOperation, target); }); } function checkDefaultValue(value) { return value === "" || value === null; } function getCurrentValueText(field, value, customOperation) { var target = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : "filterBuilder"; if (checkDefaultValue(value)) { return ""; } if (Array.isArray(value)) { var result = new _deferred.Deferred(); _deferred.when.apply(this, getArrayValueText(field, value, customOperation, target)).done(function () { for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) { args[_key] = arguments[_key]; } var text = args.some(function (item) { return !checkDefaultValue(item); }) ? args.map(function (item) { return !checkDefaultValue(item) ? item : "?"; }) : ""; result.resolve(text); }); return result; } else { return getPrimitiveValueText(field, value, customOperation, target); } } function itemExists(plainItems, parentId) { return plainItems.some(function (item) { return item.dataField === parentId; }); } function pushItemAndCheckParent(originalItems, plainItems, item) { var dataField = item.dataField; if (hasParent(dataField)) { item.parentId = getParentIdFromItemDataField(dataField); if (!itemExists(plainItems, item.parentId) && !itemExists(originalItems, item.parentId)) { pushItemAndCheckParent(originalItems, plainItems, { dataType: "object", dataField: item.parentId, caption: generateCaptionByDataField(item.parentId, true), filterOperations: ["isblank", "isnotblank"] }); } } plainItems.push(item); } function generateCaptionByDataField(dataField, allowHierarchicalFields) { var caption = ""; if (allowHierarchicalFields) { dataField = dataField.substring(dataField.lastIndexOf(".") + 1); } else if (hasParent(dataField)) { dataField.split(".").forEach(function (field, index, arr) { caption += inflector.captionize(field); if (index !== arr.length - 1) { caption += "."; } }); return caption; } return inflector.captionize(dataField); } function getItems(fields, allowHierarchicalFields) { var items = []; for (var i = 0; i < fields.length; i++) { var item = extend(true, { caption: generateCaptionByDataField(fields[i].dataField, allowHierarchicalFields) }, fields[i]); if (allowHierarchicalFields) { pushItemAndCheckParent(fields, items, item); } else { items.push(item); } } return items; } function hasParent(dataField) { return dataField.lastIndexOf(".") !== -1; } function getParentIdFromItemDataField(dataField) { return dataField.substring(0, dataField.lastIndexOf(".")); } function getCaptionWithParents(item, plainItems) { if (hasParent(item.dataField)) { var parentId = getParentIdFromItemDataField(item.dataField); for (var i = 0; i < plainItems.length; i++) { if (plainItems[i].dataField === parentId) { return getCaptionWithParents(plainItems[i], plainItems) + "." + item.caption; } } } return item.caption; } function updateConditionByOperation(condition, operation, customOperations) { var customOperation = getCustomOperation(customOperations, operation); if (customOperation) { if (customOperation.hasValue === false) { condition[1] = operation; condition.length = 2; } else { condition[1] = operation; condition[2] = ""; } return condition; } if (operation === "isblank") { condition[1] = EQUAL_OPERATION; condition[2] = null; } else if (operation === "isnotblank") { condition[1] = NOT_EQUAL_OPERATION; condition[2] = null; } else { customOperation = getCustomOperation(customOperations, condition[1]); if (customOperation || condition.length === 2 || condition[2] === null) { condition[2] = ""; } condition[1] = operation; } return condition; } function getOperationValue(condition) { var caption; if (condition[2] === null) { if (condition[1] === EQUAL_OPERATION) { caption = "isblank"; } else { caption = "isnotblank"; } } else { caption = condition[1]; } return caption; } function isValidCondition(condition, field) { var isCustomOperation = condition.length > 2 && !filterOperationsDictionary.getNameByFilterOperation(condition[1]); if (field.dataType && field.dataType !== "string" || isCustomOperation) { return condition[2] !== ""; } return true; } function setFocusToBody() { var doc = domAdapter.getDocument(); if (doc && doc.activeElement && doc.activeElement.nodeName.toLowerCase() !== "body") { doc.activeElement.blur(); } } function getMergedOperations(customOperations, betweenCaption) { var result = extend(true, [], customOperations), betweenIndex = -1; result.some(function (customOperation, index) { if (customOperation.name === "between") { betweenIndex = index; return true; } }); if (betweenIndex !== -1) { result[betweenIndex] = extend(between.getConfig(betweenCaption), result[betweenIndex]); } else { result.unshift(between.getConfig(betweenCaption)); } return result; } function isMatchedCondition(filter, addedFilterDataField) { return filter[0] === addedFilterDataField; } function removeFieldConditionsFromFilter(filter, dataField) { if (!filter || filter.length === 0) { return null; } if (isCondition(filter)) { var hasMatchedCondition = isMatchedCondition(filter, dataField); return !hasMatchedCondition ? filter : null; } else { return syncConditionIntoGroup(filter, [dataField], false); } } function syncConditionIntoGroup(filter, addedFilter, canPush) { var result = []; filter.forEach(function (item) { if (isCondition(item)) { if (isMatchedCondition(item, addedFilter[0])) { if (canPush) { result.push(addedFilter); canPush = false; } else { result.splice(result.length - 1, 1); } } else { result.push(item); } } else { (result.length || isGroup(item)) && result.push(item); } }); if (result.length === 0) { return null; } if (canPush) { result.push(AND_GROUP_OPERATION); result.push(addedFilter); } return result.length === 1 ? result[0] : result; } function syncFilters(filter, addedFilter) { if (filter === null || filter.length === 0) { return addedFilter; } if (isCondition(filter)) { if (isMatchedCondition(filter, addedFilter[0])) { return addedFilter; } else { return [filter, AND_GROUP_OPERATION, addedFilter]; } } var groupValue = getGroupValue(filter); if (groupValue !== AND_GROUP_OPERATION) { return [addedFilter, "and", filter]; } return syncConditionIntoGroup(filter, addedFilter, true); } function getMatchedConditions(filter, dataField) { if (filter === null || filter.length === 0) return []; if (isCondition(filter)) { if (isMatchedCondition(filter, dataField)) { return [filter]; } else { return []; } } var groupValue = getGroupValue(filter); if (groupValue !== AND_GROUP_OPERATION) { return []; } var result = filter.filter(function (item) { return isCondition(item) && isMatchedCondition(item, dataField); }); return result; } function filterHasField(filter, dataField) { if (filter === null || filter.length === 0) return false; if (isCondition(filter)) { return filter[0] === dataField; } return filter.some(function (item) { return (isCondition(item) || isGroup(item)) && filterHasField(item, dataField); }); } exports.isValidCondition = isValidCondition; exports.isEmptyGroup = isEmptyGroup; exports.getOperationFromAvailable = getOperationFromAvailable; exports.updateConditionByOperation = updateConditionByOperation; exports.getCaptionWithParents = getCaptionWithParents; exports.getItems = getItems; exports.setGroupValue = setGroupValue; exports.getGroupMenuItem = getGroupMenuItem; exports.getGroupValue = getGroupValue; exports.getAvailableOperations = getAvailableOperations; exports.removeItem = removeItem; exports.createCondition = createCondition; exports.createEmptyGroup = createEmptyGroup; exports.addItem = addItem; exports.getField = getField; exports.isGroup = isGroup; exports.isCondition = isCondition; exports.getNormalizedFields = getNormalizedFields; exports.getNormalizedFilter = getNormalizedFilter; exports.getGroupCriteria = getGroupCriteria; exports.convertToInnerStructure = convertToInnerStructure; exports.getDefaultOperation = getDefaultOperation; exports.getCurrentValueText = getCurrentValueText; exports.getCurrentLookupValueText = getCurrentLookupValueText; exports.getFilterOperations = getFilterOperations; exports.getCaptionByOperation = getCaptionByOperation; exports.getOperationValue = getOperationValue; exports.setFocusToBody = setFocusToBody; exports.getFilterExpression = getFilterExpression; exports.getCustomOperation = getCustomOperation; exports.getMergedOperations = getMergedOperations; exports.syncFilters = syncFilters; exports.getMatchedConditions = getMatchedConditions; exports.filterHasField = filterHasField; exports.removeFieldConditionsFromFilter = removeFieldConditionsFromFilter;