<Enter>에 jQuery UI 제출 대화 상자


131

양식이있는 jQuery UI 대화 상자가 있습니다. 대화 상자의 버튼 중 하나에 대한 클릭을 시뮬레이션하여 마우스 또는 탭을 사용할 필요가 없습니다. 다시 말해, "OK"버튼을 누르는 것을 시뮬레이션하는 일반 GUI 대화 상자처럼 작동하기를 원합니다.

대화 상자가있는 간단한 옵션 일 수 있지만 jQuery UI documentation 에서 찾을 수는 없습니다 . 각 양식 입력을 keyup ()으로 바인딩 할 수는 있지만 더 간단하고 깨끗한 방법이 있는지 알 수 없었습니다. 감사.


양식을 사용하지 않고 재사용 가능한 코드를 원한다면 여기에 좋은 답변을 제공했습니다. stackoverflow.com/a/9628800/329367
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
대화 상자에 "open"을 추가하고 (닫기, 모달, bgiframe 등) 키업 핸들러를 연결하십시오.
Milan Babuškov

5
Webkit (Safari / Chrome)의 경우 "keyup"대신 "keydown"을 수행하는 경우에만 작동합니다. 이것이 최근 변경인지 또는 내 페이지에도 실제 형식이 있는지 여부는 확실하지 않습니다. 그래도 팁 주셔서 감사합니다!
Nicholas Piasecki

12
if (e.keyCode == 13) 대신 가독성을 높이기 위해 if (e.keyCode === $ .ui.keyCode.ENTER) 할 수 있습니다.
A. 머레이

2
나는이 답변에 투표했다. 짧고 깔끔하지만 Firefox 7.0.1에서는 사용자가 자동 ​​완성 드롭 다운 상자 (예 : 이전에 입력 한 이메일 주소)에서 무언가를 선택하면 "확인"버튼이 트리거됩니다.
cburgmer

2
"open :"에서 이벤트에 바인딩하는 것은 좋지 않습니다. 이로 인해 대화 상자를 열 때마다 대화 상자가 리 바인드됩니다. 즉, 대화 상자가 두 번 열리면 이벤트 핸들러가 두 번 호출됩니다.
Elezar

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. 같은 비 호환 요소에 키를 입력 허용 textarea, select, button또는 유형 버튼 입력, 사용자 클릭이에 입력 상상 textarea과 새로운 라인을 얻는 대신 제출 양식을 얻을!
  2. 바인딩은 한 번 수행됩니다. 대화 상자가 '열릴 때마다 동일한 기능을 반복해서 바인딩하지 않도록 대화 상자'열기 '콜백을 사용하여 Enter 키를 바인딩하지 마십시오.
  3. 위의 일부 답변이 제안하는 것처럼 기존 코드를 변경하지 마십시오
  4. 더 이상 사용되지 않는 'live'대신 'delegate'를 사용하고 이전 버전의 jquery로 작업 할 수 있도록 새로운 'on'방법을 사용하지 마십시오
  5. delegate를 사용하기 때문에 대화 상자를 초기화하기 전에도 위의 코드를 작성할 수 있습니다. 없이도 헤드 태그에 넣을 수 있습니다$(document).ready
  6. 또한 델리게이트는 document위의 일부 코드와 같이 하나의 핸들러 만 바인딩하고 각 대화 상자에는 핸들러를 바인딩하지 않으므로 효율성이 향상됩니다.
  7. 다음과 같이 동적으로 생성 된 대화 상자에서도 작동 $('<div><input type="text"/></div>').dialog({buttons: .});
  8. 즉 7/8/9로 작업했습니다!
  9. 느린 선택기를 사용하지 마십시오 :first
  10. 숨겨진 제출 버튼을 만들기 위해 여기 에 답변과 같은 해킹을 사용하지 마십시오

단점 :

  1. 첫 번째 버튼을 기본 버튼으로 실행하십시오 .if 버튼으로 다른 버튼을 선택 eq()하거나 함수를 호출 할 수 있습니다
  2. 모든 대화 상자는 선택기를보다 구체적으로 지정하여 필터링 할 수있는 것과 동일한 동작을합니다 (예 : '#dialog'대신) '.ui-dialog'

나는 그 질문이 오래되었다는 것을 알고 있지만 같은 요구가 있었기 때문에 내가 사용한 솔루션을 공유했습니다.


4
이 답변이 받아 들여지지 않고 더 많은 표를 얻지 못한다는 사실은 나를 슬프고 가장 유익하며 처리기를 계속 추가하지 않습니다. +1
Chris O'Kelly 5

1
바인딩을 추가하기 위해 열린 콜백을 갖는 것은 피하고 싶은 것입니다.
Jay Rizzi

1
나를 위해 이것은 이벤트가 keydown 일 때 작동하며 tagName의 모든 조건을 제거하고 클릭 트리거를 제거합니다
Isaiyavan Babu Karan

1
또한이 작업을 수행하기 위해 "키 다운"으로 변경해야했습니다 (OS X 10.8.4, Chrome 29 및 Firefox 23에서 테스트).
natebeaty

1
이것은 오래된 답변 .delegate()이므로 jQuery 3.0에서 더 이상 사용되지 않으므로 .on()(1.7 이후 사용 가능) 아마도이 시점에 갈 경로 일 것입니다.
jinglesthula

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

최신 버전의 JQuery UI (1.8.1)와 아름답게 작동합니다. 기본값으로 설정하려는 버튼에 따라 : last 대신 : first를 사용할 수도 있습니다.

이 솔루션은 위에서 선택한 것과 비교하여 어떤 버튼이 사용자의 기본 버튼인지 표시 할 수있는 이점이 있습니다. 사용자는 버튼 사이를 탭할 수 있으며 ENTER를 누르면 현재 포커스가있는 버튼을 클릭합니다.

건배.


대화 상자에 하나 이상의 텍스트 입력 필드가있는 경우 어떻게해야합니까? 사용자가 사용자 이름과 비밀번호 필드에있을 때 ENTER가 로그인 대화 상자를 제출하고 싶습니다.
David Harkness

1
@David jQuery 대화 상자 버튼을 사용하는 경우 양식에서 일반 입력 제출 버튼을 숨기십시오. 예. 가시성 : 숨겨진;
Damo

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 키를 누를 때 트리거되는 버튼으로 대화 상자의 첫 번째 버튼을 자동으로 선택합니다. 또한 주어진 시간에 하나의 활성 대화 상자 만 있다고 가정합니다. 그러나 당신은 아이디어를 얻습니다.

참고 : 위에서 언급했듯이 enter를 누르면 누른 버튼은 설정에 따라 다릅니다. 따라서 어떤 경우에는 .find 메소드에서 : first 선택기를 사용하고 싶거나 다른 경우에는 : last 선택기를 사용하고 싶을 수도 있습니다.


$ ( '. ui-dialog'). find ( 'button'). first (). trigger ( 'click')와 같이 거기에 .first ()가 있어야한다고 생각합니다. 그렇지 않으면 대화 상자의 모든 버튼이 하나 이상 클릭되면 트리거됩니다.
JustinStolle

@thejh-아니요. 키업 이벤트 핸들러를 모든 대화 상자에 연결하지만 키를 누를 때 포커스가있는 요소가 포함 된 대화 상자 만 이벤트를 수신합니다.
David Harkness

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 키를 제출하지는 않습니다.


이것은 가장 우아한 답변처럼 보입니다.
Dan

동일한 대화 상자에 세 개 이상의 입력이 있으면 작동하지 않습니다. 이유를 모릅니다.
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

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

질문 sily을 찾으면 죄송합니다. JS / jQuery에서 너무 새롭습니다
UID

@ BenClayton : jQueryUI 대화 상자의 컨텍스트에 넣으면이 대답을 향상시킬 수 있습니다.
Michael Potter

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 객체입니다 (참고 : 거기에 "form"태그가 없습니다 ... "enter"를 누를 때 전체 화면에 태그를 넣으면 새로 고침됩니다).

사용자가 양식 내에서 "enter"를 누를 때마다 "ok"단추를 클릭하는 것과 같습니다.

이렇게하면 "확인"버튼이 이미 강조 표시된 상태에서 양식을 열지 않아도됩니다. 필드가없는 양식에는 유용하지만 사용자가 내용을 입력해야하는 경우 첫 번째 필드를 강조 표시 할 수 있습니다.


이것이 가장 논리적 인 해결책입니다. id로 버튼을 선언하고 selector를 find ()에 전달하지만 어느 쪽이든 작동하면 더 좋습니다. +1
Vincent

1

완료 및 완료

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

0

버튼 요소 선택기를 알고 있다면 :

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

당신을 위해 트릭을해야합니다. 이것은 ok 버튼에 초점을 맞추고, 원하는대로 입력하면 '클릭'합니다. 이것은 기본 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 내부에 올바른 컨텍스트를 갖지 않습니다.
Dave

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로 수정 된 답변도 이스케이프에 추가하여 대화 상자를 닫습니다.


-1

잘 작동합니다 감사합니다 !!!

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


흠 ... 게시물에 새로운 내용 (이전 답변과 비교)이 있습니까?
kleopatra

-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.