diff --git a/packages/devextreme/js/__internal/ui/collection/m_search_box_mixin.ts b/packages/devextreme/js/__internal/ui/collection/m_search_box_mixin.ts new file mode 100644 index 000000000000..fca119d60410 --- /dev/null +++ b/packages/devextreme/js/__internal/ui/collection/m_search_box_mixin.ts @@ -0,0 +1,178 @@ +import messageLocalization from '@js/common/core/localization/message'; +import $ from '@js/core/renderer'; +import { Deferred } from '@js/core/utils/deferred'; +import { extend } from '@js/core/utils/extend'; +import { stubComponent } from '@js/core/utils/stubs'; +import errors from '@js/ui/widget/ui.errors'; + +let EditorClass = stubComponent('TextBox'); + +export default { + _getDefaultOptions() { + return extend(this.callBase(), { + searchMode: '', + searchExpr: null, + searchValue: '', + searchEnabled: false, + searchEditorOptions: {}, + }); + }, + + _initMarkup(): void { + this._renderSearch(); + this.callBase(); + }, + + _renderSearch(): void { + const $element = this.$element(); + const searchEnabled = this.option('searchEnabled'); + const searchBoxClassName = this._addWidgetPrefix('search'); + const rootElementClassName = this._addWidgetPrefix('with-search'); + + if (!searchEnabled) { + $element.removeClass(rootElementClassName); + this._removeSearchBox(); + return; + } + + const editorOptions = this._getSearchEditorOptions(); + + if (this._searchEditor) { + this._searchEditor.option(editorOptions); + } else { + $element.addClass(rootElementClassName); + this._$searchEditorElement = $('
').addClass(searchBoxClassName).prependTo($element); + this._searchEditor = this._createComponent(this._$searchEditorElement, EditorClass, editorOptions); + } + }, + + _removeSearchBox(): void { + this._$searchEditorElement && this._$searchEditorElement.remove(); + delete this._$searchEditorElement; + delete this._searchEditor; + }, + + _getSearchEditorOptions() { + const that = this; + const userEditorOptions = that.option('searchEditorOptions'); + const searchText = messageLocalization.format('Search'); + + return extend({ + mode: 'search', + placeholder: searchText, + tabIndex: that.option('tabIndex'), + value: that.option('searchValue'), + valueChangeEvent: 'input', + inputAttr: { + 'aria-label': searchText, + }, + onValueChanged(e) { + const searchTimeout = that.option('searchTimeout'); + that._valueChangeDeferred = Deferred(); + clearTimeout(that._valueChangeTimeout); + + that._valueChangeDeferred.done(function () { + this.option('searchValue', e.value); + }.bind(that)); + + if (e.event && e.event.type === 'input' && searchTimeout) { + that._valueChangeTimeout = setTimeout(() => { + that._valueChangeDeferred.resolve(); + }, searchTimeout); + } else { + that._valueChangeDeferred.resolve(); + } + }, + }, userEditorOptions); + }, + + _getAriaTarget() { + if (this.option('searchEnabled')) { + return this._itemContainer(true); + } + return this.callBase(); + }, + + _focusTarget() { + if (this.option('searchEnabled')) { + return this._itemContainer(true); + } + + return this.callBase(); + }, + + _updateFocusState(e, isFocused): void { + if (this.option('searchEnabled')) { + this._toggleFocusClass(isFocused, this.$element()); + } + this.callBase(e, isFocused); + }, + + getOperationBySearchMode(searchMode) { + return searchMode === 'equals' ? '=' : searchMode; + }, + + _optionChanged(args) { + switch (args.name) { + case 'searchEnabled': + case 'searchEditorOptions': + this._invalidate(); + break; + case 'searchExpr': + case 'searchMode': + case 'searchValue': + if (!this._dataSource) { + errors.log('W1009'); + return; + } + if (args.name === 'searchMode') { + this._dataSource.searchOperation(this.getOperationBySearchMode(args.value)); + } else { + this._dataSource[args.name](args.value); + } + this._dataSource.load(); + break; + case 'searchTimeout': + break; + default: + this.callBase(args); + } + }, + + focus() { + if (!this.option('focusedElement') && this.option('searchEnabled')) { + this._searchEditor && this._searchEditor.focus(); + return; + } + + this.callBase(); + }, + + _cleanAria(): void { + const $element = this.$element(); + + this.setAria({ + role: null, + activedescendant: null, + }, $element); + + $element.attr('tabIndex', null); + }, + + _clean(): void { + this.callBase(); + this._cleanAria(); + }, + + _refresh(): void { + if (this._valueChangeDeferred) { + this._valueChangeDeferred.resolve(); + } + + this.callBase(); + }, + + setEditorClass(value): void { + EditorClass = value; + }, +}; diff --git a/packages/devextreme/js/ui/widget/ui.search_box_mixin.js b/packages/devextreme/js/ui/widget/ui.search_box_mixin.js index 4491d72a5413..b046a0491ab6 100644 --- a/packages/devextreme/js/ui/widget/ui.search_box_mixin.js +++ b/packages/devextreme/js/ui/widget/ui.search_box_mixin.js @@ -1,183 +1,3 @@ -import $ from '../../core/renderer'; -import { extend } from '../../core/utils/extend'; -import messageLocalization from '../../common/core/localization/message'; -import errors from '../widget/ui.errors'; -import { Deferred } from '../../core/utils/deferred'; -import { stubComponent } from '../../core/utils/stubs'; +import SearchBoxMixin from '../../__internal/ui/collection/m_search_box_mixin'; -let EditorClass = stubComponent('TextBox'); - -export default { - _getDefaultOptions: function() { - return extend(this.callBase(), { - searchMode: '', - - searchExpr: null, - - searchValue: '', - - searchEnabled: false, - - searchEditorOptions: {}, - - }); - }, - - _initMarkup: function() { - this._renderSearch(); - this.callBase(); - }, - - _renderSearch: function() { - const $element = this.$element(); - const searchEnabled = this.option('searchEnabled'); - const searchBoxClassName = this._addWidgetPrefix('search'); - const rootElementClassName = this._addWidgetPrefix('with-search'); - - if(!searchEnabled) { - $element.removeClass(rootElementClassName); - this._removeSearchBox(); - return; - } - - const editorOptions = this._getSearchEditorOptions(); - - if(this._searchEditor) { - this._searchEditor.option(editorOptions); - } else { - $element.addClass(rootElementClassName); - this._$searchEditorElement = $('
').addClass(searchBoxClassName).prependTo($element); - this._searchEditor = this._createComponent(this._$searchEditorElement, EditorClass, editorOptions); - } - }, - - _removeSearchBox: function() { - this._$searchEditorElement && this._$searchEditorElement.remove(); - delete this._$searchEditorElement; - delete this._searchEditor; - }, - - _getSearchEditorOptions: function() { - const that = this; - const userEditorOptions = that.option('searchEditorOptions'); - const searchText = messageLocalization.format('Search'); - - return extend({ - mode: 'search', - placeholder: searchText, - tabIndex: that.option('tabIndex'), - value: that.option('searchValue'), - valueChangeEvent: 'input', - inputAttr: { - 'aria-label': searchText - }, - onValueChanged: function(e) { - const searchTimeout = that.option('searchTimeout'); - that._valueChangeDeferred = new Deferred(); - clearTimeout(that._valueChangeTimeout); - - that._valueChangeDeferred.done(function() { - this.option('searchValue', e.value); - }.bind(that)); - - if(e.event && e.event.type === 'input' && searchTimeout) { - that._valueChangeTimeout = setTimeout(function() { - that._valueChangeDeferred.resolve(); - }, searchTimeout); - } else { - that._valueChangeDeferred.resolve(); - } - } - }, userEditorOptions); - }, - - _getAriaTarget: function() { - if(this.option('searchEnabled')) { - return this._itemContainer(true); - } - return this.callBase(); - }, - - _focusTarget: function() { - if(this.option('searchEnabled')) { - return this._itemContainer(true); - } - - return this.callBase(); - }, - - _updateFocusState: function(e, isFocused) { - if(this.option('searchEnabled')) { - this._toggleFocusClass(isFocused, this.$element()); - } - this.callBase(e, isFocused); - }, - - getOperationBySearchMode: function(searchMode) { - return searchMode === 'equals' ? '=' : searchMode; - }, - - _optionChanged: function(args) { - switch(args.name) { - case 'searchEnabled': - case 'searchEditorOptions': - this._invalidate(); - break; - case 'searchExpr': - case 'searchMode': - case 'searchValue': - if(!this._dataSource) { - errors.log('W1009'); - return; - } - if(args.name === 'searchMode') { - this._dataSource.searchOperation(this.getOperationBySearchMode(args.value)); - } else { - this._dataSource[args.name](args.value); - } - this._dataSource.load(); - break; - case 'searchTimeout': - break; - default: - this.callBase(args); - } - }, - - focus: function() { - if(!this.option('focusedElement') && this.option('searchEnabled')) { - this._searchEditor && this._searchEditor.focus(); - return; - } - - this.callBase(); - }, - - _cleanAria: function() { - const $element = this.$element(); - - this.setAria({ - 'role': null, - 'activedescendant': null - }, $element); - - $element.attr('tabIndex', null); - }, - - _clean() { - this.callBase(); - this._cleanAria(); - }, - - _refresh: function() { - if(this._valueChangeDeferred) { - this._valueChangeDeferred.resolve(); - } - - this.callBase(); - }, - - setEditorClass: function(value) { - EditorClass = value; - } -}; +export default SearchBoxMixin;