Запретить диалогу пользовательского интерфейса jQuery установить фокус на первое текстовое поле

Я установил модальный диалог jQuery UI для отображения, когда пользователь нажимает ссылку. Есть два текстовых поля (я только показываю код для 1 для краткости) в этом теге div div и он изменен как текстовое поле 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>

Ответ 1

jQuery UI 1.10.0 Список изменений содержит билет 4731 как фиксированный.

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

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

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

<input autofocus>

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

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

  • Первый элемент в диалоге с атрибутом autofocus
  • Первый элемент :tabbable в содержимом диалога
  • Первый элемент :tabbable в панели кнопок диалога
  • Кнопка закрытия диалогового окна
  • Сам диалог

Ответ 2

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

<span class="ui-helper-hidden-accessible"><input type="text"/></span>

Ответ 3

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

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

Fiddle

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

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

Ответ 4

Я нашел следующий код для функции диалога 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 работает как обходной путь.

Ответ 5

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

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

<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

Ответ 6

Просто подумал об этом во время игры.

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

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

Как я исправил это, нужно добавить это в открытое событие, чтобы удалить фокус из первого поля:

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

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

Ответ 7

Установите 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");
        }
    });
});

Ответ 8

Мое обходное решение:

open: function(){
  jQuery('input:first').blur();
  jQuery('#ui-datepicker-div').hide();
},  

Ответ 9

Простой способ:

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

например:.

<a href="" tabindex="1"></a>
...
Here comes the input element

Ответ 10

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

$("#myDialog").dialog({
   ...
   open: function(event, ui) { $(this).scrollTop(0); }
});

Ответ 11

Вот решение, которое я реализовал после прочтения jQuery UI ticket # 4731, первоначально отправленного slolife в ответ на другой ответ. (Билет также был создан им.)

Во-первых, в любом методе, который вы используете для применения автозаполнения к странице, добавьте следующую строку кода:

$.ui.dialog.prototype._focusTabbable = function(){};

Это отключает поведение "автофокусировки" jQuery. Чтобы ваш сайт по-прежнему был широкодоступным, оберните методы создания диалога, чтобы добавить дополнительный код и добавьте вызов для фокусировки первого элемента ввода:

function openDialog(context) {

    // Open your dialog here

    // Usability for screen readers.  Focus on an element so that screen readers report it.
    $("input:first", $(context)).focus();

}

Для дальнейшего доступа к доступности, когда параметры автозаполнения выбраны с клавиатуры, мы переопределяем jQuery UI "выберите" автозавершение обратного вызова и добавим дополнительный код, чтобы гарантировать, что textElement не потеряет фокус в IE 8 после выбора.

Вот код, который мы используем для применения автозаполнения к элементам:

$.fn.applyAutocomplete = function () {

    // Prevents jQuery dialog from auto-focusing on the first tabbable element.
    // Make sure to wrap your dialog opens and focus on the first input element
    // for screen readers.
    $.ui.dialog.prototype._focusTabbable = function () { };

    $(".autocomplete", this)
        .each(function (index) {

            var textElement = this;

            var onSelect = $(this).autocomplete("option", "select");
            $(this).autocomplete("option", {
                select: function (event, ui) {
                    // Call the original functionality first
                    onSelect(event, ui);

                    // We replace a lot of content via AJAX in our project.
                    // This ensures proper copying of values if the original element which jQuery UI pointed to
                    // is replaced.
                    var $hiddenValueElement = $("#" + $(textElement).attr('data-jqui-acomp-hiddenvalue'));
                    if ($hiddenValueElement.attr("value") != ui.item.value) {
                        $hiddenValueElement.attr("value", ui.item.value);
                    }

                    // Replace text element value with that indicated by "display" if any
                    if (ui.item.display)
                        textElement.value = ui.item.display;

                    // For usability purposes.  When using the keyboard to select from an autocomplete, this returns focus to the textElement.
                    $(textElement).focus();

                    if (ui.item.display)
                        return false;

                }
            });
        })
        // Set/clear data flag that can be checked, if necessary, to determine whether list is currently dropped down
        .on("autocompleteopen", function (event, ui) {
            $(event.target).data().autocompleteIsDroppedDown = true;
        })
        .on("autocompleteclose", function (event, ui) {
            $(event.target).data().autocompleteIsDroppedDown = false;
        });

    return this;
}

Ответ 12

Это может быть поведение браузера, а не плагин jQuery. Вы пытались удалить фокус программно после открытия всплывающего окна.

$('#lnkAddReservation').click(function () {
    dlg.dialog('open');

    // you may want to change the selector below
    $('input,textarea,select').blur();

    return false;
});

Не тестировали, но должны работать нормально.

Ответ 13

У меня была бы такая же проблема и ее решить, вставив пустой файл перед datepicker, который крадет фокус каждый раз, когда открывается диалог. Этот ввод скрывается при каждом открытии диалога и отображается снова при закрытии.

Ответ 14

Ну, здорово, что на данный момент никто не нашел решение, но похоже, что у меня есть что-то для вас. Плохая новость заключается в том, что диалог захватывает фокус в любом случае, даже если входы и ссылки не находятся внутри. Я использую диалог в качестве всплывающей подсказки и обязательно нуждаюсь в фокусе пребывания в исходном элементе. Вот мое решение:

использовать опцию [autoOpen: false]

$toolTip.dialog("widget").css("visibility", "hidden"); 
$toolTip.dialog("open");
$toolTip.dialog("widget").css("visibility", "visible");

Пока диалог невидим, фокус не устанавливается нигде и остается в исходном месте. Он работает со всплывающими подсказками только с простым текстом, но не проверен для более функциональных диалогов, где может быть важно иметь диалог, видимый в момент открытия. Вероятно, все будет нормально работать.

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

Протестировано в IE, FF и Chrome.

Надеюсь, это поможет кому-то.

Ответ 16

У меня аналогичная проблема. Я открываю диалоговое окно с ошибкой, когда проверка не выполняется, и она захватывает фокус, точно так же, как Flugan показывает это в ответе . Проблема в том, что даже если ни один элемент внутри диалогового окна не является tabbable, само диалоговое окно все еще сфокусировано. Вот исходный unminified код из jquery-ui-1.8.23\js\jquery.ui.dialog.js:

// set focus to the first tabbable element in the content area or the first button
// if there are no tabbable elements, set focus on the dialog itself
$(self.element.find(':tabbable').get().concat(
  uiDialog.find('.ui-dialog-buttonpane :tabbable').get().concat(
    uiDialog.get()))).eq(0).focus();

Комментарий у них!

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

Я обнаружил, что следующее обходное решение работает очень хорошо для меня:

jqueryFocus = $.fn.focus;
$.fn.focus = function (delay, fn) {
  jqueryFocus.apply(this.filter(':not(.ui-dialog)'), arguments);
};

Ответ 17

Я искал другую проблему, но по той же причине. Проблема в том, что в диалоговом окне основное внимание уделяется первому найденному <a href="">.</a>. Поэтому, если у вас много текста в вашем диалоговом окне и появляются полосы прокрутки, у вас может быть ситуация, когда полоса прокрутки будет прокручиваться вниз. Я считаю, что это также исправляет вопрос о первых лицах. Хотя другие делают тоже.

Простая для понимания проблема. <a id="someid" href="#">.</a> в качестве первой строки в диалоговом окне div.

Пример:

 <div id="dialogdiv" title="some title">
    <a id="someid" href="#">.</a>
    <p>
        //the rest of your stuff
    </p>
</div>

Когда инициировано ваше диалоговое окно

$(somediv).dialog({
        modal: true,
        open: function () { $("#someid").hide(); otherstuff or function },
        close: function () { $("#someid").show(); otherstuff or function }
    });

Вышеупомянутое не будет иметь ничего сфокусированного, и полосы прокрутки останутся наверху, где он принадлежит. <a> получает фокус, но затем скрывается. Таким образом, общий эффект - желаемый эффект.

Я знаю, что это старый поток, но, как и в пользовательском интерфейсе, нет никакого исправления. Это не требует размытия или фокусировки. Не уверен, что это самый элегантный. Но это просто понятно и легко объяснить кому-либо.

Ответ 18

Если у вас есть только одно поле в форме диалогового окна JQuery, и ему нужен Datepicker, вы можете просто установить фокус на диалог Закрыть (крест) в строке заголовка диалога:

$('.ui-dialog-titlebar-close').focus();

Вызвать этот диалог ПОСЛЕ инициализации, например:

$('#yourDialogId').dialog();
$('.ui-dialog-titlebar-close').focus();

Поскольку кнопка закрытия отображается после вызова .dialog().

Ответ 19

Если вы используете диалоговые кнопки, просто установите атрибут autofocus на одну из кнопок:

$('#dialog').dialog({
  buttons: [
    {
      text: 'OK',
      autofocus: 'autofocus'
    },
    {
      text: 'Cancel'
    }
  ]
});
<script src="https://code.jquery.com/jquery-1.12.4.min.js"></script>
<script src="https://code.jquery.com/ui/1.11.4/jquery-ui.min.js"></script>
<link href="https://code.jquery.com/ui/1.11.4/themes/smoothness/jquery-ui.css" rel="stylesheet"/>

<div id="dialog" title="Basic dialog">
  This is some text.
  <br/>
  <a href="www.google.com">This is a link.</a>
  <br/>
  <input value="This is a textbox.">
</div>

Ответ 20

Вы можете указать эту опцию, чтобы вместо этого нажать кнопку закрытия.

.dialog({
      open: function () {
              $(".ui-dialog-titlebar-close").focus();
            }
   });

Ответ 21

У меня такая же проблема.

Обходной путь, который я сделал, - добавить текстовое поле в верхней части диалогового контейнера.

<input type="text" style="width: 1px; height: 1px; border: 0px;" />

Ответ 22

Как уже упоминалось, это известная ошибка с пользовательским интерфейсом jQuery и должна быть исправлена ​​относительно скоро. До тех пор...

Вот еще один вариант, поэтому вам не нужно связываться с tabindex:

Отключить datepicker временно, пока не откроется диалоговое окно:

dialog.find(".datepicker").datepicker("disable");
dialog.dialog({
    "open": function() {$(this).find(".datepicker").datepicker("enable");},
});

Работает для меня.

Дублирующий вопрос: Как размыть ввод первой формы при открытии диалога

Ответ 23

Чтобы расширить некоторые предыдущие ответы (и игнорировать вспомогательный аспект даты), если вы хотите, чтобы событие focus() не фокусировалось на первом поле ввода при открытии диалога, попробуйте следующее:

$('#myDialog').dialog(
    { 'open': function() { $('input:first-child', $(this)).blur(); }
});

Ответ 24

У меня была аналогичная проблема и она была решена путем фокусировки на диалоговом окне после открытия:

var $dialog = $("#pnlFiltros")
    .dialog({
        autoOpen: false,
        hide: "puff",                   
        width: dWidth,
        height: 'auto',
        draggable: true,
        resizable: true,
        closeOnScape : true,
        position: [x,y]                    
    });
$dialog.dialog('open');
$("#pnlFiltros").focus(); //focus on the div being dialogued (is that a word?)

Но в моем случае первый элемент является якорем, поэтому я не знаю, откроется ли в вашем случае, что датпикер будет открыт.

EDIT: работает только с IE

Ответ 25

найти в jquery.ui.js

d.find(".ui-dialog-buttonpane :tabbable").get().concat(d.get()))).eq(0).focus(); 

и замените на

d.find(".ui-dialog-buttonpane :tabbable").get().concat(d.get()))).eq(-1).focus();

Ответ 26

jQuery 1.9 выпущен и, похоже, не исправлено. Попытка предотвратить фокусировку первого текстового поля некоторыми из предложенных методов не работает в 1.9. Я думаю, что если методы попытаются размыть фокус или переместить фокус, ПОСЛЕ того, как текстовое поле в диалоговом окне уже приобрело фокус и проделало свою грязную работу.

Я не вижу ничего в документации API, которая заставляет меня думать, что что-то изменилось с точки зрения ожидаемой функциональности. Выкл., Чтобы добавить открывающую кнопку...

Ответ 27

У меня была аналогичная проблема. На моей первой странице ввода находится текстовое поле с календарем пользовательского интерфейса jQuery. Второй элемент - это кнопка. Поскольку дата уже имеет значение, я устанавливаю фокус на кнопку, но сначала добавляю триггер для размытия в текстовом поле. Эта проблема разрешима во всех браузерах и, вероятно, во всех версиях jQuery. Протестировано в версии 1.8.2.

<div style="padding-bottom: 30px; height: 40px; width: 100%;">
@using (Html.BeginForm("Statistics", "Admin", FormMethod.Post, new { id = "FormStatistics" }))
{
    <label style="float: left;">@Translation.StatisticsChooseDate</label>
    @Html.TextBoxFor(m => m.SelectDate, new { @class = "js-date-time",  @tabindex=1 })
    <input class="button gray-button button-large button-left-margin text-bold" style="position:relative; top:-5px;" type="submit" id="ButtonStatisticsSearchTrips" value="@Translation.StatisticsSearchTrips"  tabindex="2"/>
}

<script type="text/javascript">
$(document).ready(function () {        
    $("#SelectDate").blur(function () {
        $("#SelectDate").datepicker("hide");
    });
    $("#ButtonStatisticsSearchTrips").focus();

});   

Ответ 28

Это действительно важно для смартфонов и планшетов, потому что клавиатура появляется, когда вход имеет фокус. Это то, что я сделал, добавьте этот ввод в начале div:

<input type="image" width="1px" height="1px"/>

Не работает с размером 0px. Я думаю, это даже лучше с реальным прозрачным изображением, либо .png, либо .gif, но я не пробовал.

Работает хорошо в iPad.

Ответ 29

Вы можете добавить это:

...

dlg.dialog({ autoOpen:false,
modal: true, 
width: 400,
open: function(){                  // There is new line
  $("#txtStartDate").focus();
  }
});

...

Ответ 30

как первый вход: <input type="text" style="position:absolute;top:-200px" />