Отправить диалоговое окно jQuery UI на <Enter>

118

У меня есть диалоговое окно jQuery UI с формой. Я хотел бы имитировать щелчок на одной из кнопок диалога, поэтому вам не нужно использовать мышь или вкладку. Другими словами, я хочу, чтобы он работал как обычный графический интерфейс, где имитируется нажатие кнопки "ОК".

Я предполагаю, что это может быть простой вариант с диалоговым окном, но я не могу найти его в документации jQuery UI. Я мог привязать каждый вход формы с помощью keyup(), но не знал, был ли более простой/чистый способ. Спасибо.

  • 0
    Если вы хотите избежать использования формы и хотите повторно использовать код, я предоставил хороший ответ здесь: stackoverflow.com/a/9628800/329367

22 ответа

136
Лучший ответ

Я не знаю, есть ли опция в виджетах 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");
      }
    });
  };
});
  • 0
    Как это сделать, если диалог создается на лету, как в $ ('<div title = "my title"> Message </ div>'). Dialog () ...?
  • 2
    Неважно, я нашел это: добавьте «open» в диалог (например, «закрыть», «modal», «bgiframe» и т. Д.) И подключите там обработчик ключей.
Показать ещё 14 комментариев
61

Я подытожил ответы выше и добавил важные вещи

$(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;
        }
    });

<сильные > Преимущества:

  • Запретить ввод ключа на несовместимые элементы, такие как textarea, select, button или входы с кнопкой типа, представьте себе, что пользователь нажимает кнопку ввода textarea и получает форму, представленную вместо новой строки!
  • Связывание выполняется один раз, не используйте диалог "открыть" callback для привязки ключа ввода, чтобы избежать связывания одной и той же функции снова и снова при каждом открытии диалога
  • Избегайте изменения существующего кода в соответствии с приведенными выше ответами.
  • Используйте "делегат" вместо устаревшего "живого" и не используйте новый метод 'on', чтобы разрешить работу со старыми версиями jquery
  • Поскольку мы используем делегат, это означает, что вышеприведенный код может быть записан даже до диалога инициализации. вы также можете поместить его в главный тег даже без $(document).ready
  • Также делегат свяжет только один обработчик с document и не свяжет обработчик с каждым диалогом, как в некотором коде выше, для большей эффективности
  • Работает даже с динамически создаваемыми диалоговыми окнами, такими как $('<div><input type="text"/></div>').dialog({buttons: .});
  • Работает с 7/8/9!
  • Избегайте использования медленного селектора :first
  • Избегайте использования хаков, как в ответах здесь Отправка формы, нажав кнопку ввода без кнопки отправки, чтобы сделать скрытую кнопку отправки

Неудобство:

  • Запустите первую кнопку как стандартную, вы можете выбрать другую кнопку с помощью eq() или вызвать функцию внутри оператора if
  • Все диалоги будут иметь такое же поведение, что вы можете отфильтровать его, сделав свой селектор более конкретным, т.е. '#dialog' вместо '.ui-dialog'

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

  • 4
    Тот факт, что это не принятый ответ и не имеет больше голосов, делает меня грустным, наиболее информативным и не добавляет обработчиков постоянно. +1
  • 1
    отличный ответ, вам нужно избегать открытого обратного вызова для добавления привязок
Показать ещё 5 комментариев
13
$('#dialogBox').dialog('open');
$('.ui-dialog-buttonpane > button:last').focus();

Он прекрасно работает с последней версией JQuery UI (1.8.1). Вы также можете использовать: сначала вместо: последний, в зависимости от того, какую кнопку вы хотите установить по умолчанию.

Это решение, по сравнению с выбранным выше, имеет преимущество, показывающее, какая кнопка является стандартной для пользователя. Пользователь также может TAB между кнопками и нажатием ENTER будет нажимать кнопку, находящуюся в настоящее время в фокусе.

Приветствия.

  • 0
    А что если в вашем диалоге есть одно или несколько полей для ввода текста? Я хочу, чтобы ENTER отправлял диалог входа в систему, когда пользователь находится в полях имени пользователя и пароля.
  • 1
    @David, если вы используете кнопки jQuery Dialog, просто скрывайте обычную кнопку ввода ввода в форме. например. видимость: скрытая;
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');
    }
  }
});

Обратите внимание, что разные браузеры обрабатывают ключ ввода по-разному, а некоторые не всегда выполняют ввод при вводе.

  • 0
    Это кажется самым элегантным ответом.
  • 0
    Это не работает, когда у меня есть три или более входов в одном диалоге. Не знаю почему.
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')

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

Примечание. Как упоминалось выше, кнопка, которая нажата для ввода, зависит от вашей настройки. Таким образом, в некоторых случаях вы хотели бы использовать первый селектор в методе .find, а в других - использовать последний селектор.

  • 0
    Я думаю, что там должен быть .first (), как в $ ('.ui-dialog'). Find ('button'). First (). Trigger ('click'); В противном случае вы будете вызывать нажатие всех кнопок диалогового окна, если их несколько.
  • 0
    Ты прав. Благодарю.
Показать ещё 3 комментария
5

Бен Клейтон является самым аккуратным и самым коротким, и его можно разместить в верхней части страницы индекса до того, как будут инициализированы все диалоговые окна jquery. Однако я хотел бы указать, что ".live" устарел. Предпочтительное действие теперь ".on". Если вы хотите, чтобы ".on" функционировал как ".live", вам нужно будет использовать делегированные события для присоединения обработчика события. Кроме того, еще несколько вещей...

  • Я предпочитаю использовать метод ui.keycode.ENTER для проверки ввода потому что вам не нужно запоминать фактический key code.

  • Использование кнопки $('. ui-dialog-buttonpane: first', $(this)) "для Click Select делает весь общий метод.

  • Вы хотите добавить "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

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

Когда у вас есть логика фокуса кнопки и реализована, я, вероятно, добавлю ключевой обработчик к самому диалогу и вызову его действие, связанное с текущей "сфокусированной" кнопкой.

РЕДАКТИРОВАТЬ. Я предполагаю, что вы хотите, чтобы у вас был шанс попасть в любое время, когда вы заполняете элементы формы и выполняете действие кнопки "текущее". Если вы хотите только такое поведение, когда кнопка действительно сфокусирована, мой ответ слишком сложный.

3

Иногда мы забываем о том, что поддерживает браузер:

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

Это приведет к тому, что клавиша ENTER отправит форму.

3

Я нашел это решение, оно работает на IE8, Chrome 23.0 и Firefox 16.0

Это основано на комментарии Роберта Шмидта.

$("#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();
});

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

  • 0
    Спасибо! Это сэкономило мне много времени! :)
2

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

$(".ui-dialog").live("keyup", function(e) {
    if (e.keyCode === 13) {
        $('.ok-button', $(this) ).first().click();
    }
});
  • 1
    Эй, спасибо за обновление, просто маленький вопрос, что здесь за «.ok-button»? это класс, который вы должны применить к кнопке по умолчанию, которую вы хотите нажать с вводом?
  • 0
    Извините, если вы находите вопрос глупым. Я слишком нов в JS / jQuery
Показать ещё 1 комментарий
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...

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

сделано и сделано

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

}

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 - это объект jQuery, содержащий форму html (обратите внимание, что там нет никаких тегов "формы"... если вы поместите их на весь экран, будет обновляться при нажатии "enter"),

Всякий раз, когда пользователь нажимает "enter" в форме, он будет эквивалентен нажатию кнопки "ok".

Это также позволяет избежать проблемы с открытием формы с уже выделенной кнопкой "ok". Хотя это было бы полезно для форм без полей, если вам нужно, чтобы пользователь заполнил материал, вы, вероятно, захотите выделить первое поле.

  • 0
    Это самое логичное решение. Еще лучше, если вы объявите свою кнопку с идентификатором и передадите селектор в find (), но в любом случае это работает. +1
1
$('#DialogID').dialog("option", "buttons")["TheButton"].apply()

Это отлично поработало для меня.

  • 0
    Было бы хорошо включить ссылку на $ ('# DialogID'). Dialog () в качестве аргумента для применения. В противном случае $ (this) .close () не будет иметь правильного контекста внутри TheButton.
1
   $("#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();}
   });
1

если вы знаете селектор элементов кнопки:

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

Должен сделать трюк для вас. Это будет сфокусировано на кнопке ok и введите 'click', как и следовало ожидать. Это тот же метод, который используется в собственных диалоговых окнах интерфейса.

  • 4
    Это будет работать, если форма не была задействована.
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 для закрытия диалога.

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

Ни одно из этих решений, похоже, не работало для меня в 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

Я нашел довольно простое решение для этой проблемы:

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();
    }
});
-1

Он отлично работает Спасибо!

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

  • 0
    хм ... что-нибудь новое (по сравнению с предыдущими ответами) в вашем посте?

Ещё вопросы

Сообщество Overcoder
Наверх
Меню