<Enter> üzerinde jQuery UI iletişim kutusunu gönderin


131

Form içeren bir jQuery UI iletişim kutusu var. İletişim kutusunun düğmelerinden birine tıklamayı simüle etmek istiyorum, böylece fareyi veya sekmeyi kullanmanıza gerek kalmaz. Başka bir deyişle, "Tamam" düğmesine basma simülasyonlarının yapıldığı normal bir GUI iletişim kutusu gibi davranmasını istiyorum.

Bunun iletişim kutusu ile basit bir seçenek olabileceğini varsayıyorum, ancak jQuery UI belgelerinde bulamıyorum . Her form girişini keyup () ile bağlayabilirdim, ancak daha basit / daha temiz bir yol olup olmadığını bilmiyordum. Teşekkürler.


Bir form kullanmaktan kaçınmak ve yeniden kullanılabilir kod istiyorsanız, burada iyi bir cevap verdim: stackoverflow.com/a/9628800/329367
Darren

Yanıtlar:


153

JQuery UI widget'ında bir seçenek olup olmadığını bilmiyorum , ancak keypressolayı, iletişim kutunuzu içeren div'e bağlayabilirsiniz ...

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

Bu, diyaloğunuzda hangi öğenin odağa sahip olduğu önemli değil, ne istediğinize bağlı olarak iyi bir şey olabilir veya olmayabilir.

Bunu varsayılan işlevsellik yapmak istiyorsanız, bu kod parçasını ekleyebilirsiniz:

// 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;
            }
        });
    } 
});

İşte nasıl görüneceğine dair daha ayrıntılı bir görünüm:

$( "#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
Boşver, buldum: diyaloğa "açık" ekle (kapat, modal, bgiframe gibi) ve anahtar işleyiciyi oraya bağla.
Milan Babuškov

5
Webkit (Safari / Chrome) için, bu yalnızca "keyup" yerine "keydown" yaparsam çalışır. Bunun yeni bir değişiklik olup olmadığından veya sayfamın üzerinde gerçek bir form olup olmadığından emin değilim. Yine de bahşiş için teşekkürler!
Nicholas Piasecki

12
If (e.keyCode == 13) yerine, okunabilirliği artırmak için if (e.keyCode === $ .ui.keyCode.ENTER) yapabilirsiniz.
A. Murray

2
Bu cevabı reddettim. Kısa ve derli toplu olmasına rağmen, Firefox 7.0.1'de bu, kullanıcı otomatik tamamlama açılır kutusundan bir şey seçerse, örneğin önceden girilmiş bir e-posta adresi seçerse "Tamam" düğmesini de tetikleyecektir.
cburgmer

2
"Open:" içindeki olaylara bağlanmak kötü bir fikir. Bu, iletişim kutusu her açıldığında yeniden bağlanmasına neden olur, yani iletişim kutusu iki kez açılırsa olay işleyicisi iki kez çağrılır.
Elezar

67

Yukarıdaki cevapları özetledim ve önemli şeyler ekledim

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

Avantajları:

  1. Gibi olmayan uyumlu elemanlar üzerinde anahtarı girin izin vermemek textarea, select, buttonveya tip düğmesiyle giriş, kullanıcı tıklayarak üzerinde girmek hayal textareave yeni bir satır alma yerine gönderilen formu olsun!
  2. Bağlama bir kez yapılır, diyalog her 'açıldığında' aynı işlevi tekrar tekrar bağlamayı önlemek için enter anahtarını bağlamak için iletişim 'aç' geri aramasını kullanmaktan kaçının
  3. Yukarıdaki bazı yanıtların önerdiği gibi mevcut kodu değiştirmekten kaçının
  4. Kullanımdan kaldırılan "canlı" yerine "temsilci" kullanın ve jquery'nin eski sürümleriyle çalışmaya izin vermek için yeni "açık" yöntemini kullanmaktan kaçının
  5. Temsilci kullandığımız için, bu, yukarıdaki kodun iletişim kutusu başlatılmadan önce bile yazılabileceği anlamına gelir. olmadan da baş etiketine koyabilirsiniz.$(document).ready
  6. Ayrıca temsilci, documentdaha fazla verimlilik için yukarıdaki bazı kodlarda olduğu gibi her iletişim kutusuna yalnızca bir işleyiciyi bağlar ve işleyiciyi bağlamaz.
  7. Dinamik olarak oluşturulmuş diyaloglarla bile çalışır. $('<div><input type="text"/></div>').dialog({buttons: .});
  8. İe 7/8/9 ile çalıştı!
  9. Yavaş seçiciyi kullanmaktan kaçının :first
  10. Gizli bir gönder düğmesi oluşturmak için buradaki yanıtlarda olduğu gibi hack'leri kullanmaktan kaçının

Dezavantajları:

  1. İlk düğmeyi varsayılan olarak çalıştırın, ile başka bir düğme seçebilir eq()veya if ifadesinin içinde bir işlevi çağırabilirsiniz.
  2. Tüm diyaloglar aynı davranışa sahip olacaktır, seçicinizi daha spesifik hale getirerek filtreleyebilirsiniz, yani '#dialog' yerine '.ui-dialog'

Sorunun eski olduğunu biliyorum ama aynı ihtiyacım vardı, bu yüzden kullandığım çözümü paylaştım.


4
Bunun kabul edilen cevap olmaması ve daha fazla oy almaması beni üzüyor, en bilgilendirici ve sürekli olarak işleyici eklemiyor. +1
Chris O'Kelly

1
mükemmel cevap, ciltleme eklemek için açık geri aramaya sahip olmak kaçınmak isteyeceğiniz bir şey
Jay Rizzi

1
ve olay keydown bu işler benim için i tagName tüm koşulları kaldırmak ve tıklama tetiği kaldırmak
Isaiyavan Babu Karan

1
Bunun çalışması için "keydown" olarak değiştirmem gerekiyordu (OS X 10.8.4, Chrome 29 ve Firefox 23'te test edildi).
natebeaty

1
Bu daha eski bir cevap olduğu için .delegate(), jQuery 3.0'da kullanımdan kaldırıldığını belirtmekte fayda var , bu nedenle .on()(1.7'den beri mevcuttur) muhtemelen bu noktada gidilecek yoldur.
jinglesthula

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

JQuery UI'nin (1.8.1) en son sürümüyle güzel çalışır. Varsayılan olarak ayarlamak istediğiniz düğmeye bağlı olarak: son yerine: ilk olarak da kullanabilirsiniz.

Bu çözüm, yukarıda seçilene kıyasla, kullanıcı için hangi düğmenin varsayılan olduğunu gösterme avantajına sahiptir. Kullanıcı ayrıca düğmeler arasında SEKME yapabilir ve ENTER tuşuna basmak o anda odak altındaki düğmeyi tıklayacaktır.

Şerefe.


Peki ya diyaloğunuzda bir veya daha fazla metin giriş alanı varsa? Kullanıcı kullanıcı adı ve parola alanındayken ENTER'ın oturum açma iletişim kutusunu göndermesini istiyorum.
David Harkness

1
@David, jQuery İletişim Kutusu düğmelerini kullanıyorsanız, formdaki normal giriş gönderme düğmesini gizlemeniz yeterlidir. Örneğin. görünürlük: gizli;
Damo

6

Bunun daha genel bir şekilde çalışmasını sağlamanın kaba ama etkili bir yolu:

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

Daha sonra yeni bir iletişim kutusu oluşturduğunuzda bunu yapabilirsiniz:

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

Ve daha sonra normal bir jquery iletişim kutusu gibi kullanın:

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

Daha özel durumlarda çalışmasını sağlamak için bunu geliştirmenin yolları vardır. Yukarıdaki kodla, enter'a basıldığında tetiklenecek düğme olarak otomatik olarak iletişim kutusundaki ilk düğmeyi seçecektir. Ayrıca, herhangi bir anda yalnızca bir etkin iletişim kutusu olduğunu varsayar, bu durum böyle olmayabilir. Ama fikri anladın.

Not: Yukarıda belirtildiği gibi, enter'da basılan düğme kurulumunuza bağlıdır. Bu nedenle, bazı durumlarda .find yönteminde: ilk seçiciyi, diğerlerinde ise: son seçiciyi kullanmak isteyebilirsiniz.


$ ('. Ui-dialog') gibi bir .first () olması gerektiğini düşünüyorum. Find ('button']. First (). Trigger ('click'); Aksi takdirde, birden fazla varsa, iletişim kutusundaki tüm düğmelerin tıklamasını tetiklersiniz.
JustinStolle

@thejh - Hayır, her iletişim kutusuna bir anahtar oluşturma olay işleyicisi ekler, ancak yalnızca tuşa basıldığında odağa sahip öğeyi içeren iletişim kutusu etkinliği alır.
David Harkness

6

Bu yanıttaki (işe koyamadığım gibi) anahtar kodları dinlemek yerine, iletişim kutusundaki formun gönderme olayına bağlanabilir ve ardından şunu yapabilirsiniz:

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

Yani, her şey böyle görünecekti

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

Farklı tarayıcıların enter tuşunu farklı şekilde işlediğini ve bazılarının her zaman girişte gönderim yapmadığını unutmayın.


Bu en zarif cevap gibi görünüyor.
Dan

Aynı iletişim kutusunda üç veya daha fazla girişim olduğunda bu çalışmıyor. Neden bilmiyorum.
programad

6

Ben Clayton en düzgün ve en kısadır ve herhangi bir jquery diyalogları başlatılmadan önce dizin sayfanızın en üstüne yerleştirilebilir. Ancak, ".live" ifadesinin kullanımdan kaldırıldığını belirtmek isterim. Tercih edilen eylem artık ".on" dur. ".On" öğesinin ".live" gibi çalışmasını istiyorsanız, olay işleyicisini eklemek için temsilci olayları kullanmanız gerekir. Ayrıca birkaç şey daha ...

  1. Gerçek anahtar kodunu hatırlamanız gerekmediğinden, enter anahtarını test etmek için ui.keycode.ENTER yöntemini kullanmayı tercih ediyorum.

  2. Tıklama seçici için "$ ('. Ui-dialog-buttonpane button: first', $ (this))" kullanılması, tüm yöntemi jenerik yapar.

  3. "Return false" eklemek istiyorsunuz; temerrüdü önlemek ve yayılmayı durdurmak için.

Bu durumda...

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

4

Daha basitini bilmiyorum, ancak normalde hangi düğmenin geçerli odağa sahip olduğunu takip edersiniz. Odak farklı bir kontrole değiştirilirse, "düğme odak", en son odaklanan düğmede kalacaktır. Normalde, "düğme odağı" varsayılan düğmenizde başlar. Farklı bir düğmeye geçmek, "düğme odağını" değiştirir. Farklı bir form öğesine gitmenin "düğme odağı" nı tekrar varsayılan düğmeye sıfırlayıp sıfırlamayacağına karar vermeniz gerekir. Odaklanılan düğmeyi pencerede gerçek odağı kaybettiğinden belirtmek için muhtemelen tarayıcı varsayılanından başka bir görsel göstergeye de ihtiyacınız olacaktır.

Düğme odak mantığını bir kez indirip uyguladıktan sonra, muhtemelen iletişim kutusuna bir anahtar işleyici eklerim ve mevcut "odaklanmış" düğmeyle ilişkili eylemi başlatmasını isterim.

DÜZENLEME : Form öğelerini her doldurduğunuzda ve "geçerli" düğme eyleminin öncelikli olmasını istediğinizde enter tuşuna basmak istediğinizi varsayıyorum. Bu davranışı yalnızca düğme gerçekten odaklandığında istiyorsanız, cevabım çok karmaşık.


3

Bu çözümü buldum, IE8, Chrome 23.0 ve Firefox 16.0'da çalışıyor

Robert Schmidt yorumuna dayanıyor.

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

Umarım herkese yardımcı olur.


Teşekkürler! Bu bana çok zaman kazandırdı! :)
Rahul Desai

3

Bazen tarayıcının zaten desteklediği şeyin temelini unutuyoruz:

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

Bu, ENTERanahtarın formu göndermesine neden olacaktır .


2

Ben öyle yaptım ...;) Umarım birisi için yararlı olur ..

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

Bu, düğmenin tıklama işleyicisinin tıklamasını tetiklemek için çalışmalıdır. bu örnek, jquery.validate eklentisini kullanmak için iletişim kutusundaki formu önceden ayarladığınızı varsayar. ancak kolayca adapte edilebilir.

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

Şimdiden pek çok cevap olduğunu fark ediyorum, ancak doğal olarak benim çözümümün en temiz ve muhtemelen en kısa olduğunu düşünüyorum. Gelecekte herhangi bir zamanda oluşturulmuş herhangi bir diyalog üzerinde çalışması avantajına sahiptir.

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

1
Güncelleme için teşekkürler, sadece küçük bir soru, burada ".ok-button" nedir? Enter ile tıklamak istediğiniz varsayılan butonda başvurmanız gereken sınıf mı?
UID

Soruyu sily bulursanız özür dileriz .. JS / jQuery'de çok yeni m
UID

@BenClayton: JQueryUI Dialog bağlamına koyarsanız bu cevap geliştirilebilir.
Michael Potter

1

İşte yaptığım şey:

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

Bu durumda, myForm, formun html'sini içeren bir jQuery nesnesidir (not, burada herhangi bir "form" etiketi yoktur ... bunları tüm ekrana koyarsanız "enter" tuşuna bastığınızda yenilenir).

Kullanıcı formun içinden "enter" tuşuna her bastığında, bu "ok" butonuna tıklamakla eşdeğer olacaktır.

Bu, formun zaten vurgulanmış "tamam" düğmesiyle açılması sorununu da ortadan kaldırır. Bu, alanı olmayan formlar için iyi olsa da, kullanıcının bir şeyler doldurmasına ihtiyacınız varsa, muhtemelen ilk alanın vurgulanmasını istersiniz.


Bu en mantıklı çözümdür. Düğmenizi bir id ile bildirirseniz ve seçiciyi find () öğesine geçirirseniz daha da iyi olur, ancak her iki şekilde de çalışır. +1
Vincent

1

bitti ve bitti

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

0

düğme öğesi seçiciyi biliyorsanız:

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

Senin için hile yapmalı. Bu, tamam düğmesine odaklanır ve enter, beklediğiniz gibi onu 'tıklar'. Bu, yerel kullanıcı arayüzü iletişim kutularında kullanılan teknikle aynıdır.


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

Bu sorun için oldukça basit bir çözüm buldum:

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()

Bu benim için harika çalıştı ..


Uygulanacak argüman olarak $ ['# DialogID']. Dialog () öğesine bir başvuru eklemeniz iyi olur. Aksi takdirde $ (this) .close (), TheButton içinde doğru bağlama sahip olmayacaktır.
Dave

0

Bu çözümlerin hiçbiri IE9'da benim için işe yaramadı. Ben bununla bitirdim ..

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

Gövdenin altında DIV iletişim kutusu eklendiğinden gövde kullanılır, bu nedenle gövde artık klavye olayını dinler. IE8,9,10, Mojila, Chrome'da test edildi.

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

0

Çünkü yorum yazmak için yeterli itibarım yok.

$(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 tarafından değiştirilmiş yanıt da iletişim kutusunu kapatmak için Escape'e ekleyin.


-1

İyi çalışıyor Teşekkürler !!!

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


hmm ... gönderinizde yeni bir şey (önceki cevaplara kıyasla)?
kleopatra

-1

Düğmelerinize sınıflar verin ve bunları normal şekilde seçin:

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

    });

  }
});
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.