it-swarm.com.ru

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

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

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

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

<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>
150
slolife

jQuery UI 1.10.0 Changelog списки тикет 4731 как исправленные.

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

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

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

<input autofocus>

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

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

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

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

<span class="ui-helper-hidden-accessible"><input type="text"/></span>
72
Patrick Lee Scott

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

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

Скрипки

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

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

59
Fabrício Matté

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

28
user53067

Начиная с 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

27
silkfire

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

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

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

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

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

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

13
Rob Donovan

Установите 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
redsquare

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

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

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

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

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

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

например.:

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

Вот решение, которое я реализовал после прочтения 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 и добавляем некоторый дополнительный код, чтобы гарантировать, что 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;
}
3
Alexander Pritchard

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

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

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

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

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

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

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

1
mik-t

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

используйте опцию [autoOpen: false]

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

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

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

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

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

1
Roc

Если вы используете диалоговые кнопки, просто установите атрибут 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>
1
Sam

Я искал другую проблему, но ту же причину. Проблема состоит в том, что диалог устанавливает фокус на первый <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> получает фокус, но затем скрывается. Таким образом, общий эффект - это желаемый эффект.

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

1
MikeF

У меня похожая проблема. Я открываю диалоговое окно с ошибкой, когда проверка завершается неудачей, и она захватывает фокус, как это показывает Флуган в своем ответ . Проблема в том, что даже если ни один элемент внутри диалога не является вкладкой, само диалоговое окно все еще находится в фокусе. Вот оригинальный унифицированный код из 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();

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

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

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

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

На мой взгляд, это решение очень приятно:

$("#dialog").dialog({
    open: function(event, ui) {
        $("input").blur();
    }
});

Найдено здесь: невозможно удалить автофокус-в-интерфейсе

1
emolah

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

1
Manuel Leuenberger

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

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

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

    return false;
});

Не проверял это, но должно работать хорошо.

1
RaYell

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

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

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

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

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

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

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

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

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

0
BMiner

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

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

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

Работает нормально до сих пор в iPad.

0
Ángel Arbeteta

У меня была похожая проблема, и я решил ее, сосредоточившись на диалоге после открытия:

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?)

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

Правка: работает только в IE

0
daniloquio

У меня была похожая проблема. На моей странице первым вводом является текстовое поле с календарем пользовательского интерфейса 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();

});   
0
user1698635

найти в 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();
0
user1443069

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

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

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

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

0
pixelda