UNPKG

devextreme

Version:

HTML5 JavaScript Component Suite for Responsive Web Development

1,255 lines (1,157 loc) • 131 kB
"use strict"; var $ = require("../../core/renderer"), Callbacks = require("../../core/utils/callbacks"), isWrapped = require("../../core/utils/variable_wrapper").isWrapped, dataCoreUtils = require("../../core/utils/data"), grep = require("../../core/utils/common").grep, typeUtils = require("../../core/utils/type"), iteratorUtils = require("../../core/utils/iterator"), getDefaultAlignment = require("../../core/utils/position").getDefaultAlignment, extend = require("../../core/utils/extend").extend, inArray = require("../../core/utils/array").inArray, config = require("../../core/config"), isDefined = typeUtils.isDefined, objectUtils = require("../../core/utils/object"), errors = require("../widget/ui.errors"), modules = require("./ui.grid_core.modules"), gridCoreUtils = require("./ui.grid_core.utils"), normalizeSortingInfo = gridCoreUtils.normalizeSortingInfo, equalSortParameters = gridCoreUtils.equalSortParameters, normalizeIndexes = require("../../core/utils/array").normalizeIndexes, inflector = require("../../core/utils/inflector"), dateSerialization = require("../../core/utils/date_serialization"), numberLocalization = require("../../localization/number"), dateLocalization = require("../../localization/date"), messageLocalization = require("../../localization/message"), deferredUtils = require("../../core/utils/deferred"), when = deferredUtils.when, Deferred = deferredUtils.Deferred, DataSourceModule = require("../../data/data_source/data_source"), normalizeDataSourceOptions = DataSourceModule.normalizeDataSourceOptions, filterUtils = require("../shared/filtering"); var USER_STATE_FIELD_NAMES_15_1 = ["filterValues", "filterType", "fixed", "fixedPosition"], USER_STATE_FIELD_NAMES = ["visibleIndex", "dataField", "name", "dataType", "width", "visible", "sortOrder", "lastSortOrder", "sortIndex", "groupIndex", "filterValue", "selectedFilterOperation", "added"].concat(USER_STATE_FIELD_NAMES_15_1), IGNORE_COLUMN_OPTION_NAMES = { visibleWidth: true, bestFitWidth: true, bufferedFilterValue: true }, COMMAND_EXPAND_CLASS = "dx-command-expand"; var regExp = /columns\[(\d+)\]\.?/gi; module.exports = { defaultOptions: function defaultOptions() { return { commonColumnSettings: { allowFiltering: true, allowHiding: true, allowSorting: true, allowEditing: true, encodeHtml: true, /** * @name GridBaseColumn.trueText * @publicName trueText * @type string * @default "true" */ trueText: messageLocalization.format("dxDataGrid-trueText"), /** * @name GridBaseColumn.falseText * @publicName falseText * @type string * @default "false" */ falseText: messageLocalization.format("dxDataGrid-falseText") }, /** * @name GridBaseOptions.allowColumnReordering * @publicName allowColumnReordering * @type boolean * @default false */ allowColumnReordering: false, /** * @name GridBaseOptions.allowColumnResizing * @publicName allowColumnResizing * @type boolean * @default false */ allowColumnResizing: false, /** * @name GridBaseOptions.columnResizingMode * @publicName columnResizingMode * @type Enums.ColumnResizingMode * @default "nextColumn" */ columnResizingMode: "nextColumn", /** * @name GridBaseOptions.columnMinWidth * @publicName columnMinWidth * @type number * @default undefined */ columnMinWidth: undefined, /** * @name GridBaseOptions.columnWidth * @publicName columnWidth * @type number * @default undefined */ columnWidth: undefined, adaptColumnWidthByRatio: true, /** * @name GridBaseOptions.columns * @publicName columns * @type Array<GridBaseColumn> * @fires GridBaseOptions.onOptionChanged * @default undefined */ /** * @name dxDataGridOptions.columns * @publicName columns * @type Array<dxDataGridColumn> * @default undefined */ /** * @name dxTreeListOptions.columns * @publicName columns * @type Array<dxTreeListColumn> * @default undefined */ /** * @name GridBaseColumn * @publicName GridBaseColumn * @type Object */ /** * @name dxDataGridColumn * @publicName dxDataGridColumn * @inherits GridBaseColumn * @type Object */ /** * @name dxTreeListColumn * @publicName dxTreeListColumn * @inherits GridBaseColumn * @type Object */ columns: undefined, /** * @name GridBaseColumn.visible * @publicName visible * @type boolean * @default true * @fires GridBase.onOptionChanged */ /** * @name GridBaseColumn.hidingPriority * @publicName hidingPriority * @type number * @default undefined */ /** * @name GridBaseColumn.fixed * @publicName fixed * @type boolean * @default false */ /** * @name dxDataGridColumn.columns * @publicName columns * @type Array<dxDataGridColumn> * @default undefined */ /** * @name dxTreeListColumn.columns * @publicName columns * @type Array<dxTreeListColumn> * @default undefined */ /** * @name GridBaseColumn.ownerBand * @publicName ownerBand * @type number * @default undefined */ /** * @name GridBaseColumn.isBand * @publicName isBand * @type boolean * @default undefined */ /** * @name GridBaseColumn.fixedPosition * @publicName fixedPosition * @type Enums.HorizontalEdge * @default undefined */ /** * @name GridBaseColumn.visibleIndex * @publicName visibleIndex * @type number * @default undefined * @fires GridBase.onOptionChanged */ /** * @name GridBaseColumn.showInColumnChooser * @publicName showInColumnChooser * @type boolean * @default true */ /** * @name GridBaseColumn.dataField * @publicName dataField * @type string * @default undefined */ /** * @name GridBaseColumn.dataType * @publicName dataType * @type Enums.GridColumnDataType * @default undefined */ /** * @name GridBaseColumn.validationRules * @publicName validationRules * @type Array<RequiredRule,NumericRule,RangeRule,StringLengthRule,CustomRule,CompareRule,PatternRule,EmailRule> */ /** * @name GridBaseColumn.calculateCellValue * @publicName calculateCellValue * @type function(rowData) * @type_function_param1 rowData:object * @type_function_return any */ /** * @name GridBaseColumn.setCellValue * @publicName setCellValue * @type function(newData, value, currentRowData) * @type_function_param1 newData:object * @type_function_param2 value:any * @type_function_param3 currentRowData:object */ /** * @name GridBaseColumn.calculateDisplayValue * @publicName calculateDisplayValue * @type string|function(rowData) * @type_function_param1 rowData:object * @type_function_return any */ /** * @name dxDataGridColumn.calculateGroupValue * @publicName calculateGroupValue * @type string|function(rowData) * @type_function_param1 rowData:object * @type_function_return any */ /** * @name GridBaseColumn.calculateSortValue * @publicName calculateSortValue * @type string|function(rowData) * @type_function_param1 rowData:object * @type_function_return any */ /** * @name GridBaseColumn.sortingMethod * @publicName sortingMethod * @type function(value1, value2) * @type_function_param1 value1:any * @type_function_param2 value2:any * @type_function_return number * @default undefined */ /** * @name dxDataGridColumn.showWhenGrouped * @publicName showWhenGrouped * @type boolean * @default false */ /** * @name GridBaseColumn.calculateFilterExpression * @publicName calculateFilterExpression * @type function(filterValue, selectedFilterOperation, target) * @type_function_param1 filterValue:any * @type_function_param2 selectedFilterOperation:string * @type_function_param3 target:string * @type_function_return Filter expression */ /** * @name GridBaseColumn.name * @publicName name * @type string * @default undefined */ /** * @name GridBaseColumn.caption * @publicName caption * @type string * @default undefined */ /** * @name GridBaseColumn.width * @publicName width * @type number|string * @default undefined */ /** * @name GridBaseColumn.minWidth * @publicName minWidth * @type number * @default undefined */ /** * @name GridBaseColumn.cssClass * @publicName cssClass * @type string * @default undefined */ /** * @name GridBaseColumn.sortOrder * @publicName sortOrder * @type Enums.SortOrder * @default undefined * @acceptValues undefined * @fires GridBase.onOptionChanged */ /** * @name GridBaseColumn.sortIndex * @publicName sortIndex * @type number * @default undefined * @fires GridBase.onOptionChanged */ /** * @name GridBaseColumn.showEditorAlways * @publicName showEditorAlways * @type boolean * @default false */ /** * @name GridBaseColumn.alignment * @publicName alignment * @type Enums.HorizontalAlignment * @default undefined * @acceptValues undefined */ /** * @name GridBaseColumn.format * @publicName format * @type format * @default "" */ /** * @name GridBaseColumn.customizeText * @publicName customizeText * @type function(cellInfo) * @type_function_param1 cellInfo:object * @type_function_param1_field1 value:string|number|date * @type_function_param1_field2 valueText:string * @type_function_param1_field3 target:string * @type_function_param1_field4 groupInterval:string|number * @type_function_return string */ /** * @name dxDataGridColumn.precision * @publicName precision * @type number * @default undefined * @deprecated */ /** * @name GridBaseColumn.filterOperations * @publicName filterOperations * @type Array<string> * @acceptValues "=" | "<>" | "<" | "<=" | ">" | ">=" | "notcontains" | "contains" | "startswith" | "endswith" | "between" * @default undefined */ /** * @name GridBaseColumn.selectedFilterOperation * @publicName selectedFilterOperation * @type Enums.FilterOperations * @default undefined * @fires GridBase.onOptionChanged */ /** * @name GridBaseColumn.filterValue * @publicName filterValue * @type any * @default undefined * @fires GridBase.onOptionChanged */ /** * @name GridBaseColumn.filterValues * @publicName filterValues * @type Array<any> * @default undefined * @fires GridBase.onOptionChanged */ /** * @name GridBaseColumn.filterType * @publicName filterType * @type Enums.FilterType * @default "include" */ /** * @name GridBaseColumn.cellTemplate * @publicName cellTemplate * @type template|function * @type_function_param1 cellElement:dxElement * @type_function_param2 cellInfo:object */ /** * @name GridBaseColumn.headerCellTemplate * @publicName headerCellTemplate * @type template|function * @type_function_param1 columnHeader:dxElement * @type_function_param2 headerInfo:object */ /** * @name GridBaseColumn.editCellTemplate * @publicName editCellTemplate * @type template|function * @type_function_param1 cellElement:dxElement * @type_function_param2 cellInfo:object */ /** * @name dxDataGridColumn.groupCellTemplate * @publicName groupCellTemplate * @type template|function * @type_function_param1 cellElement:dxElement * @type_function_param2 cellInfo:object */ /** * @name dxDataGridColumn.groupIndex * @publicName groupIndex * @type number * @default undefined * @fires dxDataGrid.onOptionChanged */ /** * @name dxDataGridColumn.grouped * @publicName grouped * @type boolean * @hidden * @default false */ /** * @name GridBaseColumn.allowHiding * @publicName allowHiding * @type boolean * @default true */ /** * @name GridBaseColumn.allowReordering * @publicName allowReordering * @type boolean * @default true */ /** * @name GridBaseColumn.allowResizing * @publicName allowResizing * @type boolean * @default true */ /** * @name GridBaseColumn.allowFiltering * @publicName allowFiltering * @type boolean * @default true */ /** * @name GridBaseColumn.allowHeaderFiltering * @publicName allowHeaderFiltering * @type boolean * @default true */ /** * @name GridBaseColumn.allowSearch * @publicName allowSearch * @type boolean * @default true */ /** * @name GridBaseColumn.allowEditing * @publicName allowEditing * @type boolean * @default true */ /** * @name dxDataGridColumn.allowGrouping * @publicName allowGrouping * @type boolean * @default true */ /** * @name GridBaseColumn.allowFixing * @publicName allowFixing * @type boolean * @default true */ /** * @name dxDataGridColumn.autoExpandGroup * @publicName autoExpandGroup * @type boolean * @default true */ /** * @name GridBaseColumn.allowSorting * @publicName allowSorting * @type boolean * @default true */ /** * @name GridBaseColumn.encodeHtml * @publicName encodeHtml * @type boolean * @default true */ /** * @name dxDataGridColumn.resized * @publicName resized * @type function * @hidden * @default undefined */ /** * @name GridBaseColumn.lookup * @publicName lookup * @type object * @default undefined */ /** * @name GridBaseColumn.lookup.dataSource * @publicName dataSource * @type Array<any>|DataSourceOptions|function(options) * @type_function_param1 options:object * @type_function_param1_field1 data:object * @type_function_param1_field2 key:any * @type_function_return Array<any>|DataSourceOptions * @default undefined */ /** * @name GridBaseColumn.lookup.valueExpr * @publicName valueExpr * @type string * @default undefined */ /** * @name GridBaseColumn.lookup.displayExpr * @publicName displayExpr * @type string|function(data) * @type_function_param1 data:object * @default undefined */ /** * @name GridBaseColumn.lookup.allowClearing * @publicName allowClearing * @type boolean * @default false */ /** * @name dxDataGridOptions.regenerateColumnsByVisibleItems * @publicName regenerateColumnsByVisibleItems * @type boolean * @hidden * @default false */ /** * @name GridBaseColumn.headerFilter * @publicName headerFilter * @type object * @default undefined */ /** * @name GridBaseColumn.headerFilter.dataSource * @publicName dataSource * @type Array<any>|function(options)|DataSourceOptions * @type_function_param1 options:object * @type_function_param1_field1 component:object * @type_function_param1_field2 dataSource:DataSourceOptions * @default undefined */ /** * @name GridBaseColumn.headerFilter.groupInterval * @publicName groupInterval * @type Enums.HeaderFilterGroupInterval|number * @default undefined */ /** * @name GridBaseColumn.headerFilter.allowSearch * @publicName allowSearch * @type boolean * @default false */ /** * @name GridBaseColumn.headerFilter.width * @publicName width * @type number * @default undefined */ /** * @name GridBaseColumn.headerFilter.height * @publicName height * @type number * @default undefined */ /** * @name GridBaseColumn.editorOptions * @publicName editorOptions * @type object */ /** * @name GridBaseColumn.formItem * @publicName formItem * @type dxFormSimpleItem */ regenerateColumnsByVisibleItems: false, /** * @name dxDataGridOptions.customizeColumns * @publicName customizeColumns * @type function(columns) * @type_function_param1 columns:Array<dxDataGridColumn> */ /** * @name dxTreeListOptions.customizeColumns * @publicName customizeColumns * @type function(columns) * @type_function_param1 columns:Array<dxTreeListColumn> */ customizeColumns: null, /** * @name GridBaseOptions.dateSerializationFormat * @publicName dateSerializationFormat * @type string */ dateSerializationFormat: undefined }; }, controllers: { columns: modules.Controller.inherit(function () { var DEFAULT_COLUMN_OPTIONS = { visible: true, showInColumnChooser: true }, DATATYPE_OPERATIONS = { "number": ["=", "<>", "<", ">", "<=", ">=", "between"], "string": ["contains", "notcontains", "startswith", "endswith", "=", "<>"], "date": ["=", "<>", "<", ">", "<=", ">=", "between"], "datetime": ["=", "<>", "<", ">", "<=", ">=", "between"] }, COLUMN_INDEX_OPTIONS = { visibleIndex: true, groupIndex: true, grouped: true, sortIndex: true, sortOrder: true }, GROUP_LOCATION = "group", COLUMN_CHOOSER_LOCATION = "columnChooser"; var createColumn = function createColumn(that, columnOptions, userStateColumnOptions, bandColumn) { var commonColumnOptions = {}, calculatedColumnOptions, isDefaultCommandColumn; if (columnOptions) { if (typeUtils.isString(columnOptions)) { columnOptions = { dataField: columnOptions }; } if (columnOptions.command) { isDefaultCommandColumn = that._commandColumns.some(function (column) { return column.command === columnOptions.command; }); if (!isDefaultCommandColumn) { commonColumnOptions.visible = true; } return extend(true, commonColumnOptions, columnOptions); } else { commonColumnOptions = that.getCommonSettings(); if (userStateColumnOptions && userStateColumnOptions.name && userStateColumnOptions.dataField) { columnOptions = extend({}, columnOptions, { dataField: userStateColumnOptions.dataField }); } calculatedColumnOptions = that._createCalculatedColumnOptions(columnOptions, bandColumn); return extend(true, {}, DEFAULT_COLUMN_OPTIONS, commonColumnOptions, calculatedColumnOptions, columnOptions, { selector: null }); } } }; var createColumnsFromOptions = function createColumnsFromOptions(that, columnsOptions, bandColumn) { var result = []; if (columnsOptions) { iteratorUtils.each(columnsOptions, function (index, columnOptions) { var userStateColumnOptions = that._columnsUserState && checkUserStateColumn(columnOptions, that._columnsUserState[index]) && that._columnsUserState[index], column = createColumn(that, columnOptions, userStateColumnOptions, bandColumn); if (column) { if (bandColumn) { column.ownerBand = bandColumn; } result.push(column); if (column.isBand) { result = result.concat(createColumnsFromOptions(that, column.columns, column)); delete column.columns; } } }); } return result; }; var getParentBandColumns = function getParentBandColumns(columnIndex, columnParentByIndex) { var result = [], parent = columnParentByIndex[columnIndex]; while (parent) { result.unshift(parent); columnIndex = parent.index; parent = columnParentByIndex[columnIndex]; } return result; }; var _getChildrenByBandColumn = function _getChildrenByBandColumn(columnIndex, columnChildrenByIndex, recursive) { var column, result = [], children = columnChildrenByIndex[columnIndex]; if (children) { for (var i = 0; i < children.length; i++) { column = children[i]; if (!isDefined(column.groupIndex) || column.showWhenGrouped) { result.push(column); if (recursive && column.isBand) { result = result.concat(_getChildrenByBandColumn(column.index, columnChildrenByIndex, recursive)); } } } } return result; }; var getColumnByIndexes = function getColumnByIndexes(that, columnIndexes) { var result, callbackFilter = function callbackFilter(column) { var ownerBand = result ? result.index : undefined; return column.ownerBand === ownerBand; }, columns = that._columns.filter(callbackFilter); for (var i = 0; i < columnIndexes.length; i++) { result = columns[columnIndexes[i]]; if (result) { columns = that._columns.filter(callbackFilter); } } return result; }; var getColumnFullPath = function getColumnFullPath(that, column) { var result = [], bandColumnsCache = that.getBandColumnsCache(), callbackFilter = function callbackFilter(item) { return item.ownerBand === column.ownerBand; }, columns = that._columns.filter(callbackFilter); while (columns.length && columns.indexOf(column) !== -1) { result.unshift("columns[" + columns.indexOf(column) + "]"); column = bandColumnsCache.columnParentByIndex[column.index]; columns = column ? that._columns.filter(callbackFilter) : []; } return result.join("."); }; var calculateColspan = function calculateColspan(that, columnID) { var colspan = 0, columns = that.getChildrenByBandColumn(columnID, true); iteratorUtils.each(columns, function (_, column) { if (column.isBand) { column.colspan = column.colspan || calculateColspan(that, column.index); colspan += column.colspan; } else { colspan += 1; } }); return colspan; }; var processBandColumns = function processBandColumns(that, columns, bandColumnsCache) { var i, column, rowspan, rowCount = that.getRowCount(); for (i = 0; i < columns.length; i++) { column = columns[i]; if (column.visible || column.command) { if (column.isBand) { column.colspan = column.colspan || calculateColspan(that, column.index); } if (!column.isBand || !column.colspan) { rowspan = rowCount - (!column.command && !isDefined(column.groupIndex) ? getParentBandColumns(column.index, bandColumnsCache.columnParentByIndex).length : 0); if (rowspan > 1) { column.rowspan = rowspan; } } } } }; var getValueDataType = function getValueDataType(value) { var dataType = typeUtils.type(value); if (dataType !== "string" && dataType !== "boolean" && dataType !== "number" && dataType !== "date" && dataType !== "object") { dataType = undefined; } return dataType; }; var getSerializationFormat = function getSerializationFormat(dataType, value) { switch (dataType) { case "date": case "datetime": return dateSerialization.getDateSerializationFormat(value); case "number": if (typeUtils.isString(value)) { return "string"; } if (typeUtils.isNumeric(value)) { return null; } } }; var updateSerializers = function updateSerializers(options, dataType) { if (!options.deserializeValue) { if (gridCoreUtils.isDateType(dataType)) { options.deserializeValue = function (value) { return dateSerialization.deserializeDate(value); }; options.serializeValue = function (value) { return typeUtils.isString(value) ? value : dateSerialization.serializeDate(value, this.serializationFormat); }; } if (dataType === "number") { options.deserializeValue = function (value) { var parsedValue = parseFloat(value); return isNaN(parsedValue) ? value : parsedValue; }; options.serializeValue = function (value, target) { if (target === "filter") return value; return isDefined(value) && this.serializationFormat === "string" ? value.toString() : value; }; } } }; var getAlignmentByDataType = function getAlignmentByDataType(dataType, isRTL) { switch (dataType) { case "number": return "right"; case "boolean": return "center"; default: return getDefaultAlignment(isRTL); } }; var getCustomizeTextByDataType = function getCustomizeTextByDataType(dataType) { if (dataType === "boolean") { return function (e) { if (e.value === true) { return this.trueText || "true"; } else if (e.value === false) { return this.falseText || "false"; } else { return e.valueText || ""; } }; } }; var createColumnsFromDataSource = function createColumnsFromDataSource(that, dataSource) { var firstItems = that._getFirstItems(dataSource), fieldName, processedFields = {}, i, result = []; for (i = 0; i < firstItems.length; i++) { if (firstItems[i]) { for (fieldName in firstItems[i]) { if (!typeUtils.isFunction(firstItems[i][fieldName]) || isWrapped(firstItems[i][fieldName])) { processedFields[fieldName] = true; } } } } for (fieldName in processedFields) { if (fieldName.indexOf("__") !== 0) { var column = createColumn(that, fieldName); result.push(column); } } return result; }; var updateColumnIndexes = function updateColumnIndexes(that) { iteratorUtils.each(that._columns, function (index, column) { column.index = index; }); iteratorUtils.each(that._columns, function (index, column) { if (typeUtils.isObject(column.ownerBand)) { column.ownerBand = column.ownerBand.index; } }); iteratorUtils.each(that._commandColumns, function (index, column) { column.index = -(index + 1); }); }; var updateColumnGroupIndexes = function updateColumnGroupIndexes(that, currentColumn) { normalizeIndexes(that._columns, "groupIndex", currentColumn, function (column) { var grouped = column.grouped; delete column.grouped; return grouped; }); }; var updateColumnSortIndexes = function updateColumnSortIndexes(that, currentColumn) { iteratorUtils.each(that._columns, function (index, column) { if (isDefined(column.sortIndex) && !isSortOrderValid(column.sortOrder)) { delete column.sortIndex; } }); normalizeIndexes(that._columns, "sortIndex", currentColumn, function (column) { return !isDefined(column.groupIndex) && isSortOrderValid(column.sortOrder); }); }; var updateColumnVisibleIndexes = function updateColumnVisibleIndexes(that, currentColumn) { var i, key, column, bandColumnIndex, parentBandColumns, bandColumns = {}, result = [], bandColumnsCache = that.getBandColumnsCache(), columns = that._columns.filter(function (column) { return !column.command; }); for (i = 0; i < columns.length; i++) { column = columns[i]; parentBandColumns = getParentBandColumns(i, bandColumnsCache.columnParentByIndex); if (parentBandColumns.length) { bandColumnIndex = parentBandColumns[parentBandColumns.length - 1].index; bandColumns[bandColumnIndex] = bandColumns[bandColumnIndex] || []; bandColumns[bandColumnIndex].push(column); } else { result.push(column); } } for (key in bandColumns) { normalizeIndexes(bandColumns[key], "visibleIndex", currentColumn); } normalizeIndexes(result, "visibleIndex", currentColumn); }; var getColumnIndexByVisibleIndex = function getColumnIndexByVisibleIndex(that, visibleIndex, location) { var rowIndex = typeUtils.isObject(visibleIndex) ? visibleIndex.rowIndex : null, columns = location === GROUP_LOCATION ? that.getGroupColumns() : location === COLUMN_CHOOSER_LOCATION ? that.getChooserColumns() : that.getVisibleColumns(rowIndex), column; visibleIndex = typeUtils.isObject(visibleIndex) ? visibleIndex.columnIndex : visibleIndex; column = columns[visibleIndex]; return column && isDefined(column.index) ? column.index : -1; }; var moveColumnToGroup = function moveColumnToGroup(that, column, groupIndex) { var groupColumns = that.getGroupColumns(), i; if (groupIndex >= 0) { for (i = 0; i < groupColumns.length; i++) { if (groupColumns[i].groupIndex >= groupIndex) { groupColumns[i].groupIndex++; } } } else { groupIndex = 0; for (i = 0; i < groupColumns.length; i++) { groupIndex = Math.max(groupIndex, groupColumns[i].groupIndex + 1); } } return groupIndex; }; var checkUserStateColumn = function checkUserStateColumn(column, userStateColumn) { return column && userStateColumn && userStateColumn.name === column.name && (userStateColumn.dataField === column.dataField || column.name); }; var applyUserState = function applyUserState(that) { var columnsUserState = that._columnsUserState, ignoreColumnOptionNames = that._ignoreColumnOptionNames || [], columns = that._columns, columnCountById = {}, resultColumns = [], allColumnsHaveState = true, userStateColumnIndexes = [], column, columnUserState, userStateColumnIndex, i; function applyFieldsState(column, userStateColumn) { var fieldName; if (!userStateColumn) return; for (var index = 0; index < USER_STATE_FIELD_NAMES.length; index++) { fieldName = USER_STATE_FIELD_NAMES[index]; if (inArray(fieldName, ignoreColumnOptionNames) >= 0) continue; if (fieldName === "dataType") { column[fieldName] = column[fieldName] || userStateColumn[fieldName]; } else if (inArray(fieldName, USER_STATE_FIELD_NAMES_15_1) >= 0) { if (fieldName in userStateColumn) { column[fieldName] = userStateColumn[fieldName]; } } else { column[fieldName] = userStateColumn[fieldName]; } } } function findUserStateColumn(columnsUserState, column) { var id = column.name || column.dataField, count = columnCountById[id] || 0; for (var j = 0; j < columnsUserState.length; j++) { if (checkUserStateColumn(column, columnsUserState[j])) { if (count) { count--; } else { columnCountById[id] = columnCountById[id] || 0; columnCountById[id]++; return j; } } } return -1; } if (columnsUserState) { for (i = 0; i < columns.length; i++) { userStateColumnIndex = findUserStateColumn(columnsUserState, columns[i]); allColumnsHaveState = allColumnsHaveState && userStateColumnIndex >= 0; userStateColumnIndexes.push(userStateColumnIndex); } for (i = 0; i < columns.length; i++) { column = columns[i]; userStateColumnIndex = userStateColumnIndexes[i]; if (that._hasUserState || allColumnsHaveState) { applyFieldsState(column, columnsUserState[userStateColumnIndex]); } if (userStateColumnIndex >= 0 && isDefined(columnsUserState[userStateColumnIndex].initialIndex)) { resultColumns[userStateColumnIndex] = column; } else { resultColumns.push(column); } } for (i = 0; i < columnsUserState.length; i++) { columnUserState = columnsUserState[i]; if (columnUserState.added && findUserStateColumn(columns, columnUserState) < 0) { column = createColumn(that, columnUserState.added); applyFieldsState(column, columnUserState); resultColumns.push(column); if (columnUserState.added.columns) { resultColumns = createColumnsFromOptions(that, resultColumns); } } } assignColumns(that, resultColumns); if (that._dataSourceApplied && that._dataSource) { updateIndexes(that); that._dataSource.group(that.getGroupDataSourceParameters()); that._dataSource.sort(that.getSortDataSourceParameters()); that._dataSource.load(); } } }; var updateIndexes = function updateIndexes(that, column) { updateColumnIndexes(that); updateColumnGroupIndexes(that, column); updateColumnSortIndexes(that, column); updateColumnVisibleIndexes(that, column); }; var resetColumnsCache = function resetColumnsCache(that) { that.resetColumnsCache(); }; var assignColumns = function assignColumns(that, columns) { that._columns = columns; resetColumnsCache(that); that.updateColumnDataTypes(); }; var updateColumnChanges = function updateColumnChanges(that, changeType, optionName, columnIndex) { var columnChanges = that._columnChanges || { optionNames: { length: 0 }, changeTypes: { length: 0 }, columnIndex: columnIndex }; optionName = optionName || "all"; optionName = optionName.split(".")[0]; var changeTypes = columnChanges.changeTypes; if (changeType && !changeTypes[changeType]) { changeTypes[changeType] = true; changeTypes.length++; } var optionNames = columnChanges.optionNames; if (optionName && !optionNames[optionName]) { optionNames[optionName] = true; optionNames.length++; } if (columnIndex === undefined || columnIndex !== columnChanges.columnIndex) { delete columnChanges.columnIndex; } that._columnChanges = columnChanges; resetColumnsCache(that); }; var fireColumnsChanged = function fireColumnsChanged(that) { var onColumnsChanging = that.option("onColumnsChanging"), columnChanges = that._columnChanges; if (that.isInitialized() && !that._updateLockCount && columnChanges) { if (onColumnsChanging) { that._updateLockCount++; onColumnsChanging(extend({ component: that.component }, columnChanges)); that._updateLockCount--; } that._columnChanges = undefined; if (columnChanges.optionNames && (columnChanges.optionNames.dataField || columnChanges.optionNames.lookup)) { that.reinit(); } else { that.columnsChanged.fire(columnChanges); } } }; var updateSortOrderWhenGrouping = function updateSortOrderWhenGrouping(column, groupIndex, prevGroupIndex) { var columnWasGrouped = prevGroupIndex >= 0; if (groupIndex >= 0) { if (!columnWasGrouped) { column.lastSortOrder = column.sortOrder; } } else { column.sortOrder = column.lastSortOrder; } }; var getColumnByPath = function getColumnByPath(that, path, columns) { var column, columnIndexes = []; path.replace(regExp, function (_, columnIndex) { columnIndexes.push(parseInt(columnIndex)); return ""; }); if (columnIndexes.length) { if (columns) { column = columnIndexes.reduce(function (prevColumn, index) { return prevColumn ? prevColumn.columns[index] : columns[index]; }, 0); } else { column = getColumnByIndexes(that, columnIndexes); } } return column; }; var fireOptionChanged = function fireOptionChanged(that, options) { var value = options.value, optionName = options.optionName, prevValue = options.prevValue, fullOptionName = options.fullOptionName; if (!IGNORE_COLUMN_OPTION_NAMES[optionName]) { that._skipProcessingColumnsChange = true; that.component._notifyOptionChanged(fullOptionName + "." + optionName, value, prevValue); that._skipProcessingColumnsChange = false; } }; var columnOptionCore = function columnOptionCore(that, column, optionName, value, notFireEvent) { var optionGetter = dataCoreUtils.compileGetter(optionName), columnIndex = column.index, prevValue, optionSetter, columns, changeType, fullOptionName; if (arguments.length === 3) { return optionGetter(column, { functionsAsIs: true }); } prevValue = optionGetter(column, { functionsAsIs: true }); if (prevValue !== value) { if (optionName === "groupIndex") { changeType = "grouping"; updateSortOrderWhenGrouping(column, value, prevValue); } else if (optionName === "sortIndex" || optionName === "sortOrder") { changeType = "sorting"; } else { changeType = "columns"; } optionSetter = dataCoreUtils.compileSetter(optionName); optionSetter(column, value, { functionsAsIs: true }); fullOptionName = getColumnFullPath(that, column); fullOptionName && fireOptionChange