UNPKG

devextreme

Version:

HTML5 JavaScript Component Suite for Responsive Web Development

339 lines (286 loc) • 10.9 kB
"use strict"; var $ = require("../../core/renderer"), dataUtils = require("../../core/element_data"), Callbacks = require("../../core/utils/callbacks"), commonUtils = require("../../core/utils/common"), windowUtils = require("../../core/utils/window"), getDefaultAlignment = require("../../core/utils/position").getDefaultAlignment, extend = require("../../core/utils/extend").extend, Widget = require("../widget/ui.widget"), ValidationMixin = require("../validation/validation_mixin"), Overlay = require("../overlay"); var READONLY_STATE_CLASS = "dx-state-readonly", INVALID_CLASS = "dx-invalid", INVALID_MESSAGE = "dx-invalid-message", INVALID_MESSAGE_AUTO = "dx-invalid-message-auto", INVALID_MESSAGE_ALWAYS = "dx-invalid-message-always", VALIDATION_TARGET = "dx-validation-target", VALIDATION_MESSAGE_MIN_WIDTH = 100; /** * @name Editor * @publicName Editor * @type object * @inherits Widget * @module ui/editor/editor * @export default * @hidden */ var Editor = Widget.inherit({ _init: function _init() { this.callBase(); this.validationRequest = Callbacks(); var $element = this.$element(); if ($element) { dataUtils.data($element[0], VALIDATION_TARGET, this); } }, _getDefaultOptions: function _getDefaultOptions() { return extend(this.callBase(), { /** * @name EditorOptions.value * @publicName value * @type any * @default null * @fires EditorOptions.onValueChanged */ value: null, /** * @name EditorOptions.name * @publicName name * @type string * @default "" * @hidden */ name: "", /** * @name EditorOptions.onValueChanged * @publicName onValueChanged * @extends Action * @type function(e) * @type_function_param1 e:object * @type_function_param1_field4 value:object * @type_function_param1_field5 previousValue:object * @type_function_param1_field6 jQueryEvent:jQuery.Event:deprecated(event) * @type_function_param1_field7 event:event * @action */ onValueChanged: null, /** * @name EditorOptions.readOnly * @publicName readOnly * @type boolean * @default false */ readOnly: false, /** * @name EditorOptions.isValid * @publicName isValid * @type boolean * @default true */ isValid: true, /** * @name EditorOptions.validationError * @publicName validationError * @type object * @ref * @default undefined */ validationError: null, /** * @name EditorOptions.validationMessageMode * @publicName validationMessageMode * @type Enums.ValidationMessageMode * @default "auto" */ validationMessageMode: "auto", validationBoundary: undefined, validationMessageOffset: { h: 0, v: 0 } }); }, _attachKeyboardEvents: function _attachKeyboardEvents() { if (this.option("readOnly")) { return; } this.callBase(); if (this._keyboardProcessor) { this._attachChildKeyboardEvents(); } }, _attachChildKeyboardEvents: commonUtils.noop, _setOptionsByReference: function _setOptionsByReference() { this.callBase(); extend(this._optionsByReference, { validationError: true }); }, _createValueChangeAction: function _createValueChangeAction() { this._valueChangeAction = this._createActionByOption("onValueChanged", { excludeValidators: ["disabled", "readOnly"] }); }, _suppressValueChangeAction: function _suppressValueChangeAction() { this._valueChangeActionSuppressed = true; }, _resumeValueChangeAction: function _resumeValueChangeAction() { this._valueChangeActionSuppressed = false; }, _initMarkup: function _initMarkup() { this._toggleReadOnlyState(); this._setSubmitElementName(this.option("name")); this.callBase(); this._renderValidationState(); }, _raiseValueChangeAction: function _raiseValueChangeAction(value, previousValue) { if (!this._valueChangeAction) { this._createValueChangeAction(); } this._valueChangeAction(this._valueChangeArgs(value, previousValue)); }, _valueChangeArgs: function _valueChangeArgs(value, previousValue) { return { value: value, previousValue: previousValue, event: this._valueChangeEventInstance }; }, _saveValueChangeEvent: function _saveValueChangeEvent(e) { this._valueChangeEventInstance = e; }, _renderValidationState: function _renderValidationState() { var isValid = this.option("isValid"), validationError = this.option("validationError"), validationMessageMode = this.option("validationMessageMode"), $element = this.$element(); $element.toggleClass(INVALID_CLASS, !isValid); this.setAria("invalid", !isValid || undefined); if (!windowUtils.hasWindow()) { return; } if (this._$validationMessage) { this._$validationMessage.remove(); this._$validationMessage = null; } if (!isValid && validationError && validationError.message) { this._$validationMessage = $("<div>").addClass(INVALID_MESSAGE).html(validationError.message).appendTo($element); this._validationMessage = this._createComponent(this._$validationMessage, Overlay, { integrationOptions: {}, templatesRenderAsynchronously: false, target: this._getValidationMessageTarget(), shading: false, width: 'auto', height: 'auto', container: $element, position: this._getValidationMessagePosition("below"), closeOnOutsideClick: false, closeOnTargetScroll: false, animation: null, visible: true, propagateOutsideClick: true, _checkParentVisibility: false }); this._$validationMessage.toggleClass(INVALID_MESSAGE_AUTO, validationMessageMode === "auto").toggleClass(INVALID_MESSAGE_ALWAYS, validationMessageMode === "always"); this._setValidationMessageMaxWidth(); } }, _setValidationMessageMaxWidth: function _setValidationMessageMaxWidth() { if (!this._validationMessage) { return; } if (this._getValidationMessageTarget().outerWidth() === 0) { this._validationMessage.option("maxWidth", "100%"); return; } var validationMessageMaxWidth = Math.max(VALIDATION_MESSAGE_MIN_WIDTH, this._getValidationMessageTarget().outerWidth()); this._validationMessage.option("maxWidth", validationMessageMaxWidth); }, _getValidationMessageTarget: function _getValidationMessageTarget() { return this.$element(); }, _getValidationMessagePosition: function _getValidationMessagePosition(positionRequest) { var rtlEnabled = this.option("rtlEnabled"), messagePositionSide = getDefaultAlignment(rtlEnabled), messageOriginalOffset = this.option("validationMessageOffset"), messageOffset = { h: messageOriginalOffset.h, v: messageOriginalOffset.v }, verticalPositions = positionRequest === "below" ? [" top", " bottom"] : [" bottom", " top"]; if (rtlEnabled) messageOffset.h = -messageOffset.h; if (positionRequest !== "below") messageOffset.v = -messageOffset.v; return { offset: messageOffset, boundary: this.option("validationBoundary"), my: messagePositionSide + verticalPositions[0], at: messagePositionSide + verticalPositions[1], collision: "none flip" }; }, _toggleReadOnlyState: function _toggleReadOnlyState() { this.$element().toggleClass(READONLY_STATE_CLASS, !!this.option("readOnly")); this.setAria("readonly", this.option("readOnly") || undefined); }, _dispose: function _dispose() { var element = this.$element()[0]; dataUtils.data(element, VALIDATION_TARGET, null); this.callBase(); }, _setSubmitElementName: function _setSubmitElementName(name) { var $submitElement = this._getSubmitElement(); if (!$submitElement) { return; } if (name.length > 0) { $submitElement.attr("name", name); } else { $submitElement.removeAttr("name"); } }, _getSubmitElement: function _getSubmitElement() { return null; }, _optionChanged: function _optionChanged(args) { switch (args.name) { case "onValueChanged": this._createValueChangeAction(); break; case "isValid": case "validationError": case "validationBoundary": case "validationMessageMode": this._renderValidationState(); break; case "readOnly": this._toggleReadOnlyState(); this._refreshFocusState(); break; case "value": if (!this._valueChangeActionSuppressed) { this._raiseValueChangeAction(args.value, args.previousValue); this._saveValueChangeEvent(undefined); } if (args.value != args.previousValue) { // jshint ignore:line this.validationRequest.fire({ value: args.value, editor: this }); } break; case "width": this.callBase(args); this._setValidationMessageMaxWidth(); break; case "name": this._setSubmitElementName(args.value); break; default: this.callBase(args); } }, /** * @name EditorMethods.reset * @publicName reset() */ reset: function reset() { this.option("value", null); } }).include(ValidationMixin); module.exports = Editor;