Senden Sie das jQuery-UI-Dialogfeld unter <Eingabe>

131

Ich habe ein jQuery UI-Dialogfeld mit einem Formular. Ich möchte einen Klick auf eine der Schaltflächen des Dialogfelds simulieren, damit Sie nicht die Maus oder die Registerkarte verwenden müssen. Mit anderen Worten, ich möchte, dass es sich wie ein normales GUI-Dialogfeld verhält, in dem das Drücken der Schaltfläche "OK" simuliert wird.

Ich gehe davon aus, dass dies eine einfache Option für das Dialogfeld ist, finde sie jedoch nicht in der Dokumentation zur jQuery-Benutzeroberfläche . Ich konnte jede Formulareingabe mit keyup () binden, wusste aber nicht, ob es einen einfacheren / saubereren Weg gibt. Vielen Dank.

CMB
quelle
Wenn Sie die Verwendung eines Formulars vermeiden möchten und wiederverwendbaren Code wünschen, habe ich hier eine gute Antwort gegeben: stackoverflow.com/a/9628800/329367
Darren

Antworten:

153

Ich weiß nicht, ob das jQuery-UI-Widget eine Option enthält , aber Sie können das keypressEreignis einfach an das div binden , das Ihren Dialog enthält ...

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

Dies wird unabhängig davon ausgeführt, welches Element den Fokus in Ihrem Dialogfeld hat. Dies kann je nach Wunsch eine gute Sache sein oder auch nicht.

Wenn Sie dies zur Standardfunktionalität machen möchten, können Sie diesen Code hinzufügen:

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

Hier ist eine detailliertere Ansicht, wie es aussehen würde:

$( "#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");
      }
    });
  };
});
Casey Williams
quelle
2
Trotzdem habe ich es gefunden: Füge "open" zum Dialog hinzu (wie close, modal, bgiframe usw.) und hänge den Keyup-Handler dort ein.
Milan Babuškov
5
Für Webkit (Safari / Chrome) funktioniert dies nur, wenn ich "Keydown" anstelle von "Keyup" mache. Ich bin mir nicht sicher, ob es sich um eine kürzlich vorgenommene Änderung handelt oder ob es darauf ankommt, dass meine Seite auch eine echte Form enthält. Trotzdem danke für den Tipp!
Nicholas Piasecki
12
Anstelle von if (e.keyCode == 13) können Sie if (e.keyCode === $ .ui.keyCode.ENTER) verwenden, um die Lesbarkeit zu verbessern.
A. Murray
2
Ich habe diese Antwort abgelehnt. Während es kurz und ordentlich ist, wird in Firefox 7.0.1 auch die Schaltfläche "OK" ausgelöst, wenn der Benutzer etwas aus dem Dropdown-Feld für die automatische Vervollständigung auswählt, z. B. eine zuvor eingegebene E-Mail-Adresse.
Cburgmer
2
Es ist eine schlechte Idee, sich an Ereignisse in "open:" zu binden. Dies führt dazu, dass es bei jedem Öffnen des Dialogfelds erneut gebunden wird. Wenn das Dialogfeld also zweimal geöffnet wird, wird der Ereignishandler zweimal aufgerufen.
Elezar
67

Ich habe die obigen Antworten zusammengefasst und wichtige Dinge hinzugefügt

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

Vorteile:

  1. Verbieten - Taste auf nicht kompatiblen Elementen wie eingeben textarea, select, buttonoder Eingaben mit Typ - Taste, stellen Sie auf Benutzer klicken eingeben textareaund das Formular anstatt sich neue Zeile vorgelegt bekommen!
  2. Die Bindung wird einmal durchgeführt. Vermeiden Sie es, den Rückruf des Dialogfelds "Öffnen" zum Binden der Eingabetaste zu verwenden, um zu vermeiden, dass dieselbe Funktion bei jedem Öffnen des Dialogfelds immer wieder gebunden wird
  3. Vermeiden Sie es, vorhandenen Code zu ändern, wie einige der obigen Antworten nahe legen
  4. Verwenden Sie 'delegate' anstelle des veralteten 'live' und vermeiden Sie die Verwendung der neuen 'on'-Methode, um mit älteren Versionen von jquery arbeiten zu können
  5. Da wir delegate verwenden, bedeutet dies, dass der obige Code bereits vor dem Initialisieren des Dialogs geschrieben werden kann. Sie können es auch in Head-Tag setzen, auch ohne$(document).ready
  6. Außerdem bindet der Delegat nur einen Handler an documentjeden Dialog und bindet ihn nicht wie in einigen Codes oben an jeden Dialog, um die Effizienz zu erhöhen
  7. Funktioniert auch mit dynamisch generierten Dialogen wie $('<div><input type="text"/></div>').dialog({buttons: .});
  8. Arbeitete mit dh 7/8/9!
  9. Vermeiden Sie die Verwendung des langsamen Wahlschalters :first
  10. Vermeiden Sie Hacks wie in den Antworten hier , um eine versteckte Schaltfläche zum Senden zu erstellen

Nachteile:

  1. Führen Sie die erste Schaltfläche als Standardschaltfläche aus. Sie können eine andere Schaltfläche mit auswählen eq()oder eine Funktion in der if-Anweisung aufrufen
  2. Alle Dialoge haben das gleiche Verhalten, das Sie filtern können, indem Sie Ihren Selektor spezifischer machen, dh '#dialog' anstelle von '.ui-dialog'

Ich weiß, dass die Frage alt ist, aber ich hatte das gleiche Bedürfnis, also teilte ich die Lösung, die ich verwendet habe.

Basemm
quelle
4
Die Tatsache, dass dies nicht die akzeptierte Antwort ist und nicht mehr Stimmen hat, macht mich traurig, am informativsten und fügt nicht ständig Handler hinzu. +1
Chris O'Kelly
1
Hervorragende Antwort: Der offene Rückruf zum Hinzufügen von Bindungen ist etwas, das Sie vermeiden möchten
Jay Rizzi,
1
Für mich funktioniert dies, wenn das Ereignis geschlossen ist und ich alle Bedingungen von tagName entferne und den Klick-Trigger entferne
Isaiyavan Babu Karan
1
Ich musste auch zu "keydown" wechseln, damit dies funktioniert (getestet unter OS X 10.8.4, Chrome 29 und Firefox 23).
Natebeaty
1
Da dies eine ältere Antwort ist, ist es erwähnenswert, dass .delegate()sie in jQuery 3.0 veraltet war. Daher ist .on()(verfügbar seit 1.7) wahrscheinlich der richtige Weg zu diesem Zeitpunkt.
Jinglesthula
13
$('#dialogBox').dialog('open');
$('.ui-dialog-buttonpane > button:last').focus();

Es funktioniert wunderbar mit der neuesten Version von JQuery UI (1.8.1). Sie können auch: first anstelle von: last verwenden, je nachdem, welche Schaltfläche Sie als Standard festlegen möchten.

Diese Lösung hat im Vergleich zu der oben ausgewählten den Vorteil, dass angezeigt wird, welche Schaltfläche die Standardschaltfläche für den Benutzer ist. Der Benutzer kann auch zwischen den Schaltflächen tippen und durch Drücken der EINGABETASTE auf die aktuell fokussierte Schaltfläche klicken.

Prost.

Mario Awad
quelle
Und was ist, wenn Ihr Dialogfeld ein oder mehrere Texteingabefelder enthält? Ich möchte, dass ENTER den Anmeldedialog sendet, wenn sich der Benutzer in den Feldern Benutzername und Kennwort befindet.
David Harkness
1
@David Wenn Sie die jQuery-Dialogschaltflächen verwenden, blenden Sie einfach die normale Schaltfläche zum Senden von Eingaben im Formular aus. z.B. Sichtbarkeit: versteckt;
Damo
6

Ein grober, aber effektiver Weg, um diese Arbeit allgemeiner zu gestalten:

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

Wenn Sie dann einen neuen Dialog erstellen, können Sie Folgendes tun:

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

Und verwenden Sie es danach wie einen normalen Abfragedialog:

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

Es gibt Möglichkeiten, dies zu verbessern, damit es in besonderen Fällen funktioniert. Mit dem obigen Code wird automatisch die erste Schaltfläche im Dialogfeld als Schaltfläche ausgewählt, die ausgelöst wird, wenn die Eingabetaste gedrückt wird. Außerdem wird davon ausgegangen, dass zu einem bestimmten Zeitpunkt nur ein aktiver Dialog vorhanden ist, was möglicherweise nicht der Fall ist. Aber du kommst auf die Idee.

Hinweis: Wie oben erwähnt, hängt die Taste, die bei der Eingabe gedrückt wird, von Ihrem Setup ab. In einigen Fällen möchten Sie also den: first-Selektor in der .find-Methode verwenden, in anderen möchten Sie möglicherweise den: last-Selektor verwenden.

Karim
quelle
Ich denke, es sollte ein .first () drin sein, wie in $ ('. UI-dialog'). Find ('button'). First (). Trigger ('click'); Andernfalls lösen Sie das Klicken aller Schaltflächen des Dialogfelds aus, wenn mehrere vorhanden sind.
JustinStolle
@thejh - Nein, es wird jedem Dialogfeld ein Keyup-Ereignishandler hinzugefügt, aber nur das Dialogfeld, das das Element mit Fokus enthält, wenn die Taste gedrückt wird, empfängt das Ereignis.
David Harkness
6

Anstatt auf Schlüsselcodes wie in dieser Antwort zu achten (die ich nicht bearbeiten konnte), können Sie sich im Dialogfeld an das Übermittlungsereignis des Formulars binden und dann Folgendes tun:

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

Das Ganze würde also so aussehen

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

Beachten Sie, dass verschiedene Browser die Eingabetaste unterschiedlich behandeln und einige bei der Eingabe nicht immer eine Übermittlung durchführen.

Salida Software
quelle
Dies scheint die eleganteste Antwort zu sein.
Dan
Dies funktioniert nicht, wenn ich drei oder mehr Eingaben im selben Dialogfeld habe. Ich weiß nicht warum.
Programm vom
6

Ben Clayton's ist das sauberste und kürzeste und kann oben auf Ihrer Indexseite platziert werden, bevor JQuery-Dialoge initialisiert wurden. Ich möchte jedoch darauf hinweisen, dass ".live" veraltet ist. Die bevorzugte Aktion ist jetzt ".on". Wenn ".on" wie ".live" funktionieren soll, müssen Sie delegierte Ereignisse verwenden, um den Ereignishandler anzuhängen. Auch ein paar andere Dinge ...

  1. Ich bevorzuge die Verwendung der Methode ui.keycode.ENTER, um den Eingabetaste zu testen, da Sie sich nicht an den tatsächlichen Schlüsselcode erinnern müssen.

  2. Durch die Verwendung von "$ ('. UI-dialog-buttonpane button: first', $ (this))" für die Klickauswahl wird die gesamte Methode generisch.

  3. Sie möchten "return false" hinzufügen. um die Standardeinstellung zu verhindern und die Weitergabe zu stoppen.

In diesem Fall...

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

Ich weiß nicht, was einfacher ist, aber normalerweise würden Sie verfolgen, welche Schaltfläche den aktuellen Fokus hat. Wenn der Fokus auf ein anderes Steuerelement geändert wird, bleibt der "Tastenfokus" auf der Taste, die zuletzt den Fokus hatte. Normalerweise beginnt der "Tastenfokus" auf Ihrer Standardtaste. Wenn Sie auf eine andere Schaltfläche tippen, wird der "Tastenfokus" geändert. Sie müssten entscheiden, ob das Navigieren zu einem anderen Formularelement den "Schaltflächenfokus" wieder auf die Standardschaltfläche zurücksetzen würde. Wahrscheinlich benötigen Sie auch eine andere visuelle Anzeige als die Standardeinstellung des Browsers, um die fokussierte Schaltfläche anzuzeigen, da sie den tatsächlichen Fokus im Fenster verliert.

Sobald Sie die Schaltflächenfokuslogik heruntergefahren und implementiert haben, würde ich wahrscheinlich dem Dialog selbst einen Key-Handler hinzufügen und die Aktion aufrufen, die der aktuell "fokussierten" Schaltfläche zugeordnet ist.

BEARBEITEN : Ich gehe davon aus, dass Sie jederzeit die Eingabetaste drücken möchten, wenn Sie Formularelemente ausfüllen und die Aktion "Aktuell" Vorrang hat. Wenn Sie dieses Verhalten nur wünschen, wenn die Schaltfläche tatsächlich fokussiert ist, ist meine Antwort zu kompliziert.

Tvanfosson
quelle
3

Ich habe diese Lösung gefunden, sie funktioniert unter IE8, Chrome 23.0 und Firefox 16.0

Es basiert auf dem Kommentar von 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();
});

Ich hoffe es hilft jemandem.

Pablo Oña
quelle
Vielen Dank! Das hat mir viel Zeit gespart! :)
Rahul Desai
3

Manchmal vergessen wir die Grundlagen dessen, was der Browser bereits unterstützt:

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

Dadurch sendet der ENTERSchlüssel das Formular.

Seifu
quelle
2

Ich habe es so gemacht ...;) Hoffe es wird jemandem helfen ..

$(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;
    }
});
Stanislav Vychegzhanin
quelle
2

Dies sollte funktionieren, um das Klicken des Klick-Handlers der Schaltfläche auszulösen. In diesem Beispiel wird davon ausgegangen, dass Sie das Formular bereits im Dialogfeld für die Verwendung des Plugins jquery.validate eingerichtet haben. könnte aber leicht angepasst werden.

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

            }
}
Timbrown
quelle
1

Mir ist klar, dass es bereits viele Antworten gibt, aber ich denke natürlich, dass meine Lösung die sauberste und möglicherweise die kürzeste ist. Es hat den Vorteil, dass es in allen Dialogen funktioniert, die zu einem späteren Zeitpunkt erstellt werden.

$(".ui-dialog").live("keyup", function(e) {
    if (e.keyCode === 13) {
        $('.ok-button', $(this) ).first().click();
    }
});
Ben Clayton
quelle
1
Hey danke fürs Update, nur eine kleine Frage, was ist ".ok-button" hier? Ist es die Klasse, die Sie auf die Standardschaltfläche anwenden müssen, auf die Sie mit der Eingabetaste klicken möchten?
UID
Entschuldigung, wenn Sie die Frage sily finden .. bin zu neu in JS / jQuery
UID
@ BenClayton: Diese Antwort könnte verbessert werden, wenn Sie sie in den Kontext von jQueryUI Dialog stellen würden.
Michael Potter
1

Folgendes habe ich getan:

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 diesem Fall ist myForm ein jQuery-Objekt, das das HTML des Formulars enthält (beachten Sie, dass dort keine "Formular" -Tags vorhanden sind ... Wenn Sie diese in den gesamten Bildschirm einfügen, wird sie aktualisiert, wenn Sie die Eingabetaste drücken).

Immer wenn der Benutzer im Formular die Eingabetaste drückt, entspricht dies dem Klicken auf die Schaltfläche "OK".

Dies vermeidet auch das Problem, dass das Formular geöffnet ist und die Schaltfläche "OK" bereits markiert ist. Während dies für Formulare ohne Felder gut wäre, möchten Sie wahrscheinlich, dass das erste Feld hervorgehoben wird, wenn der Benutzer etwas ausfüllen muss.

Tyler
quelle
Dies ist die logischste Lösung. Noch besser, wenn Sie Ihre Schaltfläche mit einer ID deklarieren und den Selektor an find () übergeben, aber so oder so funktioniert. +1
Vincent
1

gemacht und gemacht

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

Wenn Sie die Auswahl der Schaltflächenelemente kennen:

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

Sollte den Trick für Sie tun. Dadurch wird die OK-Schaltfläche fokussiert, und durch Eingabe wird wie erwartet darauf geklickt. Dies ist die gleiche Technik, die in nativen UI-Dialogen verwendet wird.

sandesh247
quelle
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();}
   });
LeCram
quelle
0

Ich habe eine recht einfache Lösung für dieses Problem gefunden:

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();
    }
});
Robert Schmidt
quelle
0
$('#DialogID').dialog("option", "buttons")["TheButton"].apply()

Das hat super für mich funktioniert ..

Peter
quelle
Sie sollten einen Verweis auf $ ('# DialogID'). Dialog () als anzuwendendes Argument einfügen. Andernfalls hat $ (this) .close () nicht den richtigen Kontext in TheButton.
Dave
0

Keine dieser Lösungen schien in IE9 für mich zu funktionieren. Ich endete damit ..

$('#my-dialog').dialog({
    ...
    open: function () {
        $(this).parent()
               .find("button:eq(0)")
               .focus()
               .keyup(function (e) {
                   if (e.keyCode == $.ui.keyCode.ENTER) {
                       $(this).trigger("click");
                   };
               });
    }
});
Paul Martin
quelle
0

Der folgende Körper wird verwendet, weil der Dialog DIV auf dem Körper hinzugefügt wurde, sodass der Körper jetzt das Tastaturereignis abhört. Es wurde auf IE8,9,10, Mojila, Chrome getestet.

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

Weil ich nicht genug Ruf habe, um Kommentare zu posten.

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

Geänderte Antwort von Basemm # 35 ebenfalls in Escape hinzufügen, um den Dialog zu schließen.

Liam Mitchell
quelle
-1

Es funktioniert gut Danke !!!

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

Durgaprasad Katari
quelle
hmm ... etwas Neues (im Vergleich zu früheren Antworten) in deinem Beitrag?
Kleopatra
-1

Geben Sie Ihren Schaltflächen Klassen und wählen Sie sie wie gewohnt aus:

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

    });

  }
});
yPhil
quelle