Invia la finestra di dialogo dell'interfaccia utente jQuery su <Invio>


131

Ho una finestra di dialogo dell'interfaccia utente jQuery con un modulo. Vorrei simulare un clic su uno dei pulsanti della finestra di dialogo in modo da non dover utilizzare il mouse o la scheda su di esso. In altre parole, voglio che si comporti come una normale finestra di dialogo della GUI in cui simuli di premere il pulsante "OK".

Presumo che questa potrebbe essere una semplice opzione nella finestra di dialogo, ma non riesco a trovarla nella documentazione dell'interfaccia utente di jQuery . Potrei associare ogni input di modulo con keyup () ma non sapevo se esistesse un modo più semplice / più pulito. Grazie.


Se desideri evitare di utilizzare un modulo e desideri un codice riutilizzabile, ho fornito una buona risposta qui: stackoverflow.com/a/9628800/329367
Darren

Risposte:


153

Non so se c'è un'opzione nel widget dell'interfaccia utente jQuery , ma potresti semplicemente associare l' keypressevento al div che contiene la tua finestra di dialogo ...

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

Questo funzionerà indipendentemente dall'elemento che ha lo stato attivo nella tua finestra di dialogo, che può essere o meno una buona cosa a seconda di ciò che vuoi.

Se vuoi rendere questa funzionalità predefinita, puoi aggiungere questo pezzo di codice:

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

Ecco una visione più dettagliata di come sarebbe:

$( "#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
Non importa, l'ho trovato: aggiungi "apri" alla finestra di dialogo (come close, modal, bgiframe, ecc.) E aggancia il gestore dei keyup lì.
Milano Babuškov,

5
Per Webkit (Safari / Chrome), funziona solo se eseguo "keydown" anziché "keyup". Non sono sicuro se si tratta di una modifica recente o se è importante che anche la mia pagina abbia una forma reale. Comunque, grazie per il suggerimento!
Nicholas Piasecki,

12
Invece di if (e.keyCode == 13) potresti fare if (e.keyCode === $ .ui.keyCode.ENTER) per aumentare la leggibilità.
A. Murray,

2
Ho votato a fondo questa risposta. Sebbene sia breve e pulito, in Firefox 7.0.1 questo attiverà anche il pulsante "OK" se l'utente seleziona qualcosa dalla casella a discesa del completamento automatico, ad esempio un indirizzo e-mail inserito in precedenza.
Hamburger

2
È una cattiva idea legarsi agli eventi in "open:". Questo farà sì che si ricolleghi ogni volta che si apre la finestra di dialogo, il che significa che se la finestra di dialogo viene aperta due volte, il gestore eventi verrà chiamato due volte.
Elezar,

67

Ho riassunto le risposte sopra e aggiunto cose importanti

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

vantaggi:

  1. Non consentire tasto Invio su elementi non compatibili come textarea, select, buttono ingressi con pulsante tipo, immaginate clic utente entra in textareae ottenere il modulo inviato invece di ottenere nuova linea!
  2. Il collegamento viene eseguito una volta, evitare di utilizzare la finestra di dialogo "Apri" per richiamare il tasto Invio per evitare di associare la stessa funzione ancora e ancora ogni volta che la finestra di dialogo viene "aperta"
  3. Evita di modificare il codice esistente come suggerito da alcune risposte sopra
  4. Usa 'delegate' invece del deprecato 'live' ed evita di usare il nuovo metodo 'on' per consentire di lavorare con versioni precedenti di jquery
  5. Poiché utilizziamo delegate, ciò significa che il codice sopra può essere scritto anche prima di inizializzare la finestra di dialogo. puoi anche metterlo nel tag head anche senza$(document).ready
  6. Inoltre delegare vincolerà un solo gestore a documente non vincolerà il gestore a ciascuna finestra di dialogo come in alcuni codici sopra, per una maggiore efficienza
  7. Funziona anche con dialoghi generati dinamicamente come $('<div><input type="text"/></div>').dialog({buttons: .});
  8. Ha funzionato con ie 7/8/9!
  9. Evitare di utilizzare il selettore lento :first
  10. Evita di usare gli hack come nelle risposte qui per creare un pulsante di invio nascosto

svantaggi:

  1. Esegui il primo pulsante come predefinito, puoi scegliere un altro pulsante con eq()o chiamare una funzione all'interno dell'istruzione if
  2. Tutte le finestre di dialogo avranno lo stesso comportamento che puoi filtrare rendendo il selettore più specifico, ad esempio '#dialog' anziché '.ui-dialog'

So che la domanda è vecchia ma ho avuto la stessa necessità, quindi ho condiviso la soluzione che ho usato.


4
Il fatto che questa non sia la risposta accettata e che non abbia più voti mi rende triste, più informativo e non aggiunge continuamente gestori. +1
Chris O'Kelly,

1
risposta eccellente, avere il callback aperto per aggiungere associazioni è qualcosa che vuoi evitare
Jay Rizzi,

1
per me questo funziona quando l'evento è keydown e rimuovo tutte le condizioni di tagName e rimuovo il click trigger
Isaiyavan Babu Karan

1
Ho anche dovuto passare a "keydown" per farlo funzionare (testato su OS X 10.8.4, Chrome 29 e Firefox 23).
natebeaty,

1
Poiché questa è una risposta precedente, vale la pena notare che è .delegate()stato deprecato in jQuery 3.0, quindi .on()(disponibile da 1.7) è probabilmente la strada da percorrere a questo punto.
jinglesthula,

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

Funziona magnificamente con l'ultima versione dell'interfaccia utente di JQuery (1.8.1). Puoi anche usare: first invece di: last a seconda del pulsante che vuoi impostare come predefinito.

Questa soluzione, rispetto a quella selezionata sopra, ha il vantaggio di mostrare quale pulsante è quello predefinito per l'utente. L'utente può anche TAB tra i pulsanti e premendo INVIO farà clic sul pulsante attualmente attivo.

Saluti.


E se la tua finestra di dialogo ha uno o più campi di immissione testo? Voglio che INVIO invii la finestra di dialogo di accesso quando l'utente si trova nei campi nome utente e password.
David Harkness,

1
@David se si utilizzano i pulsanti della finestra di dialogo jQuery, quindi nascondere il normale pulsante di invio dell'input sul modulo. per esempio. visibilità: nascosta;
Damo,

6

Un modo grezzo ma efficace per rendere questo lavoro più generico:

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

Quindi quando crei una nuova finestra di dialogo puoi farlo:

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

E usalo come una normale finestra di dialogo jquery da allora in poi:

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

Ci sono modi per migliorarlo per farlo funzionare in casi più speciali. Con il codice sopra, selezionerà automaticamente il primo pulsante nella finestra di dialogo come pulsante da attivare quando si preme Invio. Inoltre presuppone che ci sia una sola finestra di dialogo attiva in un dato momento che potrebbe non essere il caso. Ma hai avuto l'idea.

Nota: come accennato in precedenza, il pulsante che si preme su Invio dipende dalla configurazione. Quindi, in alcuni casi vorrai usare il: primo selettore nel metodo .find e in altri potresti voler usare: l'ultimo selettore.


Penso che dovrebbe esserci un .first () come in $ ('. Ui-dialog'). Find ('button'). First (). Trigger ('click'); Altrimenti attiverai il clic di tutti i pulsanti della finestra di dialogo se ce ne sono più di uno.
JustinStolle,

@thejh - No, allega un gestore di eventi keyup a ogni finestra di dialogo, ma solo la finestra di dialogo che contiene l'elemento attivo quando viene premuto il tasto riceverà l'evento.
David Harkness,

6

Invece di ascoltare i codici chiave come in questa risposta (che non sono riuscito a lavorare) puoi associare l'evento di invio del modulo all'interno della finestra di dialogo e quindi fare questo:

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

Quindi, l'intera cosa sarebbe simile a questa

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

Si noti che browser diversi gestiscono la chiave di invio in modo diverso e alcuni non effettuano sempre un invio al momento dell'invio.


Questa sembra la risposta più elegante.
Dan,

Questo non funziona quando ho tre o più input nella stessa finestra di dialogo. Non so perché.
Programmato il

6

Ben Clayton è il più pulito e il più breve e può essere posizionato nella parte superiore della pagina dell'indice prima che qualsiasi dialogo jquery sia stato inizializzato. Tuttavia, vorrei sottolineare che ".live" è stato deprecato. L'azione preferita ora è ".on". Se vuoi che ".on" funzioni come ".live", dovrai utilizzare eventi delegati per collegare il gestore eventi. Inoltre, alcune altre cose ...

  1. Preferisco utilizzare il metodo ui.keycode.ENTER per testare la chiave di invio poiché non è necessario ricordare il codice chiave effettivo.

  2. L'uso di "$ ('. Ui-dialog-buttonpane button: first', $ (this))" per il selettore di clic rende generico l'intero metodo.

  3. Vuoi aggiungere "return false;" per impedire il default e interrompere la propagazione.

In questo caso...

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

4

Non so di più semplice, ma di solito si rintracciava quale pulsante ha il focus attuale. Se lo stato attivo viene modificato in un altro controllo, il "pulsante attivo" rimarrebbe sul pulsante che aveva lo stato attivo per ultimo. Di solito, il "focus pulsante" si avvia sul pulsante predefinito. La tabulazione su un pulsante diverso cambierebbe lo "stato attivo del pulsante". Dovresti decidere se passare a un altro elemento del modulo ripristinerebbe nuovamente il "pulsante attivo" sul pulsante predefinito. Probabilmente avrai anche bisogno di un indicatore visivo diverso da quello predefinito del browser per indicare il pulsante di messa a fuoco in quanto perde la messa a fuoco reale nella finestra.

Una volta che la logica di attivazione dei pulsanti è disattivata e implementata, probabilmente aggiungerei un gestore di chiavi alla finestra di dialogo stessa e fare in modo che invochi l'azione associata al pulsante "focalizzato" attualmente.

EDIT : Sto assumendo che tu voglia essere in grado di premere invio ogni volta che stai compilando elementi del modulo e hai la precedenza che l'azione del pulsante "corrente" ha la precedenza. Se vuoi questo comportamento solo quando il pulsante è effettivamente attivo, la mia risposta è troppo complicata.


3

Ho trovato questa soluzione, funziona su IE8, Chrome 23.0 e Firefox 16.0

Si basa sul commento di 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();
});

Spero possa aiutare chiunque.


Grazie! Mi ha fatto risparmiare un sacco di tempo! :)
Rahul Desai,

3

A volte dimentichiamo il fondamento di ciò che il browser supporta già:

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

Ciò farà sì che la ENTERchiave invii il modulo.


2

Ho fatto in questo modo ...;) Spero che sia utile per qualcuno ..

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

Questo dovrebbe funzionare per attivare il clic del gestore di clic del pulsante. questo esempio presuppone che tu abbia già impostato il modulo nella finestra di dialogo per usare il plugin jquery.validate. ma potrebbe essere facilmente adattato.

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

Mi rendo conto che ci sono già molte risposte, ma credo naturalmente che la mia soluzione sia la più pulita e forse la più breve. Ha il vantaggio che funziona su tutte le finestre di dialogo create in qualsiasi momento in futuro.

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

1
Ehi, grazie per l'aggiornamento, solo una piccola domanda, che cos'è ".ok-button" qui? è la classe che devi applicare sul pulsante predefinito con cui vuoi fare clic con Invio?
UID

Scusate se trovate la domanda furba .. m troppo nuovo in JS / jQuery
UID

@BenClayton: questa risposta potrebbe essere migliorata se la inserissi nel contesto della finestra di dialogo jQueryUI.
Michael Potter,

1

Ecco cosa ho fatto:

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

In questo caso, myForm è un oggetto jQuery contenente l'html del modulo (nota, non ci sono tag "form" lì dentro ... se metti quelli nell'intero schermo si aggiorna quando premi "invio").

Ogni volta che l'utente preme "invio" dall'interno del modulo sarà equivalente a fare clic sul pulsante "ok".

Ciò evita anche il problema di avere il modulo aperto con il pulsante "ok" già evidenziato. Anche se sarebbe utile per i moduli senza campi, se hai bisogno che l'utente riempia gli oggetti, probabilmente vorrai evidenziare il primo campo.


Questa è la soluzione più logica. Ancora meglio se dichiari il tuo pulsante con un id e passi il selettore al find () ma funziona in entrambi i modi. +1
Vincent,

1

fatto e fatto

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

0

se conosci il selettore dell'elemento pulsante:

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

Dovrebbe fare il trucco per te. Questo metterà a fuoco il pulsante ok e invio lo farà "clic", come ci si aspetterebbe. Questa è la stessa tecnica utilizzata nelle finestre di dialogo dell'interfaccia utente nativa.


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

Ho trovato una soluzione abbastanza semplice per questo problema:

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

Questo ha funzionato benissimo per me ..


Faresti bene a includere un riferimento a $ ('# DialogID'). Dialog () come argomento da applicare. Altrimenti $ (this) .close () non avrà il contesto corretto all'interno di TheButton.
Dave,

0

Nessuna di queste soluzioni sembrava funzionare per me in IE9. Ho finito con questo ..

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

Il corpo sottostante viene utilizzato perché la finestra di dialogo DIV è stata aggiunta sul corpo, quindi il corpo ora ascolta l'evento della tastiera. Ha testato su 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

Perché non ho abbastanza reputazione per pubblicare commenti.

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

Anche la risposta modificata da Basemm # 35 aggiunge in Escape per chiudere la finestra di dialogo.


-1

Funziona bene Grazie !!!

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


hmm ... qualcosa di nuovo (rispetto alle risposte precedenti) nel tuo post?
Kleopatra,

-1

Dai alle tue classi di pulsanti e selezionale nel solito modo:

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

    });

  }
});
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.