Отправить диалоговое окно jQuery UI на <Enter> - PullRequest
129 голосов
/ 15 мая 2009

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

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

Ответы [ 23 ]

149 голосов
/ 15 мая 2009

Я не знаю, есть ли опция в виджете 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");
      }
    });
  };
});
65 голосов
/ 23 ноября 2012

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

$(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. Привязка выполняется один раз, избегайте использования обратного вызова диалога «Открыть» для привязки клавиши ввода, чтобы избежать повторного связывания одной и той же функции снова и снова каждый раз, когда диалоговое окно «открыто»
  3. Избегайте изменения существующего кода, так как некоторые ответы выше предлагают
  4. Используйте «делегат» вместо устаревшего «живого» и избегайте использования нового метода «on», чтобы разрешить работу со старыми версиями jquery
  5. Поскольку мы используем делегат, это означает, что приведенный выше код может быть написан еще до инициализации диалога. Вы также можете поместить его в заголовок даже без $(document).ready
  6. Кроме того, делегат будет привязывать только один обработчик к document и не будет привязывать обработчик к каждому диалогу, как в некотором коде выше, для большей эффективности
  7. Работает даже с динамически генерируемыми диалогами, такими как $('<div><input type="text"/></div>').dialog({buttons: .});
  8. Работал с т.е. 7/8/9!
  9. Избегайте использования медленного селектора :first
  10. Избегайте использования хаков, как в ответах здесь , чтобы сделать скрытую кнопку отправки

Недостатки:

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

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

13 голосов
/ 14 мая 2010
$('#dialogBox').dialog('open');
$('.ui-dialog-buttonpane > button:last').focus();

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

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

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

6 голосов
/ 03 декабря 2009

Грубый, но эффективный способ сделать эту работу более общей:

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

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

6 голосов
/ 13 мая 2011

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

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

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

5 голосов
/ 19 июня 2012

Ben Clayton's - самый аккуратный и самый короткий, и его можно поместить вверху вашей индексной страницы до того, как будут инициализированы любые jquery-диалоги Тем не менее, я хотел бы отметить, что «.live» устарела. Предпочтительное действие теперь ".on". Если вы хотите, чтобы «.on» функционировал как «.live», вам придется использовать делегированные события, чтобы присоединить обработчик событий. Кроме того, несколько других вещей ...

  1. Я предпочитаю использовать метод ui.keycode.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 голосов
/ 15 мая 2009

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

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

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

3 голосов
/ 28 февраля 2013

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

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

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

3 голосов
/ 13 декабря 2012

Я нашел это решение, оно работает на 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();
});

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

2 голосов
/ 14 февраля 2011

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

            }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...