Запретить диалогу jQuery UI устанавливать фокус на первое текстовое поле - PullRequest
150 голосов
/ 29 июля 2009

Я установил модальное диалоговое окно jQuery UI, которое отображается, когда пользователь нажимает на ссылку. В этом теге div диалога есть два текстовых поля (для краткости я показываю только код 1), и оно заменено текстовым полем jQuery UI DatePicker, которое реагирует на фокус.

Проблема в том, что диалоговое окно jQuery UI («open») каким-то образом вызывает фокусировку в первом текстовом поле, а затем немедленно запускает календарь средства выбора даты.

Поэтому я ищу способ предотвратить автоматическую фокусировку.

<div><a id="lnkAddReservation" href="#">Add reservation</a></div>

<div id="divNewReservation" style="display:none" title="Add reservation">
    <table>
        <tr>
            <th><asp:Label AssociatedControlID="txtStartDate" runat="server" Text="Start date" /></th>
            <td>
                <asp:TextBox ID="txtStartDate" runat="server" CssClass="datepicker" />
            </td>
        </tr>
    </table>

    <div>
        <asp:Button ID="btnAddReservation" runat="server" OnClick="btnAddReservation_Click" Text="Add reservation" />
    </div>
</div>

<script type="text/javascript">
    $(document).ready(function() {
        var dlg = $('#divNewReservation');
        $('.datepicker').datepicker({ duration: '' });
        dlg.dialog({ autoOpen:false, modal: true, width:400 });
        $('#lnkAddReservation').click(function() { dlg.dialog('open'); return false; });
        dlg.parent().appendTo(jQuery("form:first"));
    });
</script>

Ответы [ 30 ]

77 голосов
/ 27 января 2011

jQuery UI 1.10.0 Журнал изменений списки тикет 4731 как исправленные.

Похоже, что focusSelector не был реализован, но вместо этого использовался каскадный поиск различных элементов. Из билета:

Расширение автофокуса, начиная с [автофокус], затем: содержимое с вкладками, затем панель кнопок, затем кнопка закрытия, затем диалоговое окно

Итак, отметьте элемент с атрибутом autofocus, и именно этот элемент должен получить фокус:

<input autofocus>

В документации объясняется логика фокуса (непосредственно под оглавлением, под заголовком "Фокус"):

При открытии диалога фокус автоматически перемещается на первый элемент что соответствует следующему:

  1. Первый элемент в диалоге с атрибутом autofocus
  2. Первый :tabbable элемент в содержимом диалога
  3. Первый :tabbable элемент в панели кнопок диалога
  4. Кнопка закрытия диалогового окна
  5. Сам диалог
72 голосов
/ 05 мая 2012

Добавьте скрытый диапазон над ним, используйте ui-helper-hidden-available, чтобы сделать его скрытым путем абсолютного позиционирования. Я знаю, что у вас есть этот класс, потому что вы используете диалог из jquery-ui, а он в jquery-ui.

<span class="ui-helper-hidden-accessible"><input type="text"/></span>
59 голосов
/ 21 апреля 2013

В jQuery UI> = 1.10.2 вы можете заменить метод-прототип _focusTabbable на функцию плацебо:

$.ui.dialog.prototype._focusTabbable = $.noop;

Fiddle

Это повлияет на все dialog с на странице без необходимости редактировать каждый вручную.

Исходная функция не делает ничего, кроме установки фокуса на первый элемент с атрибутом autofocus / tabbable element / или возврата к самому диалогу. Так как он используется только для установки фокуса на элементе, не должно быть проблем с заменой его на noop.

28 голосов
/ 29 июля 2009

Я обнаружил следующий код диалоговой функции jQuery UI для открытия.

c([]).add(d.find(".ui-dialog-content :tabbable:first")).add(d.find(".ui-dialog-buttonpane :tabbable:first")).add(d).filter(":first").focus();

Вы можете либо обойти поведение jQuery, либо изменить поведение.

tabindex -1 работает как обходной путь.

27 голосов
/ 07 февраля 2013

Начиная с jQuery UI 1.10.0, вы можете выбрать на какой элемент ввода фокусироваться, используя атрибут HTML5 автофокус .

Все, что вам нужно сделать, это создать фиктивный элемент в качестве первого ввода в диалоговом окне. Он поглотит фокус для вас.

<input type="hidden" autofocus="autofocus" />

Это было проверено в Chrome, Firefox и Internet Explorer (все последние версии) 7 февраля 2013 г.

http://jqueryui.com/upgrade-guide/1.10/#added-ability-to-specify-which-element-to-focus-on-open

13 голосов
/ 18 июля 2014

Просто понял это во время игры.

Я обнаружил, что с этими решениями для удаления фокуса, клавиша ESC перестала работать (т.е. закрывать диалог) при первом входе в диалог.

Если диалоговое окно открывается и вы сразу нажимаете ESC , оно не закрывает диалоговое окно (если оно включено), потому что фокус находится на каком-то скрытом поле или чем-то еще, и оно не получает события нажатия клавиш.

Я исправил это, добавив это к событию open, чтобы вместо этого убрать фокус из первого поля:

$('#myDialog').dialog({
    open: function(event,ui) {
        $(this).parent().focus();
    }
});

Устанавливает фокус на диалоговое окно, которое не отображается, и затем работает клавиша ESC .

10 голосов
/ 29 июля 2009

Установите tabindex для ввода равным -1, а затем установите dialog.open для восстановления tabindex, если он понадобится позже:

$(function() {
    $( "#dialog-message" ).dialog({
        modal: true,
        width: 500,
        autoOpen: false,
        resizable: false,
        open: function()
        {
            $( "#datepicker1" ).attr("tabindex","1");
            $( "#datepicker2" ).attr("tabindex","2");
        }
    });
});
10 голосов
/ 22 марта 2011

Мой обходной путь:

open: function(){
  jQuery('input:first').blur();
  jQuery('#ui-datepicker-div').hide();
},  
7 голосов
/ 08 июля 2011

Простой обходной путь:

Просто создайте невидимый элемент с tabindex = 1 ... Это не будет фокусировать средство выбора даты ...

например:.

<a href="" tabindex="1"></a>
...
Here comes the input element
7 голосов
/ 10 августа 2010

У меня был контент, который был длиннее, чем диалог. При открытии диалоговое окно переходит к первому: вкладка, которая находится внизу. Вот мое исправление.

$("#myDialog").dialog({
   ...
   open: function(event, ui) { $(this).scrollTop(0); }
});
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...