UNPKG

devextreme

Version:

HTML5 JavaScript Component Suite for Responsive Web Development

975 lines (967 loc) • 65.7 kB
/** * DevExtreme (ui/grid_core/ui.grid_core.validating.js) * Version: 20.1.7 * Build date: Tue Aug 25 2020 * * Copyright (c) 2012 - 2020 Developer Express Inc. ALL RIGHTS RESERVED * Read about DevExtreme licensing here: https://js.devexpress.com/Licensing/ */ "use strict"; var _renderer = require("../../core/renderer"); var _renderer2 = _interopRequireDefault(_renderer); var _events_engine = require("../../events/core/events_engine"); var _events_engine2 = _interopRequireDefault(_events_engine); var _uiGrid_core = require("./ui.grid_core.modules"); var _uiGrid_core2 = _interopRequireDefault(_uiGrid_core); var _uiGrid_core3 = require("./ui.grid_core.utils"); var _common = require("../../core/utils/common"); var _iterator = require("../../core/utils/iterator"); var _type = require("../../core/utils/type"); var _extend = require("../../core/utils/extend"); var _selectors = require("../widget/selectors"); var _message = require("../../localization/message"); var _message2 = _interopRequireDefault(_message); var _button = require("../button"); var _button2 = _interopRequireDefault(_button); var _pointer = require("../../events/pointer"); var _pointer2 = _interopRequireDefault(_pointer); var _validation_engine = require("../validation_engine"); var _validation_engine2 = _interopRequireDefault(_validation_engine); var _validator = require("../validator"); var _validator2 = _interopRequireDefault(_validator); var _tooltip = require("../tooltip"); var _tooltip2 = _interopRequireDefault(_tooltip); var _overlay = require("../overlay"); var _overlay2 = _interopRequireDefault(_overlay); var _themes = require("../themes"); var _themes2 = _interopRequireDefault(_themes); var _ui = require("../widget/ui.errors"); var _ui2 = _interopRequireDefault(_ui); var _deferred = require("../../core/utils/deferred"); var _load_indicator = require("../load_indicator"); var _load_indicator2 = _interopRequireDefault(_load_indicator); var _string = require("../../core/utils/string"); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj } } function _toConsumableArray(arr) { return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread() } function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.") } function _unsupportedIterableToArray(o, minLen) { if (!o) { return } if ("string" === typeof o) { return _arrayLikeToArray(o, minLen) } var n = Object.prototype.toString.call(o).slice(8, -1); if ("Object" === n && o.constructor) { n = o.constructor.name } if ("Map" === n || "Set" === n) { return Array.from(o) } if ("Arguments" === n || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) { return _arrayLikeToArray(o, minLen) } } function _iterableToArray(iter) { if ("undefined" !== typeof Symbol && Symbol.iterator in Object(iter)) { return Array.from(iter) } } function _arrayWithoutHoles(arr) { if (Array.isArray(arr)) { return _arrayLikeToArray(arr) } } function _arrayLikeToArray(arr, len) { if (null == len || len > arr.length) { len = arr.length } for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i] } return arr2 } var INVALIDATE_CLASS = "invalid"; var REVERT_TOOLTIP_CLASS = "revert-tooltip"; var ROWS_VIEW_CLASS = "rowsview"; var INVALID_MESSAGE_CLASS = "dx-invalid-message"; var WIDGET_INVALID_MESSAGE_CLASS = "invalid-message"; var INVALID_MESSAGE_ALWAYS_CLASS = "dx-invalid-message-always"; var REVERT_BUTTON_CLASS = "dx-revert-button"; var CELL_HIGHLIGHT_OUTLINE = "dx-highlight-outline"; var VALIDATOR_CLASS = "validator"; var PENDING_INDICATOR_CLASS = "dx-pending-indicator"; var VALIDATION_PENDING_CLASS = "dx-validation-pending"; var INSERT_INDEX = "__DX_INSERT_INDEX__"; var PADDING_BETWEEN_TOOLTIPS = 2; var EDIT_MODE_ROW = "row"; var EDIT_MODE_FORM = "form"; var EDIT_MODE_BATCH = "batch"; var EDIT_MODE_CELL = "cell"; var EDIT_MODE_POPUP = "popup"; var GROUP_CELL_CLASS = "dx-group-cell"; var FORM_BASED_MODES = [EDIT_MODE_POPUP, EDIT_MODE_FORM]; var COMMAND_TRANSPARENT = "transparent"; var VALIDATION_STATUS = { valid: "valid", invalid: "invalid", pending: "pending" }; var EDIT_DATA_INSERT_TYPE = "insert"; var VALIDATION_CANCELLED = "cancel"; var validationResultIsValid = function(result) { return (0, _type.isDefined)(result) && result !== VALIDATION_CANCELLED }; var cellValueShouldBeValidated = function(value, rowOptions) { return void 0 !== value || void 0 === value && rowOptions && !rowOptions.isNewRow }; var rowIsValidated = function(editData) { return !!editData && !!editData.validated }; var ValidatingController = _uiGrid_core2.default.Controller.inherit(function() { return { init: function() { this._editingController = this.getController("editing"); this.createAction("onRowValidating") }, _getBrokenRules: function(editData, validationResults) { var brokenRules; if (validationResults) { brokenRules = validationResults.brokenRules || validationResults.brokenRule && [validationResults.brokenRule] } else { brokenRules = editData.brokenRules || [] } return brokenRules }, _rowValidating: function(editData, validationResults) { var deferred = new _deferred.Deferred; var brokenRules = this._getBrokenRules(editData, validationResults); var isValid = validationResults ? validationResults.isValid : editData.isValid; var parameters = { brokenRules: brokenRules, isValid: isValid, key: editData.key, newData: editData.data, oldData: editData.oldData, promise: null, errorText: this.getHiddenValidatorsErrorText(brokenRules) }; this.executeAction("onRowValidating", parameters); (0, _deferred.when)(parameters.promise).always(function() { editData.isValid = parameters.isValid; editData.errorText = parameters.errorText; deferred.resolve(parameters) }); return deferred.promise() }, getHiddenValidatorsErrorText: function(brokenRules) { var brokenRulesMessages = []; (0, _iterator.each)(brokenRules, function(_, brokenRule) { var column = brokenRule.column; var isGroupExpandColumn = column && void 0 !== column.groupIndex && !column.showWhenGrouped; var isVisibleColumn = column && column.visible; if (!brokenRule.validator.$element().parent().length && (!isVisibleColumn || isGroupExpandColumn)) { brokenRulesMessages.push(brokenRule.message) } }); return brokenRulesMessages.join(", ") }, validate: function(isFull) { var _this = this; var isValid = true; var editingController = this._editingController; var deferred = new _deferred.Deferred; var completeList = []; var editMode = editingController.getEditMode(); isFull = isFull || editMode === EDIT_MODE_ROW; if (this._isValidationInProgress) { return deferred.resolve(false).promise() } this._isValidationInProgress = true; if (isFull) { editingController.addDeferred(deferred); (0, _iterator.each)(editingController._editData, function(index, editData) { if (editData.type && "remove" !== editData.type) { var validationResult = _this.validateGroup(editData); completeList.push(validationResult); validationResult.done(function(validationResult) { editData.validated = true; isValid = isValid && validationResult.isValid }) } }) } else { if (this._currentCellValidator) { var validationResult = this.validateGroup(this._currentCellValidator._findGroup()); completeList.push(validationResult); validationResult.done(function(validationResult) { isValid = validationResult.isValid }) } } _deferred.when.apply(void 0, completeList).done(function() { _this._isValidationInProgress = false; deferred.resolve(isValid) }); return deferred.promise() }, validateGroup: function validateGroup(editData) { var _this2 = this; var result = new _deferred.Deferred; var validateGroup = _validation_engine2.default.getGroupConfig(editData); var validationResult; if (validateGroup && validateGroup.validators.length) { this.resetRowValidationResults(editData); validationResult = _validation_engine2.default.validateGroup(editData) }(0, _deferred.when)(validationResult && validationResult.complete || validationResult).done(function(validationResult) { (0, _deferred.when)(_this2._rowValidating(editData, validationResult)).done(result.resolve) }); return result.promise() }, isRowDataModified: function(editData) { return !(0, _type.isEmptyObject)(editData.data) }, updateEditData: function(editData) { var editMode = this._editingController.getEditMode(); if (FORM_BASED_MODES.indexOf(editMode) === -1) { if (editData.type === EDIT_DATA_INSERT_TYPE && !this.isRowDataModified(editData)) { editData.isValid = true; return } this.setDisableApplyValidationResults(true); if (_validation_engine2.default.getGroupConfig(editData)) { var validationResult = _validation_engine2.default.validateGroup(editData); (0, _deferred.when)(validationResult.complete || validationResult).done(function(validationResult) { editData.isValid = validationResult.isValid; editData.brokenRules = validationResult.brokenRules }) } else { if (!editData.brokenRules || !editData.brokenRules.length) { editData.isValid = true } } this.setDisableApplyValidationResults(false) } else { editData.isValid = true } }, setValidator: function(validator) { this._currentCellValidator = validator }, renderCellPendingIndicator: function($container) { var $indicator = $container.find("." + PENDING_INDICATOR_CLASS); if (!$indicator.length) { var $indicatorContainer = $container.find("." + CELL_HIGHLIGHT_OUTLINE); if (!$indicatorContainer.length) { $indicatorContainer = $container } $indicator = (0, _renderer2.default)("<div>").appendTo($indicatorContainer).addClass(PENDING_INDICATOR_CLASS); this._createComponent($indicator, _load_indicator2.default); $container.addClass(VALIDATION_PENDING_CLASS) } }, disposeCellPendingIndicator: function($container) { var $indicator = $container.find("." + PENDING_INDICATOR_CLASS); if ($indicator.length) { var indicator = _load_indicator2.default.getInstance($indicator); if (indicator) { indicator.dispose(); indicator.$element().remove() } $container.removeClass(VALIDATION_PENDING_CLASS) } }, validationStatusChanged: function(result) { var validator = result.validator; var editData = validator.option("validationGroup"); var column = validator.option("dataGetter")().column; this.updateCellValidationResult({ rowKey: editData.key, columnIndex: column.index, validationResult: result }) }, validatorInitialized: function(arg) { arg.component.on("validating", this.validationStatusChanged.bind(this)); arg.component.on("validated", this.validationStatusChanged.bind(this)) }, validatorDisposing: function(arg) { var validator = arg.component; var editData = validator.option("validationGroup"); var column = validator.option("dataGetter")().column; var result = this.getCellValidationResult({ rowKey: editData.key, columnIndex: column.index }); if (validationResultIsValid(result) && result.status === VALIDATION_STATUS.pending) { this.cancelCellValidationResult({ editData: editData, columnIndex: column.index }) } }, applyValidationResult: function($container, result) { var validator = result.validator; var editData = validator.option("validationGroup"); var column = validator.option("dataGetter")().column; result.brokenRules && result.brokenRules.forEach(function(rule) { rule.columnIndex = column.index; rule.column = column }); if ($container) { var validationResult = this.getCellValidationResult({ rowKey: editData.key, columnIndex: column.index }); var requestIsDisabled = validationResultIsValid(validationResult) && validationResult.disabledPendingId === result.id; if (this._disableApplyValidationResults || requestIsDisabled) { return } if (result.status === VALIDATION_STATUS.invalid) { var $focus = $container.find(":focus"); this._editingController.showHighlighting($container, true); if (!(0, _selectors.focused)($focus)) { _events_engine2.default.trigger($focus, "focus"); _events_engine2.default.trigger($focus, _pointer2.default.down) } } var editor = !column.editCellTemplate && this.getController("editorFactory").getEditorInstance($container); if (result.status === VALIDATION_STATUS.pending) { this._editingController.showHighlighting($container, true); if (editor) { editor.option("validationStatus", VALIDATION_STATUS.pending) } else { this.renderCellPendingIndicator($container) } } else { if (editor) { editor.option("validationStatus", VALIDATION_STATUS.valid) } else { this.disposeCellPendingIndicator($container) } } $container.toggleClass(this.addWidgetPrefix(INVALIDATE_CLASS), result.status === VALIDATION_STATUS.invalid) } }, createValidator: function(parameters, $container) { var _this3 = this; var editData; var editIndex; var editingController = this._editingController; var column = parameters.column; var getValue = function() { var value = column.calculateCellValue(editData.data || {}); return void 0 !== value ? value : parameters.value }; var showEditorAlways = column.showEditorAlways; if ((0, _type.isDefined)(column.command) || !column.validationRules || !Array.isArray(column.validationRules) || !column.validationRules.length) { return } editIndex = editingController.getIndexByKey(parameters.key, editingController._editData); if (editIndex < 0) { if (!showEditorAlways) { var columnsController = this.getController("columns"); var visibleColumns = columnsController && columnsController.getVisibleColumns() || []; showEditorAlways = visibleColumns.some(function(column) { return column.showEditorAlways }) } if (showEditorAlways && editingController.isCellOrBatchEditMode() && editingController.allowUpdating({ row: parameters.row })) { editIndex = editingController._addEditData({ key: parameters.key, oldData: parameters.data }) } } if (editIndex >= 0) { if ($container && !$container.length) { _ui2.default.log("E1050"); return } editData = editingController._editData[editIndex]; var useDefaultValidator = $container && $container.hasClass("dx-widget"); $container && $container.addClass(this.addWidgetPrefix(VALIDATOR_CLASS)); var validator = new _validator2.default($container || (0, _renderer2.default)("<div>"), { name: column.caption, validationRules: (0, _extend.extend)(true, [], column.validationRules), validationGroup: editData, adapter: useDefaultValidator ? null : { getValue: getValue, applyValidationResults: function(result) { _this3.applyValidationResult($container, result) } }, dataGetter: function() { return { data: (0, _uiGrid_core3.createObjectWithChanges)(editData.oldData, editData.data), column: column } }, onInitialized: this.validatorInitialized.bind(this), onDisposing: this.validatorDisposing.bind(this) }); if (useDefaultValidator) { var adapter = validator.option("adapter"); if (adapter) { adapter.getValue = getValue; adapter.validationRequestsCallbacks.empty() } } return validator } }, setDisableApplyValidationResults: function(flag) { this._disableApplyValidationResults = flag }, getDisableApplyValidationResults: function() { return this._disableApplyValidationResults }, isCurrentValidatorProcessing: function(_ref) { var rowKey = _ref.rowKey, columnIndex = _ref.columnIndex; return this._currentCellValidator && this._currentCellValidator.option("validationGroup").key === rowKey && this._currentCellValidator.option("dataGetter")().column.index === columnIndex }, validateCell: function(validator) { var cellParams = { rowKey: validator.option("validationGroup").key, columnIndex: validator.option("dataGetter")().column.index }; var validationResult = this.getCellValidationResult(cellParams); var stateRestored = validationResultIsValid(validationResult); if (!stateRestored) { validationResult = validator.validate() } var deferred = new _deferred.Deferred; var adapter = validator.option("adapter"); if (stateRestored && validationResult.status === VALIDATION_STATUS.pending) { this.updateCellValidationResult(cellParams); adapter.applyValidationResults(validationResult) }(0, _deferred.when)(validationResult.complete || validationResult).done(function(validationResult) { stateRestored && adapter.applyValidationResults(validationResult); deferred.resolve(validationResult) }); return deferred.promise() }, updateCellValidationResult: function(_ref2) { var rowKey = _ref2.rowKey, columnIndex = _ref2.columnIndex, validationResult = _ref2.validationResult; var editData = this._editingController.getEditDataByKey(rowKey); if (!editData) { return } if (!editData.validationResults) { editData.validationResults = {} } var result; if (validationResult) { result = (0, _extend.extend)({}, validationResult); editData.validationResults[columnIndex] = result; if (validationResult.status === VALIDATION_STATUS.pending) { if (this._editingController.getEditMode() === EDIT_MODE_CELL) { result.deferred = new _deferred.Deferred; result.complete.always(function() { result.deferred.resolve() }); this._editingController.addDeferred(result.deferred) } if (this._disableApplyValidationResults) { result.disabledPendingId = validationResult.id; return } } } else { result = editData.validationResults[columnIndex] } if (result && result.disabledPendingId) { delete result.disabledPendingId } }, getCellValidationResult: function(_ref3) { var rowKey = _ref3.rowKey, columnIndex = _ref3.columnIndex; var editData = this._editingController.getEditDataByKey(rowKey); return editData && editData.validationResults && editData.validationResults[columnIndex] }, removeCellValidationResult: function(_ref4) { var editData = _ref4.editData, columnIndex = _ref4.columnIndex; if (editData && editData.validationResults) { this.cancelCellValidationResult({ editData: editData, columnIndex: columnIndex }); delete editData.validationResults[columnIndex] } }, cancelCellValidationResult: function(_ref5) { var editData = _ref5.editData, columnIndex = _ref5.columnIndex; if (editData && editData.validationResults) { var result = editData.validationResults[columnIndex]; if (result) { result.deferred && result.deferred.reject(VALIDATION_CANCELLED); editData.validationResults[columnIndex] = VALIDATION_CANCELLED } } }, resetRowValidationResults: function(editData) { if (editData) { editData.validationResults && delete editData.validationResults; delete editData.validated } }, isInvalidCell: function(_ref6) { var rowKey = _ref6.rowKey, columnIndex = _ref6.columnIndex; var result = this.getCellValidationResult({ rowKey: rowKey, columnIndex: columnIndex }); return validationResultIsValid(result) && result.status === VALIDATION_STATUS.invalid }, getCellValidator: function(_ref7) { var rowKey = _ref7.rowKey, columnIndex = _ref7.columnIndex; var editData = this._editingController.getEditDataByKey(rowKey); var groupConfig = editData && _validation_engine2.default.getGroupConfig(editData); var validators = groupConfig && groupConfig.validators; return validators && validators.filter(function(v) { var column = v.option("dataGetter")().column; return column ? column.index === columnIndex : false })[0] }, setCellValidationStatus: function(cellOptions) { var validationResult = this.getCellValidationResult({ rowKey: cellOptions.key, columnIndex: cellOptions.column.index }); if ((0, _type.isDefined)(validationResult)) { cellOptions.validationStatus = validationResult !== VALIDATION_CANCELLED ? validationResult.status : VALIDATION_CANCELLED } else { delete cellOptions.validationStatus } } } }()); module.exports = { defaultOptions: function() { return { editing: { texts: { validationCancelChanges: _message2.default.format("dxDataGrid-validationCancelChanges") } } } }, controllers: { validating: ValidatingController }, extenders: { controllers: { editing: { _addEditData: function(options, row) { var that = this; var validatingController = that.getController("validating"); var editDataIndex = that.callBase(options, row); if (editDataIndex >= 0) { var editData = that._editData[editDataIndex]; validatingController.updateEditData(editData) } return editDataIndex }, _updateRowAndPageIndices: function() { var that = this; var startInsertIndex = that.getView("rowsView").getTopVisibleItemIndex(); var rowIndex = startInsertIndex; (0, _iterator.each)(that._editData, function(_, editData) { if (!editData.isValid && editData.pageIndex !== that._pageIndex) { editData.pageIndex = that._pageIndex; if (editData.type === EDIT_DATA_INSERT_TYPE) { editData.rowIndex = startInsertIndex } else { editData.rowIndex = rowIndex } rowIndex++ } }) }, _needInsertItem: function(editData) { var result = this.callBase.apply(this, arguments); if (result && !editData.isValid) { result = editData.key.pageIndex === this._pageIndex } return result }, processItems: function(items, changeType) { var that = this; var i; var editData = that._editData; var dataController = that.getController("data"); var getIndexByEditData = function(editData, items) { var index = -1; var isInsert = editData.type === EDIT_DATA_INSERT_TYPE; var key = editData.key; (0, _iterator.each)(items, function(i, item) { if ((0, _common.equalByValue)(key, isInsert ? item : dataController.keyOf(item))) { index = i; return false } }); return index }; items = that.callBase(items, changeType); var itemsCount = items.length; var addInValidItem = function(editData) { var data = { key: editData.key }; var index = getIndexByEditData(editData, items); if (index >= 0) { return } editData.rowIndex = editData.rowIndex > itemsCount ? editData.rowIndex % itemsCount : editData.rowIndex; var rowIndex = editData.rowIndex; data[INSERT_INDEX] = 1; items.splice(rowIndex, 0, data) }; if (that.getEditMode() === EDIT_MODE_BATCH && "prepend" !== changeType && "append" !== changeType) { for (i = 0; i < editData.length; i++) { if (editData[i].type && editData[i].pageIndex === that._pageIndex && editData[i].key.pageIndex !== that._pageIndex) { addInValidItem(editData[i]) } } } return items }, processDataItem: function(item) { var that = this; var isInserted = item.data[INSERT_INDEX]; var key = isInserted ? item.data.key : item.key; var editMode = that.getEditMode(); if (editMode === EDIT_MODE_BATCH && isInserted && key) { var editIndex = (0, _uiGrid_core3.getIndexByKey)(key, that._editData); if (editIndex >= 0) { var editData = that._editData[editIndex]; if (editData.type !== EDIT_DATA_INSERT_TYPE) { item.data = (0, _extend.extend)(true, {}, editData.oldData, editData.data); item.key = key } } } that.callBase.apply(that, arguments) }, _getInvisibleColumns: function(editData) { var _this4 = this; var columnsController = this.getController("columns"); var hasInvisibleRows; var invisibleColumns = columnsController.getInvisibleColumns(); if (this.isCellOrBatchEditMode()) { hasInvisibleRows = editData.some(function(rowEditData) { var rowIndex = _this4._dataController.getRowIndexByKey(rowEditData.key); return rowIndex < 0 }) } return hasInvisibleRows ? columnsController.getColumns() : invisibleColumns }, _createInvisibleColumnValidators: function(editData) { var validatingController = this.getController("validating"); var columnsController = this.getController("columns"); var invisibleColumns = this._getInvisibleColumns(editData).filter(function(column) { return !column.isBand }); var groupColumns = columnsController.getGroupColumns().filter(function(column) { return !column.showWhenGrouped && invisibleColumns.indexOf(column) === -1 }); var invisibleColumnValidators = []; invisibleColumns.push.apply(invisibleColumns, _toConsumableArray(groupColumns)); if (FORM_BASED_MODES.indexOf(this.getEditMode()) === -1) { (0, _iterator.each)(invisibleColumns, function(_, column) { editData.forEach(function(options) { var data; if (options.type === EDIT_DATA_INSERT_TYPE) { data = options.data } else { if ("update" === options.type) { data = (0, _uiGrid_core3.createObjectWithChanges)(options.oldData, options.data) } } if (data) { var validator = validatingController.createValidator({ column: column, key: options.key, value: column.calculateCellValue(data) }); if (validator) { invisibleColumnValidators.push(validator) } } }) }) } return function() { invisibleColumnValidators.forEach(function(validator) { validator.dispose() }) } }, _beforeSaveEditData: function(editData, editIndex) { var _this5 = this; var result = this.callBase.apply(this, arguments); var validatingController = this.getController("validating"); if (editData) { var isValid = "remove" === editData.type || editData.isValid; result = result || !isValid } else { var disposeValidators = this._createInvisibleColumnValidators(this._editData); result = new _deferred.Deferred; this.executeOperation(result, function() { validatingController.validate(true).done(function(isFullValid) { disposeValidators(); _this5._updateRowAndPageIndices(); switch (_this5.getEditMode()) { case EDIT_MODE_CELL: if (!isFullValid) { _this5._focusEditingCell() } break; case EDIT_MODE_BATCH: if (!isFullValid) { _this5._editRowIndex = -1; _this5._editColumnIndex = -1; _this5.getController("data").updateItems() } } result.resolve(!isFullValid) }) }) } return result.promise ? result.promise() : result }, _beforeEditCell: function(rowIndex, columnIndex, item) { var result = this.callBase(rowIndex, columnIndex, item); if (this.getEditMode() === EDIT_MODE_CELL) { var $cell = this._rowsView._getCellElement(rowIndex, columnIndex); var validator = $cell && $cell.data("dxValidator"); var rowOptions = $cell && $cell.closest(".dx-row").data("options"); var value = validator && validator.option("adapter").getValue(); if (validator && cellValueShouldBeValidated(value, rowOptions)) { var validatingController = this.getController("validating"); var deferred = new _deferred.Deferred; (0, _deferred.when)(validatingController.validateCell(validator), result).done(function(validationResult, result) { deferred.resolve(validationResult.status === VALIDATION_STATUS.valid && result) }); return deferred.promise() } else { if (!validator) { return result } } } }, _afterSaveEditData: function(cancel) { var _this6 = this; var $firstErrorRow; (0, _iterator.each)(this._editData, function(_, editData) { var $errorRow = _this6._showErrorRow(editData); $firstErrorRow = $firstErrorRow || $errorRow }); if ($firstErrorRow) { var scrollable = this._rowsView.getScrollable(); if (scrollable) { scrollable.update(); scrollable.scrollToElement($firstErrorRow) } } if (cancel && this.getEditMode() === EDIT_MODE_CELL && this._needUpdateRow()) { var editRowIndex = this.getEditRowIndex(); this._dataController.updateItems({ changeType: "update", rowIndices: [editRowIndex] }); this._focusEditingCell() } }, _showErrorRow: function(editData) { var $popupContent; var errorHandling = this.getController("errorHandling"); var items = this.getController("data").items(); var rowIndex = this.getIndexByKey(editData.key, items); if (!editData.isValid && editData.errorText && rowIndex >= 0) { $popupContent = this.getPopupContent(); return errorHandling && errorHandling.renderErrorRow(editData.errorText, rowIndex, $popupContent) } }, updateFieldValue: function(e) { var _this7 = this; var validatingController = this.getController("validating"); var deferred = new _deferred.Deferred; validatingController.removeCellValidationResult({ editData: this.getEditDataByKey(e.key), columnIndex: e.column.index }); this.callBase.apply(this, arguments).done(function() { var currentValidator = validatingController.getCellValidator({ rowKey: e.key, columnIndex: e.column.index }); (0, _deferred.when)(currentValidator && validatingController.validateCell(currentValidator)).done(function(validationResult) { _this7.getController("editorFactory").refocus(); deferred.resolve(validationResult) }) }); return deferred.promise() }, showHighlighting: function($cell, skipValidation) { var _this8 = this; var isValid = true; var callBase = this.callBase; var deferred = new _deferred.Deferred; if (!skipValidation) { var validator = $cell.data("dxValidator"); if (validator) { (0, _deferred.when)(this.getController("validating").validateCell(validator)).done(function(validationResult) { isValid = validationResult.status === VALIDATION_STATUS.valid; if (isValid) { callBase.call(_this8, $cell) } deferred.resolve() }); return deferred.promise() } } if (isValid) { callBase.call(this, $cell) } return deferred.resolve().promise() }, highlightDataCell: function($cell, parameters) { var isEditableCell = !!parameters.setValue; var cellModified = this.isCellModified(parameters); var validatingController = this.getController("validating"); if (!cellModified && isEditableCell) { validatingController.setCellValidationStatus(parameters); var isValidated = (0, _type.isDefined)(parameters.validationStatus); var skipValidation = parameters.row.isNewRow || !isValidated; (0, _deferred.when)(this.showHighlighting($cell, skipValidation)).done(function() { validatingController.setCellValidationStatus(parameters) }); return } this.callBase.apply(this, arguments) }, getEditDataByKey: function(key) { return this._editData[(0, _uiGrid_core3.getIndexByKey)(key, this._editData)] }, isCellModified: function(parameters) { var cellModified = this.callBase(parameters); var editData = this.getEditDataByKey(parameters.key); var isCellInvalid = !!parameters.row && this.getController("validating").isInvalidCell({ rowKey: parameters.key, columnIndex: parameters.column.index }); return cellModified || rowIsValidated(editData) && isCellInvalid } }, editorFactory: function() { var getWidthOfVisibleCells = function(that, element) { var rowIndex = (0, _renderer2.default)(element).closest("tr").index(); var $cellElements = (0, _renderer2.default)(that._rowsView.getRowElement(rowIndex)).first().children().filter(":not(.dx-hidden-cell)"); return that._rowsView._getWidths($cellElements).reduce(function(w1, w2) { return w1 + w2 }, 0) }; var getBoundaryNonFixedColumnsInfo = function(fixedColumns) { var firstNonFixedColumnIndex; var lastNonFixedColumnIndex; fixedColumns.some(function(column, index) { if (column.command === COMMAND_TRANSPARENT) { firstNonFixedColumnIndex = 0 === index ? -1 : index; lastNonFixedColumnIndex = index === fixedColumns.length - 1 ? -1 : index + column.colspan - 1; return true } }); return { startColumnIndex: firstNonFixedColumnIndex, endColumnIndex: lastNonFixedColumnIndex } }; return { _showRevertButton: function($container, $targetElement) { var _this9 = this; if (!$targetElement || !$targetElement.length) { return } var $tooltipElement = $container.find("." + this.addWidgetPrefix(REVERT_TOOLTIP_CLASS)); $tooltipElement && $tooltipElement.remove(); $tooltipElement = (0, _renderer2.default)("<div>").addClass(this.addWidgetPrefix(REVERT_TOOLTIP_CLASS)).appendTo($container); var tooltipOptions = { animation: null, visible: true, target: $targetElement, container: $container, closeOnOutsideClick: false, closeOnTargetScroll: false, contentTemplate: function() { var $buttonElement = (0, _renderer2.default)("<div>").addClass(REVERT_BUTTON_CLASS); var buttonOptions = { icon: "revert", hint: _this9.option("editing.texts.validationCancelChanges"), onClick: function() { _this9._editingController.cancelEditData() } }; return new _button2.default($buttonElement, buttonOptions).$element() }, position: { my: "left top", at: "right top", of: $targetElement, offset: "1 0", collision: "flip", boundary: this._rowsView.element() }, onPositioned: this._positionedHandler.bind(this) }; return new _tooltip2.default($tooltipElement, tooltipOptions) }, _hideFixedGroupCell: function($cell, overlayOptions) { var $nextFixedRowElement; var $groupCellElement; var isFixedColumns = this._rowsView.isFixedColumns(); var isFormEditMode = this._editingController.isFormEditMode(); if (isFixedColumns && !isFormEditMode) { var nextRowOptions = $cell.closest(".dx-row").next().data("options"); if (nextRowOptions && "group" === nextRowOptions.rowType) { $nextFixedRowElement = (0, _renderer2.default)(this._rowsView.getRowElement(nextRowOptions.rowIndex)).last(); $groupCellElement = $nextFixedRowElement.find("." + GROUP_CELL_CLASS); if ($groupCellElement.length && "hidden" !== $groupCellElement.get(0).style.visibility) { $groupCellElement.css("visibility", "hidden"); overlayOptions.onDisposing = function() { $groupCellElement.css("visibility", "") } } } } }, _positionedHandler: function(e, isOverlayVisible) { if (!e.component.__skipPositionProcessing) { var isRevertButton = (0, _renderer2.default)(e.element).hasClass(this.addWidgetPrefix(REVERT_TOOLTIP_CLASS)); var needRepaint = !isRevertButton && this._rowsView.updateFreeSpaceRowHeight(); var normalizedPosition = this._normalizeValidationMessagePositionAndMaxWidth(e, isRevertButton, isOverlayVisible); e.component.__skipPositionProcessing = !!(needRepaint || normalizedPosition); if (normalizedPosition) { e.component.option(normalizedPosition) } else { if (needRepaint) { e.component.repaint()