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.


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

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.


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.


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.


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.


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

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.


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.


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.


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

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

            }
}

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

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.


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

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.


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

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

0
$('#DialogID').dialog("option", "buttons")["TheButton"].apply()

Das hat super für mich funktioniert ..


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

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

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.


-1

Es funktioniert gut Danke !!!

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


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

    });

  }
});
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.