<Enter>でjQuery UIダイアログを送信する


131

フォーム付きのjQuery UIダイアログボックスがあります。ダイアログのボタンのクリックをシミュレートしたいので、マウスやタブを使用する必要はありません。つまり、「OK」ボタンを押すことをシミュレートする通常のGUIダイアログボックスのように動作させたいのです。

これはダイアログの簡単なオプションかもしれないと思いますが、jQuery UIのドキュメントにはありません。keyup()を使用して各フォーム入力をバインドできますが、よりシンプルでクリーンな方法があるかどうかはわかりませんでした。ありがとう。


フォームの使用を避け、再利用可能なコードが必要な場合は、ここで良い答えを提供しています。stackoverflow.com
Darren

回答:


153

jQuery UIウィジェットにオプションがあるかどうかはわかりませんkeypressが、ダイアログを含むdivにイベントをバインドするだけです...

$('#DialogTag').keypress(function(e) {
    if (e.keyCode == $.ui.keyCode.ENTER) {
          //Close dialog and/or submit here...
    }
});

これは、ダイアログのどの要素にフォーカスがあるかに関係なく実行されます。これは、目的に応じて適切な場合とそうでない場合があります。

これをデフォルトの機能にしたい場合は、次のコードを追加できます。

// jqueryui defaults
$.extend($.ui.dialog.prototype.options, { 
    create: function() {
        var $this = $(this);

        // focus first button and bind enter to it
        $this.parent().find('.ui-dialog-buttonpane button:first').focus();
        $this.keypress(function(e) {
            if( e.keyCode == $.ui.keyCode.ENTER ) {
                $this.parent().find('.ui-dialog-buttonpane button:first').click();
                return false;
            }
        });
    } 
});

これがどのように見えるかの詳細なビューは次のとおりです。

$( "#dialog-form" ).dialog({
  buttons: {  },
  open: function() {
    $("#dialog-form").keypress(function(e) {
      if (e.keyCode == $.ui.keyCode.ENTER) {
        $(this).parent().find("button:eq(0)").trigger("click");
      }
    });
  };
});

2
気にしないで、私はそれを見つけました:ダイアログに「閉じる」(閉じる、モーダル、bgiframeなどのような)を追加し、そこにキーアップハンドラーをフックします。
ミラノバブスコフ09

5
Webkit(Safari / Chrome)の場合、これは「keyup」ではなく「keydown」を実行した場合にのみ機能します。これが最近の変更なのか、それとも私のページにも実際のフォームが含まれていることが重要なのかわからない。それでも、ヒントをありがとう!
ニコラスピアセッキ2010

12
if(e.keyCode == 13)の代わりにif(e.keyCode === $ .ui.keyCode.ENTER)を実行すると、読みやすくなります。
A.マレー

2
私はこの回答に反対票を投じました。短くてすっきりしていますが、Firefox 7.0.1では、ユーザーがオートコンプリートドロップダウンボックスから何かを選択した場合(たとえば、以前に入力した電子メールアドレス)、[OK]ボタンがトリガーされます。
cburgmer 2012年

2
「open:」でイベントにバインドするのは悪い考えです。これにより、ダイアログが開かれるたびに再バインドされます。つまり、ダイアログが2回開かれた場合、イベントハンドラーは2回呼び出されます。
Elezar 2014

67

上記の回答をまとめ、重要なものを追加しました

$(document).delegate('.ui-dialog', 'keyup', function(e) {
        var target = e.target;
        var tagName = target.tagName.toLowerCase();

        tagName = (tagName === 'input' && target.type === 'button') 
          ? 'button' 
          : tagName;

        isClickableTag = tagName !== 'textarea' && 
          tagName !== 'select' && 
          tagName !== 'button';

        if (e.which === $.ui.keyCode.ENTER && isClickableTag) {
            $(this).find('.ui-dialog-buttonset button').eq(0).trigger('click');

            return false;
        }
    });

利点:

  1. 以下のような非互換性のある要素のキーを入力して許可しないtextareaselectbuttonまたはタイプのボタンで入力、で入力したユーザがクリックを想像textareaして、フォームに新しい行を取得する代わりに提出しましょう!
  2. バインドは1回実行されます。ダイアログの「開く」コールバックを使用してEnterキーをバインドすることを避け、ダイアログが「開く」たびに同じ関数を何度もバインドしないようにします。
  3. 上記の回答が示唆するように、既存のコードを変更しないでください
  4. 非推奨の「ライブ」の代わりに「デリゲート」を使用し、新しい「オン」メソッドを使用しないで古いバージョンのjqueryでの作業を許可する
  5. delegateを使用しているため、上記のコードはダイアログを初期化する前でも作成できます。なくてもヘッドタグに入れることができます$(document).ready
  6. また、デリゲートはdocument、上記のいくつかのコードのように、ハンドラーを1つのダイアログにのみバインドし、各ダイアログにハンドラーをバインドしません。
  7. 次のような動的に生成されるダイアログでも機能します $('<div><input type="text"/></div>').dialog({buttons: .});
  8. ie 7/8/9で動作しました!
  9. 遅いセレクターの使用を避ける :first
  10. ここで回答のようなハックを使用して非表示の送信ボタンを作成しないでください

短所:

  1. 最初のボタンをデフォルトとして実行します。if eq()ステートメント内で別のボタンを選択するか、関数を呼び出すことができます。
  2. すべてのダイアログは同じ動作をしますが、セレクタをより具体的にすることでフィルタリングできます。つまり、「#dialog」ではなく '.ui-dialog'

質問が古いことはわかっていますが、同じニーズがあったので、使用したソリューションを共有しました。


4
これは受け入れられた回答ではなく、投票数も少ないという事実は、悲しく、最も有益で、ハンドラーを継続的に追加していません。+1
クリスオケリー

1
優れた答えは、バインディングを追加するためのオープンコールバックを持つことは避けたいことです
Jay Rizzi

1
私にとってこれはイベントがキーダウンで、私がtagNameのすべての条件を削除してクリックトリガーを削除したときに機能します
Isaiyavan Babu Karan

1
また、これを機能させるには「キーダウン」に変更する必要がありました(OS X 10.8.4、Chrome 29、Firefox 23でテスト済み)。
natebeaty 2013

1
これは古い回答な.delegate()ので、jQuery 3.0で廃止されたことは注目に値し.on()ます。そのため、(1.7以降で利用可能です)おそらくこの時点でのルートです。
jinglesthula 2016年

13
$('#dialogBox').dialog('open');
$('.ui-dialog-buttonpane > button:last').focus();

JQuery UIの最新バージョン(1.8.1)で美しく動作します。デフォルトとして設定するボタンに応じて、:lastではなく:firstを使用することもできます。

このソリューションには、上記で選択したものと比較して、どのボタンがユーザーのデフォルトボタンであるかを示すという利点があります。ユーザーはボタン間でTABを押すこともでき、Enterキーを押すと現在フォーカスされているボタンをクリックします。

乾杯。


また、ダイアログに1つ以上のテキスト入力フィールドがある場合はどうなりますか?ユーザーがユーザー名とパスワードのフィールドにいるときにENTERにログインダイアログを送信させたい。
David Harkness

1
@David jQueryダイアログボタンを使用している場合は、フォーム上の通常の入力送信ボタンを非表示にします。例えば。可視性:非表示;
ダモ2011

6

これをより一般的に機能させるための粗雑で効果的な方法:

$.fn.dlg = function(options) {
    return this.each(function() {
             $(this).dialog(options);
             $(this).keyup(function(e){
                  if (e.keyCode == 13) {                
                       $('.ui-dialog').find('button:first').trigger('click');
                  }
             });
    });
}

次に、新しいダイアログを作成するときにこれを行うことができます。

$('#a-dialog').mydlg({...options...})

その後、通常のjqueryダイアログのように使用します。

$('#a-dialog').dialog('close')

より特殊なケースで機能するように改善する方法があります。上記のコードでは、Enterキーが押されたときにトリガーするボタンとして、ダイアログの最初のボタンが自動的に選択されます。また、アクティブなダイアログが常に1つしかないことを前提としています。しかし、あなたはアイデアを理解します。

注:上記のように、Enterで押されるボタンは、セットアップによって異なります。したがって、.findメソッドで:firstセレクターを使用したい場合もあれば、:lastセレクターを使用したい場合もあります。


$( '。ui-dialog')。find( 'button')。first()。trigger( 'click');のように.first()があるはずだと思います。それ以外の場合は、ダイアログのすべてのボタンがクリックされたときに、そのボタンのクリックをトリガーします。
JustinStolle

@thejh-いいえ、すべてのダイアログにkeyupイベントハンドラーをアタッチしますが、キーが押されたときにフォーカスのある要素を含むダイアログのみがイベントを受け取ります。
David Harkness、2011

6

この答えのようにキーコードを聞くのではなく(これを実行することができませんでした)、ダイアログ内でフォームの送信イベントにバインドしてから、次のように実行できます。

$("#my_form").parents('.ui-dialog').first().find('.ui-button').first().click();

だから、全体はこのようになります

$("#my_form").dialog({
  open: function(){
    //Clear out any old bindings
    $("#my_form").unbind('submit');
    $("#my_form").submit(function(){
      //simulate click on create button
      $("#my_form").parents('.ui-dialog').first().find('.ui-button').first().click();
      return false;
    });
  },
  buttons: {
    'Create': function() {
      //Do something
    },
    'Cancel': function() {
      $(this).dialog('close');
    }
  }
});

ブラウザーによって、Enterキーの扱いが異なります。また、ブラウザーによっては、Enter時に送信が行われない場合があります。


これは最もエレガントな答えのようです。
ダン

同じダイアログに3つ以上の入力がある場合、これは機能しません。理由がわからない。
programad

6

Ben Claytonは最も近く、最も短く、jqueryダイアログが初期化される前にインデックスページの上部に配置できます。ただし、「。live」は非推奨になっていることを指摘しておきます。優先アクションは「.on」になりました。「.on」を「.live」のように機能させたい場合は、委任されたイベントを使用してイベントハンドラーをアタッチする必要があります。また、他のいくつかのこと...

  1. 実際のキーコードを覚えておく必要がないので、ui.keycode.ENTERメソッドを使用してEnterキーをテストすることをお勧めします。

  2. クリックセレクターに「$( '。ui-dialog-buttonpane button:first'、$(this))」を使用すると、メソッド全体がジェネリックになります。

  3. 「return false;」を追加したい。デフォルトを防止し、伝播を停止します。

この場合...

$('body').on('keypress', '.ui-dialog', function(event) { 
    if (event.keyCode === $.ui.keyCode.ENTER) { 
        $('.ui-dialog-buttonpane button:first', $(this)).click();
        return false;
    }
});

4

もっと単純なことはわかりませんが、通常はどのボタンが現在フォーカスされているかを追跡します。フォーカスが別のコントロールに変更された場合、「ボタンフォーカス」は最後にフォーカスがあったボタンに残ります。通常、「ボタンフォーカス」はデフォルトのボタンから始まります。別のボタンにタブ移動すると、「ボタンのフォーカス」が変わります。別のフォーム要素に移動すると、「ボタンのフォーカス」がデフォルトのボタンに再びリセットされるかどうかを決定する必要があります。また、フォーカスされたボタンがウィンドウ内の実際のフォーカスを失うため、フォーカスされたボタンを示すために、ブラウザのデフォルト以外の視覚的なインジケータも必要になる可能性があります。

ボタンのフォーカスロジックをダウンして実装したら、おそらくダイアログ自体にキーハンドラーを追加し、現在「フォーカスされている」ボタンに関連付けられているアクションを呼び出します。

編集:私は、フォーム要素に入力しているときにいつでもEnterキーを押して「現在の」ボタンアクションを優先できるようにすることを前提としています。ボタンが実際にフォーカスされているときにのみこの動作が必要な場合、私の答えは複雑すぎます。


3

私はこの解決策を見つけました、それはIE8、Chrome 23.0およびFirefox 16.0で動作します

Robert Schmidtのコメントに基づいています。

$("#id_dialog").dialog({
    buttons: [{
        text: "Accept",
        click: function() {
            // My function
        },
        id: 'dialog_accept_button'
    }]
}).keyup(function(e) {
    if (e.keyCode == $.ui.keyCode.ENTER)
        $('#dialog_accept_button').click();
});

私はそれが誰にも役立つことを願っています。


ありがとう!それは私に多くの時間を節約しました!:)
Rahul Desai 2015年

3

ブラウザがすでにサポートしているものの基本を忘れることがあります。

<input type="submit" style="visibility:hidden" />

これにより、ENTERキーがフォームを送信します。


2

私はそのようにした...;)それが誰かに役立つことを願っています。

$(window).keypress(function(e) {
    if ((e.which && e.which == 13) || (e.keyCode && e.keyCode == 13)) {
        $(".ui-dialog:visible").find('.ui-dialog-buttonpane').find('button:first').click();
        return false;
    }
});

2

これにより、ボタンのクリックハンドラーのクリックがトリガーされます。この例では、jquery.validateプラグインを使用するようにダイアログのフォームをすでに設定していることを前提としています。しかし、簡単に適応できます。

open: function(e,ui) {
    $(this).keyup(function(e) {
        if (e.keyCode == 13) {
           $('.ui-dialog-buttonpane button:last').trigger('click');
        }
    });
},
buttons: {
    "Submit Form" : function() {
            var isValid = $('#yourFormsID').valid();
            // if valid do ajax call
            if(isValid){
               //do  your ajax call here. with serialize form or something...

            }
}

1

私はすでに多くの答えがあることを理解していますが、私の解決策は最も近いものであり、おそらく最短であると自然に考えています。将来作成されるダイアログで機能するという利点があります。

$(".ui-dialog").live("keyup", function(e) {
    if (e.keyCode === 13) {
        $('.ok-button', $(this) ).first().click();
    }
});

1
更新してくれてありがとう、ちょっとした質問です。ここで「.ok-button」とは何ですか?Enterでクリックしたいデフォルトのボタンに適用する必要があるクラスですか?
UID 2014年

質問silyを見つけた場合は申し訳ありません。JS/ jQueryでmが新しすぎる
UID

@BenClayton:この答えは、jQueryUI Dialogのコンテキストに置くと改善される可能性があります。
マイケル・ポッター

1

これが私がしたことです:

myForm.dialog({
  "ok": function(){
    ...blah...
  }
  Cancel: function(){
    ...blah...
  }
}).keyup(function(e){
  if( e.keyCode == 13 ){
   $(this).parent().find('button:nth-child(1)').trigger("click");
  }
});

この場合、myFormはフォームのhtmlを含むjQueryオブジェクトです(注、そこに「フォーム」タグはありません...これらを画面全体に配置すると、「Enter」を押すと更新されます)。

ユーザーがフォーム内から「Enter」を押すと、「OK」ボタンをクリックするのと同じことになります。

これにより、「OK」ボタンがすでに強調表示された状態でフォームが開かれるという問題も回避されます。フィールドのないフォームの場合はこれで十分ですが、ユーザーがデータを入力する必要がある場合は、最初のフィールドを強調表示する必要があります。


これは最も論理的なソリューションです。ボタンをIDで宣言し、セレクターをfind()に渡すと、どちらの方法でも機能します。+1
ヴィンセント

1

終わりました

  $('#login input').keyup(function(e) {
      if (e.keyCode == 13) {
          $('#login form').submit();
      }
   }

0

ボタン要素セレクターを知っている場合:

$('#dialogBox').dialog('open');
$('#okButton').focus();

あなたのためのトリックを行う必要があります。これにより、[OK]ボタンがフォーカスされ、Enterキーを押すと、期待どおりに「クリック」されます。これは、ネイティブUIダイアログで使用されるのと同じ手法です。


0
   $("#LogOn").dialog({
       modal: true,
       autoOpen: false,
       title: 'Please Log On',
       width: 370,
       height: 260,
       buttons: { "Log On": function () { alert('Hello world'); } },
       open: function() { $(this).parents('.ui-dialog-buttonpane button:eq(0)').focus();}
   });

0

私はこの問題の非常に単純な解決策を見つけました:

var d = $('<div title="My dialog form"><input /></div>').dialog(
    buttons: [{
        text: "Ok",
        click: function(){
            // do something
            alert('it works');
        },
        className: 'dialog_default_button'
    }]
});

$(d).find('input').keypress(function(e){
    if ((e.which && e.which == 13) || (e.keyCode && e.keyCode == 13)) {
        e.preventDefault();
        $('.dialog_default_button').click();
    }
});

0
$('#DialogID').dialog("option", "buttons")["TheButton"].apply()

これは私にとってはうまくいきました。


適用する引数として$( '#DialogID')。dialog()への参照を含めるとよいでしょう。そうしないと、$(this).close()はTheButton内に正しいコンテキストを持ちません。
デイブ

0

これらのソリューションはどれも、IE9では機能しないようです。私はこれで終わりました。

$('#my-dialog').dialog({
    ...
    open: function () {
        $(this).parent()
               .find("button:eq(0)")
               .focus()
               .keyup(function (e) {
                   if (e.keyCode == $.ui.keyCode.ENTER) {
                       $(this).trigger("click");
                   };
               });
    }
});

0

本文の下にダイアログDIVが追加されたため、本文の下が使用されます。本文はキーボードイベントをリッスンします。IE8、9、10、Mojila、Chromeでテストされています。

open: function() {
$('body').keypress(function (e) { 
     if (e.keyCode == 13) {   
     $(this).parent().find(".ui-dialog-buttonpane button:eq(0)").trigger("click");
     return false; 
     }
  }); 
}

0

コメントを投稿するのに十分な評判がないので。

$(document).delegate('.ui-dialog', 'keyup', function(e) {
  var tagName = e.target.tagName.toLowerCase();

  tagName = (tagName === 'input' && e.target.type === 'button') ? 'button' : tagName;

  if (e.which === $.ui.keyCode.ENTER && tagName !== 'textarea' && tagName !== 'select' && tagName !== 'button') {
      $(this).find('.ui-dialog-buttonset button').eq(0).trigger('click');
    return false;
  } else if (e.which === $.ui.keyCode.ESCAPE) {
      $(this).close();
  }
});

Basemm#35による修正された回答もEscapeに追加してダイアログを閉じます。


-1

ありがとうございます!!!

open: function () { debugger; $("#dialogDiv").keypress(function (e) { if (e.keyCode == 13) { $(this).parent().find("#btnLoginSubmit").trigger("click"); } }); },


うーん...あなたの投稿に何か新しいもの(以前の回答と比較して)?
クレオパトラ2013

-1

ボタンクラスを提供し、通常の方法でそれらを選択します。

$('#DialogTag').dialog({
  closeOnEscape: true,
  buttons: [
    {
      text: 'Cancel',
      class: 'myCancelButton',
      click: function() {
        // Close dialog fct
      }
    },
    {
      text: 'Ok',
      class: 'myOKButton',
      click: function() {
        // OK fct
      }
    }
  ],
  open: function() {

    $(document).keyup(function(event) {

      if (event.keyCode === 13) {
        $('.myOKButton').click();
      }

    });

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