devextreme
Version:
HTML5 JavaScript Component Suite for Responsive Web Development
275 lines (229 loc) • 8.04 kB
JavaScript
"use strict";
var $ = require("../core/renderer"),
eventsEngine = require("../events/core/events_engine"),
noop = require("../core/utils/common").noop,
registerComponent = require("../core/component_registrator"),
extend = require("../core/utils/extend").extend,
eventUtils = require("../events/utils"),
pointerEvents = require("../events/pointer"),
TextBox = require("./text_box");
var TEXTAREA_CLASS = "dx-textarea",
TEXTEDITOR_INPUT_CLASS = "dx-texteditor-input";
/**
* @name dxTextArea
* @isEditor
* @publicName dxTextArea
* @inherits dxTextBox
* @module ui/text_area
* @export default
*/
var TextArea = TextBox.inherit({
_getDefaultOptions: function _getDefaultOptions() {
return extend(this.callBase(), {
/**
* @name dxTextAreaOptions.mode
* @publicName mode
* @hidden
* @inheritdoc
*/
/**
* @name dxTextAreaOptions.showClearButton
* @publicName showClearButton
* @hidden
* @inheritdoc
*/
/**
* @name dxTextAreaOptions.spellcheck
* @publicName spellcheck
* @type boolean
* @default true
*/
spellcheck: true,
/**
* @name dxTextAreaOptions.minHeight
* @publicName minHeight
* @type numeric|string
* @default undefined
*/
minHeight: undefined,
/**
* @name dxTextAreaOptions.maxHeight
* @publicName maxHeight
* @type numeric|string
* @default undefined
*/
maxHeight: undefined,
/**
* @name dxTextAreaOptions.autoResizeEnabled
* @publicName autoResizeEnabled
* @type boolean
* @default false
*/
autoResizeEnabled: false
/**
* @name dxTextAreaOptions.mask
* @publicName mask
* @hidden
* @inheritdoc
*/
/**
* @name dxTextAreaOptions.maskChar
* @publicName maskChar
* @hidden
* @inheritdoc
*/
/**
* @name dxTextAreaOptions.maskRules
* @publicName maskRules
* @hidden
* @inheritdoc
*/
/**
* @name dxTextAreaOptions.maskInvalidMessage
* @publicName maskInvalidMessage
* @hidden
* @inheritdoc
*/
/**
* @name dxTextAreaOptions.useMaskedValue
* @publicName useMaskedValue
* @hidden
* @inheritdoc
*/
/**
* @name dxTextAreaOptions.showMaskMode
* @publicName showMaskMode
* @hidden
* @inheritdoc
*/
});
},
_initMarkup: function _initMarkup() {
this.$element().addClass(TEXTAREA_CLASS);
this.callBase();
this.setAria("multiline", "true");
},
_renderContentImpl: function _renderContentImpl() {
this._updateInputHeight();
this.callBase();
},
_renderInput: function _renderInput() {
this.callBase();
this._renderScrollHandler();
},
_createInput: function _createInput() {
var $input = $("<textarea>");
this._applyInputAttributes($input, this.option("inputAttr"));
return $input;
},
_applyInputAttributes: function _applyInputAttributes($input, customAttributes) {
$input.attr(customAttributes).addClass(TEXTEDITOR_INPUT_CLASS);
},
_renderScrollHandler: function _renderScrollHandler() {
var $input = this._input(),
eventY = 0;
eventsEngine.on($input, eventUtils.addNamespace(pointerEvents.down, this.NAME), function (e) {
eventY = eventUtils.eventData(e).y;
});
eventsEngine.on($input, eventUtils.addNamespace(pointerEvents.move, this.NAME), function (e) {
var scrollTopPos = $input.scrollTop(),
scrollBottomPos = $input.prop("scrollHeight") - $input.prop("clientHeight") - scrollTopPos;
if (scrollTopPos === 0 && scrollBottomPos === 0) {
return;
}
var currentEventY = eventUtils.eventData(e).y;
var isScrollFromTop = scrollTopPos === 0 && eventY >= currentEventY,
isScrollFromBottom = scrollBottomPos === 0 && eventY <= currentEventY,
isScrollFromMiddle = scrollTopPos > 0 && scrollBottomPos > 0;
if (isScrollFromTop || isScrollFromBottom || isScrollFromMiddle) {
e.isScrollingEvent = true;
e.stopPropagation();
}
eventY = currentEventY;
});
},
_renderDimensions: function _renderDimensions() {
var $element = this.$element();
var element = $element.get(0);
var width = this._getOptionValue("width", element);
var height = this._getOptionValue("height", element);
var minHeight = this.option("minHeight");
var maxHeight = this.option("maxHeight");
$element.css({
minHeight: minHeight !== undefined ? minHeight : "",
maxHeight: maxHeight !== undefined ? maxHeight : "",
width: width,
height: height
});
},
_resetDimensions: function _resetDimensions() {
this.$element().css({
"height": "",
"minHeight": "",
"maxHeight": ""
});
},
_renderEvents: function _renderEvents() {
if (this.option("autoResizeEnabled")) {
eventsEngine.on(this._input(), eventUtils.addNamespace("input paste", this.NAME), this._updateInputHeight.bind(this));
}
this.callBase();
},
_refreshEvents: function _refreshEvents() {
eventsEngine.off(this._input(), eventUtils.addNamespace("input paste", this.NAME));
this.callBase();
},
_updateInputHeight: function _updateInputHeight() {
var $input = this._input();
if (!this.option("autoResizeEnabled") || this.option("height") !== undefined) {
$input.css("height", "");
return;
}
this._resetDimensions();
$input.css("height", 0);
var heightDifference = this._$element.outerHeight() - $input.outerHeight();
this._renderDimensions();
var minHeight = this.option("minHeight"),
maxHeight = this.option("maxHeight"),
inputHeight = $input[0].scrollHeight;
if (minHeight !== undefined) {
inputHeight = Math.max(inputHeight, minHeight - heightDifference);
}
if (maxHeight !== undefined) {
inputHeight = Math.min(inputHeight, maxHeight - heightDifference);
}
$input.css("height", inputHeight);
},
_renderInputType: noop,
_visibilityChanged: function _visibilityChanged(visible) {
if (visible) {
this._updateInputHeight();
}
},
_optionChanged: function _optionChanged(args) {
switch (args.name) {
case "autoResizeEnabled":
this._refreshEvents();
this._updateInputHeight();
break;
case "value":
case "height":
this.callBase(args);
this._updateInputHeight();
break;
case "minHeight":
case "maxHeight":
this._renderDimensions();
this._updateInputHeight();
break;
case "visible":
this.callBase(args);
args.value && this._updateInputHeight();
break;
default:
this.callBase(args);
}
}
});
registerComponent("dxTextArea", TextArea);
module.exports = TextArea;