Wie füge ich eine Bestätigung zum Ajax-Link hinzu?

8

Ich rendere Ajax-Link wie folgt:

l(t('Click here'), 'mypath', array('attributes' => array('id' => 'my-id', 'class' => array('use-ajax'))));

Wie wird der Bestätigungsdialog angezeigt, bevor eine Ajax-Anfrage aufgerufen wird?

Ich mache es wie folgt in Javascript, wie ich es in diesem Thread gefunden habe :

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

 Drupal.ajax['my-id'].beforeSerialize = function () {  

      if(confirm('Are you sure?'))
          return true;
      else
          return false;

  }
 }
}

Wenn ich auf den Link klicke, wird die Ajax-Anfrage nicht aufgerufen, aber der Dialog wird angezeigt. Es ist okay. Das Problem ist, dass nach dem Klicken auf "Abbrechen" im Bestätigungsdialog die Ajax-Anforderung nach dem Schließen des Bestätigungsdialogs aufgerufen wird.

Kann jemand helfen, wie der Bestätigungsdialog funktioniert?

tomas.teicher
quelle
Betrachtet mit options.beforeSerializeoder options.beforeSubmitanstelle von beforeSerialize? Die Dokumentation ist ziemlich schlecht und ich bin mir nicht sicher, welche dieser 3 der richtige Weg ist, aber Sie sollten weniger als 5 Minuten brauchen, um beide zu testen.
Mołot
Danke für den Tipp, aber es hat nicht geholfen
tomas.teicher
OK, tut mir leid das zu hören, da ich etwas ahnungslos war und Ihre Frage vernünftig ist und auch für mich nützlich sein könnte.
Mołot
Hier sollten Sie einen Weg finden, um zu gehen .. drupal.stackexchange.com/questions/14450/…
rémy

Antworten:

4

Ich denke nicht, dass dies der beste Weg ist, da Sie direkt mit Drupals Ajax-Objekt herumspielen.

Der beste Weg, dies zu tun, besteht darin, im Grunde Ihren eigenen Klick-Handler zu schreiben und die Bestätigung selbst zu bearbeiten und dann selbst einen Drupal AJAX-Aufruf auszulösen.

Hier ist ein Beispiel:

l(t('Click here'), 'mypath', array('attributes' => array('id' => 'my-id', 'class' => array('toms-ajax'))));

In Ihrer js-Datei:

(function($) {

Drupal.behaviors.tomsAjaxLinks = {
  attach: function(context, settings) {
    $('.toms-ajax',context).once('toms-ajax').on('click', this.handleAjax);
  },
  handleAjax: function(e) {
    // Cache the anchor link
    var $element = $(this);

    // We need some unique id, either ID of link or create our own
    var nowStamp = new Date().getTime() + Math.floor(Math.random() * (1000 - 0) + 0);
    var base = $element.attr('id') || 'toms-ajax-'+ nowStamp;

    // Change the event type to load, so we can trigger it ourselves
    var drupal_ajax_settings = {
      url : $element.attr('href'),
      event : 'load',
      progress : {
        type: 'throbber',
        message : '',
      }
    };

    // Create the ajax object
    Drupal.ajax[base] = new Drupal.ajax(base, this, drupal_ajax_settings);

    // Your confirmation code e.g. Jquery UI Dialog or something
    // Open dialog
    if(yes) {
      $element.trigger('load');
    } else {
      // Dont trigger ajax
    }
  }
}; 

})(jQuery);

Im Wesentlichen bedeutet dies:

  1. Hängt die handleAjax-Funktion einmal an Ihre ".toms-ajax" -Links an, um sicherzustellen, dass nicht mehrere Ereignishandler angehängt werden
  2. Beim Klicken wird die Funktion handleAjax aufgerufen
  3. Ein entsprechendes Drupal Ajax-Objekt wird mit einer eigenen eindeutigen ID erstellt. Es wird an den Link angehängt und beim Ereignis 'Laden' ausgelöst. Sie bearbeiten dann das Bestätigungsfeld.
  4. Wenn das Bestätigungsfeld den Ajax-Aufruf bestätigt, lösen wir einfach das Ereignis 'load' für das Link-Objekt aus und veranlassen das Drupal AJAX-Objekt, dies zu tun.
JNP Web Developer
quelle
3

Basierend auf der Antwort von @jnpWebDeveloper, jedoch mit einigen Änderungen:

  • Unterstützung für das erneute Anhängen von Ereignissen an über Ajax geladene Inhalte.
  • Unterstützung für benutzerdefinierte Nachrichten vom dataAttribut des Elements.
  • Der Code ist produktionsbereit (es müssen keine Variablen usw. geändert werden).

ajax-confirm-link.js

/**
 * @file
 * Handling of AJAX links with a confirmation message.
 *
 * @code
 * <a href="custom/nojs/path" class="use-ajax-confirm">Link with default message</a>
 * <a href="custom/nojs/path" class="use-ajax-confirm" data-use-ajax-confirm-message="Please confirm your action">Link with custom message</a>
 * @endcode
 */

/*global jQuery, Drupal*/

(function ($) {
  'use strict';
  Drupal.behaviors.ajaxConfirmLink = {
    attach: function (context, settings) {
      $('.use-ajax-confirm').filter('a').once('use-ajax-confirm').on('click', function (event) {
        var $this = $(this);
        // Allow to provide confirmation message in
        // data-use-ajax-confirm-message element attribute.
        var message = $this.data('use-ajax-confirm-message') || Drupal.t('Are you sure you want to do this?');

        if (confirm(message)) {
          // Create ajax event only if action was confirmed.
          var id = $this.attr('id');
          // Generate unique id, if the element does not already have one.
          if (!id || id.trim() == '') {
            id = 'use-ajax-confirm' + new Date().getTime() + Math.floor(Math.random() * 1000);
            $this.attr('id', id);
          }

          Drupal.ajax[id] = new Drupal.ajax(id, this, {
            // 'nojs' to 'ajax' replacement in path performed by Drupal.ajax().
            url: $this.attr('href'),
            event: 'load.use-ajax-confirm'
          });

          $this.trigger('load.use-ajax-confirm');
        }

        return false;
      });
    }
  };
}(jQuery));
Alex Skrypnyk
quelle
0

Wenn Sie die Drupal-Datei "ajax.js" überprüfen, ist der Verknüpfungsprozess ein Sonderfall.

Der Kommentar zu "Drupal.ajax.prototype.beforeSerialize" besagt, dass die Funktion niemals aufgerufen wird, wenn es sich nicht um ein Formular handelt.

In diesem Fall wird "options.beforeSerialize" vor dem Aufruf von jQuery ajax verwendet. Wenn Sie hier Ihre Bestätigung durchführen, können Sie auf OK klicken oder abbrechen. Ein Ajax-Anruf wird immer ausgelöst.

Wenn Sie jedoch stattdessen die Funktion "options.beforeSend" überladen, sollte Ihr Bestätigungsfeld möglicherweise funktionieren, da der Ajax-Aufruf abgebrochen wird, wenn diese Funktion false zurückgibt (jQuery Doc: http://api.jquery.com/jQuery.ajax/ ).

Hier ist das Snippet, das in der Datei "ajax.js" verwendet wird

beforeSend: function (xmlhttprequest, options) {
  ajax.ajaxing = true;
  return ajax.beforeSend(xmlhttprequest, options);
}

Die aktualisierte Version können Sie ausprobieren:

Drupal.ajax['my-id'].beforeSend: function (xmlhttprequest, options) {
  if(confirm('Are you sure?')){
      ajax.ajaxing = true;
      return ajax.beforeSend(xmlhttprequest, options);
  }
  return false;
}

Ich hatte keine Zeit, dieses Snippet zu testen, Upgrades und Kommentare sind willkommen :)

Payou
quelle