it-swarm.com.de

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

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?

8
tomas.teicher

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 genommen Ihren eigenen Klick-Handler zu schreiben und die Bestätigung selbst zu bearbeiten und dann einen Drupal AJAX-Aufruf selbst) 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 seiner eigenen eindeutigen ID erstellt. Es wird an den Link angehängt und beim Ereignis 'Laden' ausgelöst. Anschließend bearbeiten Sie das Bestätigungsfeld.
  4. Wenn das Bestätigungsfeld den Ajaxcall bestätigt, lösen wir einfach das 'load'-Ereignis für das Link-Objekt aus und lassen das Drupal AJAX-Objekt) das tun.
4

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 aus dem Attribut data 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));
3
Alex Skrypnyk

Wenn Sie die Datei Drupal "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 stattdessen die Funktion "options.beforeSend" überladen, sollte Ihr Bestätigungsfeld möglicherweise funktionieren. Wenn diese Funktion false zurückgibt, wird der Ajax-Aufruf abgebrochen (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 :)

0
Payou