Текущая версия расширенного поиска диалога (см определение jqFilter
в grid.filter.js
) воссоздать все элементы управления диалогового окна на изменение кого-то. Смотрите код reDraw который выглядит
this.reDraw = function() {
$("table.group:first",this).remove();
var t = this.createTableForGroup(p.filter, null);
$(this).append(t);
if($.isFunction(this.p.afterRedraw)) {
this.p.afterRedraw.call(this, this.p);
}
};
Как можно увидеть в первой строке $("table.group:first",this).remove();
удалить содержимое всех фильтров. Текущий фокус будет потерян, и у вас есть проблемы, которые вы описали.
Я предлагаю, чтобы исправить код reDraw
используя document.activeElement элемент, который был введен в Internet Explorer изначально (по крайней мере, в IE4) и который поддерживается в настоящее время во всех браузерах, потому что это часть стандарта HTML5 (см here). Элемент, который имеет фокус изначально, будет уничтожен, и позже он не сможет сосредоточиться на нем. Поэтому я предлагаю сохранить имя элемента и его классы (например, input.add-group
или input.add-rule.ui-add
) и найти позицию элемента в диалоговом окне поиска. Позже, после того, как элемент диалога будет воссоздан, мы сосредоточим внимание на элементе с тем же индексом.
Я предлагаю, чтобы изменить код reDraw
к следующему
this.reDraw = function() {
var activeElement = document.activeElement, selector, $dialog, activeIndex = -1, $newElem, $buttons,
buttonClass,
getButtonClass = function (classNames) {
var arClasses = ['add-group', 'add-rule', 'delete-group', 'delete-rule'], i, n, className;
for (i = 0, n = classNames.length; i < n; i++) {
className = classNames[i];
if ($.inArray(className, arClasses) >= 0) {
return className;
}
}
return null;
};
if (activeElement) {
selector = activeElement.nodeName.toLowerCase();
buttonClass = getButtonClass(activeElement.className.split(' '));
if (buttonClass !== null) {
selector += '.' + buttonClass;
if (selector === "input.delete-rule") {
$buttons = $(activeElement).closest('table.group')
.find('input.add-rule,input.delete-rule');
activeIndex = $buttons.index(activeElement);
if (activeIndex > 0) {
// find the previous "add-rule" button
while (activeIndex--) {
$newElem = $($buttons[activeIndex]);
if ($newElem.hasClass("add-rule")) {
activeElement = $newElem[0];
selector = activeElement.nodeName.toLowerCase() + "." +
getButtonClass(activeElement.className.split(' '));
break;
}
}
}
} else if (selector === "input.delete-group") {
// change focus to "Add Rule" of the parent group
$newElem = $(activeElement).closest('table.group')
.parent()
.closest('table.group')
.find('input.add-rule');
if ($newElem.length > 1) {
activeElement = $newElem[$newElem.length-2];
selector = activeElement.nodeName.toLowerCase() + "." +
getButtonClass(activeElement.className.split(' '));
}
}
$dialog = $(activeElement).closest(".ui-jqdialog");
activeIndex = $dialog.find(selector).index(activeElement);
}
}
$("table.group:first",this).remove();
$(this).append(this.createTableForGroup(this.p.filter, null));
if($.isFunction(this.p.afterRedraw)) {
this.p.afterRedraw.call(this, this.p);
}
if (activeElement && activeIndex >=0) {
$newElem = $dialog.find(selector + ":eq(" + activeIndex + ")");
if ($newElem.length>0) {
$newElem.focus();
} else {
$dialog.find("input.add-rule:first").focus();
}
}
};
Как можно видеть на the next demo фокус в Зоркий Диалог остаются неизменными после нажатия на «Добавить подгруппу» или «Добавить правило» кнопки , Я установил его на кнопках «Добавить правило» предыдущей группы строк в случае нажатия «Удалить группу».
One more demo использование стиля jQuery UI кнопок и текстов в кнопках (см. the answer). После нажатия кнопки «Удалить» (правило или группа) я попытался установить фокус на предыдущую кнопку «Добавить правило», потому что настройка фокуса на другую кнопку «Удалить» (правило или группа) я считаю опасной.
Кроме того, в демо-версии я использую
afterShowSearch: function ($form) {
var $lastInput = $form.find(".input-elm:last");
if ($lastInput.length > 0) {
$lastInput.focus();
}
}
, потому что кажется мне смысл установить первоначальный фокус на последнее поле ввода в диалоговом окне открытия.
ОБНОВЛЕНО: Я нахожу еще более значимым, чтобы установить фокус на текущие кнопки «Добавить подгруппу», «Добавить правило» или «Удалить группу». Преимущество, которое вы видите в случае, когда оно сначала нажимает на кнопку с помощью мыши, а затем хочет продолжить работу с клавиатурой.Поэтому я предлагаю, чтобы изменить the line
inputAddSubgroup.bind('click',function() {
в
inputAddSubgroup.bind('click',function(e) {
$(e.target).focus();
Чтобы изменить the line
inputAddRule.bind('click',function() {
в
inputAddRule.bind('click',function(e) {
$(e.target).focus();
и the line
inputDeleteGroup.bind('click',function() {
в
inputDeleteGroup.bind('click',function(e) {
$(e.target).focus();
и the line
ruleDeleteInput.bind('click',function() {
в
ruleDeleteInput.bind('click',function(e) {
$(e.target).focus();
Я попробовал эти изменения с afterRedraw кода из другого ответа, который применяется кнопка jQuieryUI() для диалоговых кнопок , В этом случае кнопка не получает фокус, а клавиши клавиатуры по-прежнему игнорируются после нажатия кнопки – Andrus
@ Andrus: я обновил код еще раз (см. Выше). Новая демонстрация [здесь] (http://www.ok-soft-gmbh.com/jqGrid/SearchOnEnter3.htm). – Oleg
Thak you, он работает. Я попытался с вертикальной полосой прокрутки тела отключен. После нажатия кнопки «Добавить кнопки» несколько раз высота диалога увеличивается с экрана (вертикальная полоса прокрутки не отображается в диалоговом окне). Также после нажатия кнопки «Добавить правило» в IE9, если указатель мыши зависает над кнопкой «Добавить роль», высота диалога увеличивается при каждом наведении. Я думаю, мы исправили это для формы редактирования (я предусмотрел тогда тест для этого в другом вопросе). – Andrus