it-swarm.com.de

So fügen Sie ein JS-Bestätigungs-Popup hinzu, wenn Sie auf eine #ajax-Schaltfläche klicken

Ich habe eine grundlegende FAPI-Tasteneingabe, die #ajax aktiviert ist und gut funktioniert, aber ich möchte eine JS hinzufügen. "Sind Sie sicher?" Bestätigungs-Popup beim Klicken auf die Schaltfläche, bevor der Code tatsächlich ausgeführt wird, und ich bin mir nicht sicher, wie ich das tun soll, da JS von FAPI den Klick zu essen scheint, bevor ich darauf zugreifen kann, egal was ich tue.

Ich habe versucht, einen Inline-Onclick-Handler hinzuzufügen, wie folgt:

$form['search_filters']['channels']['channel_delete_' . $channel->nid] = array(
  '#type' => 'button',
  '#name' => 'channel_delete_' . $channel->nid,
  '#value' => 'Delete',
  '#attributes' => array(
    'class' => array('confirm'),
    'onclick' => "return confirm('Are you sure you want to delete that?')"
  ),
  '#button_type' => 'no-submit',
  '#ajax' => array(
    'callback' => 'delete_channel_callback',
    'wrapper' => 'channel_container_' . $channel->nid
  ),
);

... was nicht hilft, und ich habe auch versucht hinzuzufügen:

$('.confirm').click(function(e) {
  e.preventDefault();
  alert('Is this recognized')? // never runs
});

im JS meines Moduls, das ebenfalls ignoriert wird.

Irgendwelche anderen Ideen? Gibt es eine Möglichkeit, einen Submit-Handler oben im Stapel hinzuzufügen, der Drupal #ajax erkennt)?

10
Mike Crittenden

Drupal ist ein PHP Framework, und es ist erstaunlich, wie viel Phantasie AJAX Zeug, das Sie mit diesem und dem FAPI bekommen können. Aber es hat Grenzen und für eine Verwendung In diesem Fall würde ich vorschlagen, dass Sie benutzerdefiniertes JavaScript verwenden. Anstatt das normalerweise JavaScript-Dialogfeld zu verwenden, können Sie stattdessen auch die jQuery-Benutzeroberfläche verwenden, um ein themenbezogenes Dialogfeld zu erstellen.

Wie auch immer, das Problem, mit dem Sie konfrontiert sind, wird wahrscheinlich dadurch verursacht, dass Sie AJAX auf der Senden-Schaltfläche) verwenden. Da Sie AJAX für den tatsächlichen Löschaufruf verwenden, preventDefault und dergleichen wird nicht funktionieren.

Was Sie tun müssten, ist so etwas. (Dies ist nicht weit verbreitet, sollte aber funktionieren.)

Drupal.behaviors.module = {
  attach: function() {

    var events = $('.confirm').data('events'); // Get the jQuery events.
    $('.confirm').unbind('click'); // Remove the click events.
    $('.confirm').click(function () {
      if (confirm('Are you sure you want to delete that?')) {
        $.each(events.click, function() {
          this.handler(); // Invoke the click handlers that was removed.
        });
      }
      // Prevent default action.
      return false;
    });
  }
}
15
googletorp

Die Frage ist alt, aber ich habe mich auch dafür interessiert. Meiner Meinung nach ist es am einfachsten, das Klickereignis in Ihrer Ajax-Definition zu verwenden, da Drupal verwendet das Mousedown-Ereignis als Standard:

$form['submit'] = array(
  '#type' => 'submit',
  '#value' => t('some value'),
  '#attributes' => array(
    'class' => array('some-class'),
    ),
  '#ajax' => array(
    'event' => 'click',    //add this line!
    'callback' => 'some_callback',
    'wrapper' => 'some-wrapper',
  ),
);

Dann müssen Sie Ihrer Schaltfläche in Ihrer Javascript-Datei nur noch ein .mousedown() -Ereignis hinzufügen, da es vor dem Klickereignis ausgelöst wird:

$('.some-class').mousedown(function() {
  //do something
});

Wenn Ihre Ajax-Anfrage weiterhin mit dem Mousedown-Ereignis aufgerufen werden soll, können Sie ein benutzerdefiniertes Ereignis verwenden:

//change this line in the Ajax Defintion of your button
'event' => 'click',
//to
'event' => 'custom_event',

Dann können Sie dieses Ereignis im Ereignis .mousedown() Ihrer Javascript-Datei auslösen:

$('.some-class').mousedown(function() {
  //do something
  $('.some-class').trigger('custom_event');
});

Beide Versionen funktionieren!

4
Daniel

bestätigung, dass Jeroen den Code des Googletorp korrigiert.

Ich selbst habe jedoch festgestellt, dass die Ereignisse vom Typ "Mousedown" wieder geboten und gebunden werden müssen. Der Code, der für mich funktioniert hat, ist der folgende:

(function ($) {
  Drupal.behaviors.confirm = {
    attach: function(context, settings) {
      var events =  $('.form-submit-delete').clone(true).data('events');// Get the jQuery events.
      $('.form-submit-delete').unbind('mousedown'); // Remove the click events.
      $('.form-submit-delete').mousedown(function () {
    if (confirm('Are you sure you want to delete that?')) {
      $.each(events.mousedown, function() {
        this.handler(); // Invoke the mousedown handlers that was removed.
      });
    }
    // Prevent default action.
    return false;
      });
    }
  }
})(jQuery);
4
Turtletrail

Haben Sie versucht, Ihr JS innerhalb eines Drupal -Verhaltens) auszuführen? Es kann nur sein, dass Ihr Click-Handler nach Drupal angehängt wird.

In beiden Fällen sollten Sie jedoch in der Lage sein, Drupals Klick-Handler auf der Schaltfläche zu lösen, damit Sie zuerst aufgerufen werden, und Sie können Drupals Ajax-Klick-Handler manuell (und bedingt) aufrufen.

0
Adam DiCarlo

Antworten, um festzustellen, dass der Code von googletorp nicht 100% korrekt ist.

Sie müssen die Zeile, in der die Ereignisse gespeichert sind, folgendermaßen ändern:

var events = $('.confirm').clone(true).data('events'); // Get the jQuery events.

Auf diese Weise beseitigen Sie alle Objektreferenzprobleme. Wenn Sie also die Klickereignisse aufheben, wird die Bindung auch nicht in Ihrem var aufgehoben;)

Beachten Sie außerdem, dass die Methode .data () seit jQuery 1.8 veraltet ist. Das Abrufen von Ereignisdaten erfolgt jetzt über eine interne Datenstruktur:

. data ("events") : jQuery speichert seine ereignisbezogenen Daten in einem Datenobjekt mit dem Namen (warte darauf) events auf jedem Element. Da es sich um eine interne Datenstruktur handelt, wird diese in Version 1.8 aus dem Namensraum für Benutzerdaten entfernt, damit keine Konflikte mit gleichnamigen Elementen auftreten. Auf die Ereignisdaten von jQuery kann weiterhin über jQuery._data (Element, "Ereignisse") zugegriffen werden. Beachten Sie jedoch, dass dies eine interne Datenstruktur ist, die nicht dokumentiert ist und nicht geändert werden sollte.

Quelle: http://blog.jquery.com/2011/11/08/building-a-slimmer-jquery/

0
Jeroen

Ich habe oben viele nützliche Antworten gefunden und konnte mein Formular zum Laufen bringen. Alles zusammen hat für meine Anwendung funktioniert: Eine Schaltfläche zum Löschen von Formularen mit einem Bestätigungsdialog und AJAX Rückruf, um den Inhalt einer Auswahlliste zu ändern.

Das Javascript :

$form['my_form']['delete_button_js'] = array(
  '#markup' => '<script type="text/javascript">
  (function ($) {
     // override the default confirmation dialog behavior
     Drupal.behaviors.confirm = { 

      // Get the jQuery events.
      attach: function(context, settings) {
      var events =  $(\'.deleteButtonClass\').clone(true).data(\'events\'); 

      $(\'.deleteButtonClass\').unbind(\'mousedown\'); // Remove the mousedown event.

      $(\'.deleteButtonClass\').mousedown(function () { 
           // Popup the confirmation
           if (confirm(\'Are you sure you want to delete the Group?\')) {
             // if YES, then we fire the AJAX event 
             $(\'.deleteButtonClass\').trigger(\'deleteGroupEvent\'); 
           }
           // Override the default action.
           return false;
        });
    }
            }
  })(jQuery);
  </script>
  ',
);

Das zu ändernde Formularelement (Auswahlliste) :

$form['my_form']['select_list'] = array(
         '#type' => 'select',
         '#title' => t('My Title'),
         '#options' =>  $optionsArray,
         '#size' => 5,
         '#prefix' => t('<div id="mySelectList">'),
         '#suffix' => t('</div>'),
    }

Die Schaltfläche :

$form['my_form']['delete_button'] = array(
  '#type' => 'button',
  '#value' => 'Delete',

  '#attributes' => array( 
      'class' => array('deleteButtonClass'), 
    ),

  '#ajax' => array (

    // this is the custom event that will be fired from the jQuery function
    'event' => 'deleteGroupEvent', 

    'callback' => 'ajax_delete_callback',
    'wrapper' => 'mySelectList',
    ),

);

nd schließlich der Rückruf AJAX :) :

function ajax_delete_callback ($form, $form_state) {

  // callback implementation code

  return $form['my_form']['select_list'];
}
0
Susanne