jQuery UIダイアログが最初のテキストボックスにフォーカスを設定しないようにする


156

ユーザーがリンクをクリックしたときに表示されるjQuery UIモーダルダイアログをセットアップしました。そのダイアログのdivタグには2つのテキストボックス(簡潔にするために1のコードのみを示しています)があり、フォーカスに反応するjQuery UI DatePickerテキストボックスに変更されています。

問題は、jQuery UI dialog( '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>

画像にもピントを合わせます!通常の<img>タグと<input type = image>の
両方に

回答:


78

jQuery UI 1.10.0の変更ログでは、チケット4731が修正済みとしてリストされています。

focusSelectorは実装されていないようですが、代わりにさまざまな要素のカスケード検索が使用されました。チケットから:

[autofocus]で始まり、:tabbableコンテンツ、ボタンペイン、閉じるボタン、ダイアログの順にオートフォーカスを拡張します

そのため、要素をautofocus属性でマークし、それがフォーカスを取得する要素です。

<input autofocus>

ではドキュメント、フォーカスロジックは(タイトル「フォーカス」の下で、ちょうど内容のテーブルの下)について説明します。

ダイアログを開くと、フォーカスは自動的に次と一致する最初のアイテムに移動します。

  1. autofocus属性を持つダイアログ内の最初の要素
  2. :tabbableダイアログのコンテンツ内の最初の要素
  3. :tabbableダイアログのボタンペイン内の最初の要素
  4. ダイアログの閉じるボタン
  5. ダイアログ自体

反対投票は何ですか?修正バージョンとして1.9を指定したことが原因である場合は、チケットに合わせて1.10に更新しました。
slolife 2012年

1
Dialogのjquery-ui 1.10ドキュメントを見ていて、表示されていません。APIで「focusSelector」を検索しましたが、ありません。
Paul Tomblin 2013年

3
画面外にある任意の要素にフォーカスを設定すると、ウィンドウがその要素まで上下にスクロールします。これは、ダイアログが開いているときだけでなく、ウィンドウがフォーカスを取得したときにも発生します。Firebugを使用して「要素を検査」し、ドキュメントウィンドウ内をクリックして戻ると、ウィンドウが上下にスクロールして、jQuery-UIがフォーカスした要素に移動します。問題は、どの要素をフォーカスするかを選択する方法ではなく、どのようにフォーカスを防ぐかです。フォーカスする別の要素を選択しても問題は解決しません。
Vladimir Kornea 2014年

4
jQuery UIがこれを「修正済み」と見なしているという考えは奇妙です。修正はオートフォーカスロジックをすべて削除することです。入力ではなく、ダイアログを開くように頼みました。とても迷惑。
AJB、2015年

2
fwiw、最初の入力の上にtype = "hidden"の入力を追加し、それにautofocus属性を追加しました。それはあなたがそれが何を意味するかを意味するものではありませんが、この問題を修正するために機能します。
jinglesthula

77

その上に非表示のスパンを追加し、ui-helper-hidden-accessibleを使用して絶対配置によって非表示にします。jquery-uiからのダイアログを使用していて、jquery-uiにあるので、そのクラスがあることはわかっています。

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

1
素晴らしい仕事です。jsは必要ありません。レイアウトは変更されません。jqueryuiはネイティブでサポートします。
12

同意してください。非表示のアクセス可能なクラスについても知っておくと便利です。ありがとう!!
user1055761 2012年

4
これは、支援技術(スクリーンリーダーなど)を使用している人に問題を引き起こします
rink.attendant.6 '22

1
@ rink.attendant.6どの問題?
oxfn 2015

素晴らしいソリューション
ペドロコエーリョ

63

jQuery UI> = 1.10.2では、_focusTabbableプロトタイプメソッドをプラセボ関数で置き換えることができます。

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

フィドル

これはdialog、ページ内のすべてのに影響を与え、それぞれを手動で編集する必要はありません。

元の関数は、autofocus属性/ tabbable要素/ を使用して最初の要素にフォーカスを設定するか、ダイアログ自体にフォールバックするだけです。その使用は要素にフォーカスを設定するだけなので、それをで置き換えることには何の問題もないはずnoopです。


7
何時間も何時間もこれで焼き尽くされました。私のクライアントはありがとう。
lamarant 2014年

1
これが答えになるはずです!
briansol

このソリューションを2日間検索したところ、他に何も機能しませんでした。どうもありがとうございました。
Legionar 2015

1
警告:ダイアログがポップアップ表示されたときにEscapeキーを押しても、ダイアログにフォーカスが移るまでダイアログは閉じません。
ロバート

1
@Robertをで置き換える代わりに$.noop、アクティブなダイアログをメモする関数で置き換えESC、「アクティブ」ダイアログがある場合はそれをインターセプトして閉じるグローバルキーイベントハンドラーを登録します。
パーキンス

28

jQuery UI 1.10.0以降、HTML5属性 autofocus を使用して、フォーカスする入力要素を選択できます。

ダイアログボックスで最初の入力としてダミー要素を作成するだけです。それはあなたのために焦点を吸収します。

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

これは、2013年2月7日にChrome、Firefox、Internet Explorer(すべての最新バージョン)でテストされています。

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


27

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は回避策として機能します。


1
tabindex = -1は、テキストボックスにタブで移動できないようにしませんか?
slolife 2009

2
調査をありがとう。現在、それを実行しているのは実際のコードです。この自動フォーカスを無効にするオプションを追加するようにjQuery UIチームに提案するかもしれません。
slolife 2009

3
@slolife-この本当に古いスレッドを復活させて申し訳ありませんが、そのチケットは修正(focusSelectorオプション)がjQueryUI 1.8にあるはずであり、現在1.8.13であり、jQueryUIダイアログドキュメントに表示されていません。これはどうなりましたか?
トムハミング

気にしないで。変更履歴で「マイルストーンがTBDから1.8に変更されました」を見たことがありますが、実際には一番上に1.9と表示されていることに気付きませんでした。
トムハミング

私は私の回避策がここで説明され、同様の問題を抱えている- stackoverflow.com/a/12250193/80002
マーク

15

遊んでいる間にこれを理解しました。

フォーカスを削除するこれらの解決策を見つけたためESC、最初にダイアログに入ったときにキーが機能しなくなりました(つまり、ダイアログを閉じました)。

ダイアログが開いてすぐにを押すESCと、フォーカスがいくつかの非表示フィールドまたは何かにフォーカスされており、keypressイベントを取得していないため、ダイアログが閉じません(有効になっている場合)。

私が修正した方法は、これをopenイベントに追加して、代わりに最初のフィールドからフォーカスを削除することでした:

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

これにより、表示されていないダイアログボックスにフォーカスが設定され、ESCキーが機能します。


3
これは、役に立たないHTMLの追加、tabindexの削除、またはESCキーの破損を含まない、唯一の有効な解決策のようです。
BojanBedrač16年

10

入力の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");
        }
    });
});

4
tabindex = -1は、テキストボックスにタブで移動できないようにしませんか?
slolife 2009

1
ダイアログが表示され
たら

10

私の回避策:

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

+1。:firstセレクターを使用するか.first()、FF / Chrome / IE9でチャームのように機能します。それをdialogopenバインディングに投げ込むこともできます。
nickb

これも私をそこに連れて行ってくれました。私を除いて、ダイアログにはまったく入力がなく、最初のリンクがフォーカスされていました...そのため、このオプションをjQueryダイアログに追加しました:open: function(){ $('a').blur(); // no autofocus on links }
Marcus

8

ダイアログよりも長いコンテンツがありました。開くと、ダイアログは一番下にある最初の:tabbableに移動します。ここに私の修正がありました。

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

これでうまくいきましたが、$('...').blur();スクロールの代わりに使用しました。
ジャワ

4
私のコンテンツも非常に長くなりました。ぼかしは選択を削除しましたが、ダイアログを一番下までスクロールしたままにしました。scrollTopは、コンテンツを上にスクロールしましたが、選択範囲は残しました。私は$( '...')。blur();を使用してしまいました $(this).scrollTop(0); チャンピオンのように働いた。

7

簡単な回避策:

tabindex = 1で非表示の要素を作成するだけです...これは日付ピッカーをフォーカスしません...

例えば。:

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

ie9とfirefoxでは正常に動作しますが、safari / chromeでは動作しません。
tuseau

3

これは、jQuery UIチケット#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の「select」オートコンプリートコールバックをオーバーライドし、選択を行った後、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;
}

2

このオプションを提供して、代わりに閉じるボタンにフォーカスすることができます。

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

1

これは、jQueryプラグインの問題ではなく、ブラウザの動作である可能性があります。ポップアップを開いた後、プログラムでフォーカスを削除してみましたか?

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

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

    return false;
});

テストしていませんが、問題なく動作するはずです。


1
悲しいことに、これは機能しません。それがIEなのか、jquery UIなのかはわかりません。ただし、プログラムによってフォーカスを別の場所に移動しても、カレンダーは開いたままです。
パトリシア

1

私は同じ問題を抱えていて、ダイアログが開かれるたびにフォーカスを奪う、日付ピッカーの前に空の入力を挿入することで解決しました。この入力は、ダイアログを開くたびに非表示になり、閉じるときに再び表示されます。


1

さて、今のところ誰も解決策を見つけられなかったのはクールですが、私はあなたのために何かを持っているようです。悪いニュースは、入力とリンクが内部にない場合でも、ダイアログがフォーカスを取得することです。ダイアログをツールチップとして使用し、フォーカスを元の要素に留める必要があります。これが私の解決策です:

オプションを使用[autoOpen:false]

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

ダイアログは非表示ですが、フォーカスはどこにも設定されず、元の場所にとどまります。プレーンテキストのみのツールチップで機能しますが、開始時にダイアログを表示することが重要である可能性のあるより機能的なダイアログについてはテストされていません。おそらくいずれの場合も問題なく動作します。

元の投稿は最初の要素にフォーカスが当たらないようにするためのものだったと理解していますが、ダイアログを開いた後(コードの後)にフォーカスを置く場所を簡単に決定できます。

IE、FF、Chromeでテスト済み。

うまくいけば、これは誰かを助けるでしょう。



1

同様の問題があります。検証が失敗したときにエラーダイアログを開き、Fluganが回答に表示するように、フォーカスを取得します。問題は、ダイアログ内の要素にタブを設定できない場合でも、ダイアログ自体がフォーカスされていることです。以下は、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);
};

これは、.dialog()の「dialogClass」オプションを使用し、上記の:notフィルターを変更してクラスを含めることにより、特定のダイアログにのみ影響を与えるように拡張できます。例:not(.ui-dialog.myDialogClass)
Andrew Martinez

1

別の問題を探していましたが、同じ原因がありました。問題は、ダイアログが最初<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>フォーカスを取得したが、その後隠されています。したがって、全体的な効果は望ましい効果です。

私はこれが古いスレッドであることを知っていますが、UIドキュメントに関してはこれに対する修正はありません。これには、ぼかしや焦点を合わせる必要はありません。それが最もエレガントかどうかはわかりません。しかし、それは意味があり、誰にでも簡単に説明できます。


1

Jqueryダイアログの形式でフィールドが1つしかなく、それがDatepickerを必要とするフィールドである場合、代わりに、ダイアログのタイトルバーにあるダイアログの閉じる(クロス)ボタンにフォーカスを設定することができます。

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

これを呼び出した後、ダイアログが初期化されました。例:

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

.dialog()が呼び出された後に閉じるボタンがレンダリングされるためです。


1

ダイアログボタンを使用している場合autofocusは、ボタンの1つに属性を設定します。

$('#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>


0

同じ問題が発生しました。

私が行った回避策は、ダイアログコンテナーの上部にダミーのテキストボックスを追加することです。

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

0

前述のように、これはjQuery UIの既知のバグであり、比較的早く修正されるはずです。それまで...

これは別のオプションなので、tabindexをいじる必要はありません。

ダイアログボックスが開くまで、datepickerを一時的に無効にします。

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

私のために働く。

重複する質問:ダイアログを開くときに最初のフォーム入力をぼかす方法


0

focus()ダイアログが開いたときにイベントが最初の入力フィールドにフォーカスしないようにしたい場合は、以前の回答のいくつかを拡張して(そして補助的な日付ピッカーの側面を無視して)、以下を試してください:

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

0

私は同様の問題を抱えていて、開いた後のダイアログに焦点を当てることで解決しました:

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

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

jQuery 1.9がリリースされ、修正はないようです。いくつかの推奨された方法で最初のテキストボックスのフォーカスを回避しようとしても、1.9では機能しません。ダイアログのテキストボックスが既にフォーカスを取得し、ダーティな作業を行った後で、フォーカスをぼかしたりフォーカスを移動したりするメソッドが発生するためです。

APIドキュメントに、期待される機能の点で何か変更されたと思わせるものは何もありません。オープナーボタンを追加するにはオフ...


修正はjQueryチケットに従って1.10にプッシュされました:bugs.jqueryui.com/ticket/4731
slolife

0

同様の問題がありました。私のページでは、最初の入力はjQuery UIカレンダーを含むテキストボックスです。2番目の要素はボタンです。日付にはすでに値があるので、ボタンにフォーカスを設定しますが、最初にテキストボックスにぼかしのトリガーを追加します。これにより、すべてのブラウザー、およびおそらくすべてのバージョンの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

入力にフォーカスがあるとキーボードが表示されるため、これはスマートフォンやタブレットにとって非常に重要です。これは私がやったことです、この入力をdivの先頭に追加します:

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

サイズでは機能しません0px。私はそれがより良い本物の透明なイメージを持つだと思う、のいずれか.pngまたは.gif私は試していません。

これまでのところiPadで正常に動作しています。


-1

これを追加できます:

...

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

...


3
彼はフォーカスを追加するのではなく、フォーカスを防ぐ方法を尋ねています。
CBarr 2012年

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.