diff --git a/apps/common/main/lib/component/ComboBox.js b/apps/common/main/lib/component/ComboBox.js
index 78a7b0a22..abb993cd1 100644
--- a/apps/common/main/lib/component/ComboBox.js
+++ b/apps/common/main/lib/component/ComboBox.js
@@ -86,7 +86,8 @@ define([
displayField: 'displayValue',
valueField : 'value',
search : false,
- scrollAlwaysVisible: false
+ scrollAlwaysVisible: false,
+ takeFocusOnClose: false
},
template: _.template([
@@ -340,6 +341,10 @@ define([
this.cmpEl.find('.dropdown-toggle').blur();
this.trigger('hide:after', this, e, isFromInputControl);
Common.NotificationCenter.trigger('menu:hide', this, isFromInputControl);
+ if (this.options.takeFocusOnClose) {
+ var me = this;
+ setTimeout(function(){me._input.focus();}, 1);
+ }
},
onAfterKeydownMenu: function(e) {
diff --git a/apps/common/main/lib/component/DataView.js b/apps/common/main/lib/component/DataView.js
index 723389239..855f52d0f 100644
--- a/apps/common/main/lib/component/DataView.js
+++ b/apps/common/main/lib/component/DataView.js
@@ -242,6 +242,7 @@ define([
me.listenStoreEvents= (me.options.listenStoreEvents!==undefined) ? me.options.listenStoreEvents : true;
me.allowScrollbar = (me.options.allowScrollbar!==undefined) ? me.options.allowScrollbar : true;
me.scrollAlwaysVisible = me.options.scrollAlwaysVisible || false;
+ me.tabindex = me.options.tabindex || 0;
if (me.parentMenu)
me.parentMenu.options.restoreHeight = (me.options.restoreHeight>0);
me.rendered = false;
@@ -678,7 +679,7 @@ define([
if (this.enableKeyEvents && this.handleSelect) {
var el = $(this.el).find('.inner').addBack().filter('.inner');
el.addClass('canfocused');
- el.attr('tabindex', '0');
+ el.attr('tabindex', this.tabindex.toString());
el.on((this.parentMenu && this.useBSKeydown) ? 'dataview:keydown' : 'keydown', _.bind(this.onKeyDown, this));
}
},
@@ -1120,7 +1121,7 @@ define([
if (this.enableKeyEvents && this.handleSelect) {
var el = $(this.el).find('.inner').addBack().filter('.inner');
el.addClass('canfocused');
- el.attr('tabindex', '0');
+ el.attr('tabindex', this.tabindex.toString());
el.on((this.parentMenu && this.useBSKeydown) ? 'dataview:keydown' : 'keydown', _.bind(this.onKeyDown, this));
}
},
diff --git a/apps/common/main/lib/component/FocusManager.js b/apps/common/main/lib/component/FocusManager.js
new file mode 100644
index 000000000..877dd445b
--- /dev/null
+++ b/apps/common/main/lib/component/FocusManager.js
@@ -0,0 +1,130 @@
+/*
+ *
+ * (c) Copyright Ascensio System SIA 2010-2020
+ *
+ * This program is a free software product. You can redistribute it and/or
+ * modify it under the terms of the GNU Affero General Public License (AGPL)
+ * version 3 as published by the Free Software Foundation. In accordance with
+ * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect
+ * that Ascensio System SIA expressly excludes the warranty of non-infringement
+ * of any third-party rights.
+ *
+ * This program is distributed WITHOUT ANY WARRANTY; without even the implied
+ * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For
+ * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html
+ *
+ * You can contact Ascensio System SIA at 20A-12 Ernesta Birznieka-Upisha
+ * street, Riga, Latvia, EU, LV-1050.
+ *
+ * The interactive user interfaces in modified source and object code versions
+ * of the Program must display Appropriate Legal Notices, as required under
+ * Section 5 of the GNU AGPL version 3.
+ *
+ * Pursuant to Section 7(b) of the License you must retain the original Product
+ * logo when distributing the program. Pursuant to Section 7(e) we decline to
+ * grant you any rights under trademark law for use of our trademarks.
+ *
+ * All the Product's GUI elements, including illustrations and icon sets, as
+ * well as technical writing content are licensed under the terms of the
+ * Creative Commons Attribution-ShareAlike 4.0 International. See the License
+ * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode
+ *
+ */
+/**
+ * FocusManager.js
+ *
+ * Created by Julia Radzhabova on 24.09.2020
+ * Copyright (c) 2020 Ascensio System SIA. All rights reserved.
+ *
+ */
+
+
+if (Common === undefined)
+ var Common = {};
+
+if (Common.UI === undefined) {
+ Common.UI = {};
+}
+
+Common.UI.FocusManager = function (tabindex, parent) {
+ var register = function(fields, options, tabindex) {
+ var arr = [],
+ selector,
+ el;
+ if (typeof options==='string') {
+ selector = options;
+ } else {
+ el = options;
+ }
+ if (!fields.forEach) {
+ fields = [fields];
+ if (el)
+ el = [el];
+ }
+
+ fields.forEach(function(cmp, index) {
+ var elem = selector ? (cmp.$el || $(cmp.el)).find(selector) : (el && el[index] ? el[index] : cmp);
+ elem && elem.attr && elem.attr('tabindex', tabindex.toString());
+ arr.push({
+ cmp: cmp,
+ el: elem,
+ selector: selector
+ });
+ });
+ return arr;
+ };
+
+ return {
+ tabindex: tabindex || 0,
+ parent: parent,
+ fields: [],
+
+ add: function(fields, options) { // options may be selector or component.el
+ this.fields = this.fields.concat(register(fields, options, this.tabindex));
+ !this.trapFirst && this.addTraps();
+ },
+
+ insert: function(field, index, options) {
+ this.fields.splice(index, 0, register(field, options, this.tabindex));
+ },
+
+ remove: function(index) {
+ this.fields.splice(index, 1);
+ },
+
+ addTraps: function() {
+ if (!this.parent || !this.parent.$window) return;
+
+ var me = this;
+ this.trapFirst = $('');
+ this.trapFirst.on('focus', function() {
+ for (var i=0; i');
+ this.trapLast.on('focus', function() {
+ for (var i=me.fields.length-1; i>=0; i--) {
+ var field = me.fields[i];
+ if (field.cmp.isVisible ? field.cmp.isVisible() : field.cmp.is(':visible')) {
+ var el = (field.selector) ? (field.cmp.$el || $(field.cmp.el)).find(field.selector) : field.el;
+ el.focus();
+ break;
+ }
+ }
+ });
+ this.parent.$window.append(this.trapLast);
+ },
+
+ setTabIndex: function (tabindex) {
+ this.tabindex = tabindex;
+ }
+ }
+};
diff --git a/apps/common/main/lib/component/Window.js b/apps/common/main/lib/component/Window.js
index cc4020a78..63caa522f 100644
--- a/apps/common/main/lib/component/Window.js
+++ b/apps/common/main/lib/component/Window.js
@@ -137,7 +137,8 @@
define([
'common/main/lib/component/BaseView',
- 'common/main/lib/component/CheckBox'
+ 'common/main/lib/component/CheckBox',
+ 'common/main/lib/component/FocusManager'
], function () {
'use strict';
@@ -612,6 +613,9 @@ define([
!this.initConfig.id && (this.initConfig.id = 'window-' + this.cid);
!this.initConfig.tpl && (this.initConfig.tpl = '');
+ if (options.focusManager)
+ this.focusManager = Common.UI.FocusManager(1, this);
+
Common.UI.BaseView.prototype.initialize.call(this, this.initConfig);
},
diff --git a/apps/spreadsheeteditor/main/app/view/ChartDataRangeDialog.js b/apps/spreadsheeteditor/main/app/view/ChartDataRangeDialog.js
index 8fe5b5db2..f0d1736d2 100644
--- a/apps/spreadsheeteditor/main/app/view/ChartDataRangeDialog.js
+++ b/apps/spreadsheeteditor/main/app/view/ChartDataRangeDialog.js
@@ -52,7 +52,8 @@ define([
type: 0, // 0 - category, 1 - series
width : 350,
cls : 'modal-dlg',
- buttons: ['ok', 'cancel']
+ buttons: ['ok', 'cancel'],
+ focusManager: true
},
initialize : function(options) {
@@ -171,9 +172,10 @@ define([
$window.find('.dlg-btn').on('click', _.bind(this.onBtnClick, this));
- _.defer(function(){
- me.inputRange1.cmpEl.find('input').focus();
- }, 10);
+ this.focusManager.add([me.inputRange1, me.inputRange2, me.inputRange3], '.form-control');
+ setTimeout(function(){
+ me.inputRange1.cmpEl.find('input').focus();
+ }, 10);
},
onPrimary: function() {
diff --git a/apps/spreadsheeteditor/main/app/view/FormatSettingsDialog.js b/apps/spreadsheeteditor/main/app/view/FormatSettingsDialog.js
index 6b8e66c2b..c1e6e125c 100644
--- a/apps/spreadsheeteditor/main/app/view/FormatSettingsDialog.js
+++ b/apps/spreadsheeteditor/main/app/view/FormatSettingsDialog.js
@@ -49,7 +49,8 @@ define([
SSE.Views.FormatSettingsDialog = Common.Views.AdvancedSettingsWindow.extend(_.extend({
options: {
contentWidth: 284,
- height: 340
+ height: 340,
+ focusManager: true
},
initialize : function(options) {
@@ -171,7 +172,8 @@ define([
cls: 'input-group-nr',
menuStyle: 'min-width: 264px;',
editable: false,
- data: this.numFormatData
+ data: this.numFormatData,
+ takeFocusOnClose: true
});
this.cmbFormat.setValue(this.FormatType);
this.cmbFormat.on('selected', _.bind(this.onFormatSelect, this));
@@ -182,7 +184,8 @@ define([
menuStyle: 'min-width: 264px;max-height:235px;',
editable: false,
data: [],
- scrollAlwaysVisible: true
+ scrollAlwaysVisible: true,
+ takeFocusOnClose: true
});
this.cmbNegative.on('selected', _.bind(this.onNegativeSelect, this));
@@ -210,7 +213,8 @@ define([
menuStyle: 'min-width: 264px;max-height:235px;',
editable: false,
data: [],
- scrollAlwaysVisible: true
+ scrollAlwaysVisible: true,
+ takeFocusOnClose: true
});
this.cmbSymbols.on('selected', _.bind(this.onSymbolsSelect, this));
@@ -220,7 +224,8 @@ define([
menuStyle: 'min-width: 264px;max-height:235px;',
editable: false,
data: [],
- scrollAlwaysVisible: true
+ scrollAlwaysVisible: true,
+ takeFocusOnClose: true
});
this.cmbType.on('selected', _.bind(this.onTypeSelect, this));
@@ -230,7 +235,8 @@ define([
menuStyle: 'min-width: 310px;max-height:235px;',
editable: false,
data: [],
- scrollAlwaysVisible: true
+ scrollAlwaysVisible: true,
+ takeFocusOnClose: true
});
this.cmbCode.on('selected', _.bind(this.onCodeSelect, this));
@@ -243,11 +249,17 @@ define([
this.lblExample = this.$window.find('#format-settings-label-example');
+ this.focusManager.add([this.cmbFormat, this.spnDecimal, this.cmbSymbols, this.cmbNegative, this.cmbType, this.cmbCode], '.form-control');
+
this.afterRender();
},
afterRender: function() {
this._setDefaults(this.props);
+ var cmp = this.cmbFormat;
+ setTimeout(function(){
+ (cmp.$el || $(cmp.el)).find('.form-control').focus();
+ }, 10);
},
show: function() {
@@ -489,7 +501,7 @@ define([
this.lblExample.text(this.api.asc_getLocaleExample(this.Format));
this._decimalPanel.toggleClass('hidden', !hasDecimal);
- this._negativePanel.css('visibility', hasNegative ? '' : 'hidden');
+ this._negativePanel.toggleClass('hidden', !hasNegative);
this._separatorPanel.toggleClass('hidden', !hasSeparator);
this._typePanel.toggleClass('hidden', !hasType);
this._symbolsPanel.toggleClass('hidden', !hasSymbols);
diff --git a/apps/spreadsheeteditor/main/app/view/FormulaDialog.js b/apps/spreadsheeteditor/main/app/view/FormulaDialog.js
index d5991d3be..44c10a850 100644
--- a/apps/spreadsheeteditor/main/app/view/FormulaDialog.js
+++ b/apps/spreadsheeteditor/main/app/view/FormulaDialog.js
@@ -63,7 +63,8 @@ define([
contentTemplate : '',
title : t.txtTitle,
items : [],
- buttons: null
+ buttons: null,
+ focusManager: true
}, options);
this.template = options.template || [
@@ -114,6 +115,7 @@ define([
}
me.filterFormulas();
});
+ this.focusManager.add(this.inputSearch._input);
this.btnOk = new Common.UI.Button({
el: $('#formula-dlg-btn-ok')
@@ -149,9 +151,10 @@ define([
if (this.cmbListFunctions) {
this.inputSearch.setValue('');
- _.delay(function (me) {
+ var me = this;
+ setTimeout(function () {
me.inputSearch.$el.find('input').focus();
- }, 100, this);
+ }, 100);
}
this._preventCloseCellEditor = false;
},
@@ -242,10 +245,11 @@ define([
menuStyle : 'min-width: 100%;',
cls : 'input-group-nr',
data : groupsListItems,
- editable : false
+ editable : false,
+ takeFocusOnClose: true
});
-
this.cmbFuncGroup.on('selected', _.bind(this.onSelectGroup, this));
+ this.focusManager.add(this.cmbFuncGroup, '.form-control');
} else {
this.cmbFuncGroup.setData(groupsListItems);
}
@@ -266,6 +270,7 @@ define([
this.cmbListFunctions = new Common.UI.ListView({
el: $('#formula-dlg-combo-functions'),
store: this.functions,
+ tabindex: 1,
itemTemplate: _.template('<%= value %>
')
});
@@ -275,6 +280,8 @@ define([
this.cmbListFunctions.onKeyDown = _.bind(this.onKeyDown, this.cmbListFunctions);
this.cmbListFunctions.scrollToRecord = _.bind(this.onScrollToRecordCustom, this.cmbListFunctions);
this.onUpdateFocus();
+
+ this.focusManager.add(this.cmbListFunctions, '.listview');
}
if (this.functions) {
diff --git a/apps/spreadsheeteditor/main/app/view/FormulaWizard.js b/apps/spreadsheeteditor/main/app/view/FormulaWizard.js
index 264f4ffe4..fe22a0818 100644
--- a/apps/spreadsheeteditor/main/app/view/FormulaWizard.js
+++ b/apps/spreadsheeteditor/main/app/view/FormulaWizard.js
@@ -46,7 +46,8 @@ define([
SSE.Views.FormulaWizard = Common.Views.AdvancedSettingsWindow.extend(_.extend({
options: {
contentWidth: 580,
- height: 397
+ height: 397,
+ focusManager: true
},
initialize : function(options) {
@@ -281,6 +282,8 @@ define([
else
me.args[argcount].lblName.html(me.args[argcount].argName);
me.args[argcount].lblValue.html('= '+ ( argres!==null && argres!==undefined ? argres : '' + me.args[argcount].argTypeName + ''));
+
+ this.focusManager.add(txt._input);
},
onInputChanging: function(input, newValue, oldValue, e) {
diff --git a/apps/spreadsheeteditor/main/app/view/PageMarginsDialog.js b/apps/spreadsheeteditor/main/app/view/PageMarginsDialog.js
index f2a739b10..226c55e42 100644
--- a/apps/spreadsheeteditor/main/app/view/PageMarginsDialog.js
+++ b/apps/spreadsheeteditor/main/app/view/PageMarginsDialog.js
@@ -50,7 +50,8 @@ define([
style: 'min-width: 216px;',
cls: 'modal-dlg',
id: 'window-page-margins',
- buttons: ['ok', 'cancel']
+ buttons: ['ok', 'cancel'],
+ focusManager: true
},
initialize : function(options) {
@@ -146,6 +147,12 @@ define([
$window.find('.dlg-btn').on('click', _.bind(this.onBtnClick, this));
$window.find('input').on('keypress', _.bind(this.onKeyPress, this));
+ this.focusManager.add(this.spinners, '.form-control');
+ var cmp = this.spnTop;
+ setTimeout(function(){
+ (cmp.$el || $(cmp.el)).find('.form-control').focus();
+ }, 10);
+
this.updateMetricUnit();
},