it-roy-ru.com

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

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

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

129
CMB

Я не знаю, есть ли опция в виджете 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");
      }
    });
  };
});
149
Casey Williams

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

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

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

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

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

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

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

13
Mario Awad

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

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

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

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

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

6
Salida Software

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

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

  2. Использование "$ ('. Ui-dialog-buttonpane button: first', $ (this))" для селектора кликов делает весь метод универсальным.

  3. Вы хотите добавить "вернуть ложь"; чтобы предотвратить дефолт и остановить распространение.

В этом случае...

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

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

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

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

4
tvanfosson

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

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

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

3
Seifu

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

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

3
Pablo Oña

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

Я сделал так ...;) Надеюсь, это будет полезно для кого-то ..

$(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
Stanislav Vychegzhanin

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

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

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

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

Вот что я сделал:

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

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

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

1
Tyler

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

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
Robert Schmidt

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

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

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

0
sandesh247

Нижнее тело используется, потому что в теле добавлен диалог 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
LoopCoder

Похоже, что ни одно из этих решений не помогло мне в 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
Paul Martin

Потому что у меня недостаточно репутации, чтобы оставлять комментарии.

$(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
Liam Mitchell
$('#DialogID').dialog("option", "buttons")["TheButton"].apply()

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

0
Peter
   $("#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
LeCram