web-dev-qa-db-fra.com

Comment ajouter une confirmation au lien ajax?

Je rend le lien ajax comme suit:

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

Comment afficher la boîte de dialogue de confirmation avant l'appel de la demande ajax?

Je le fais comme suit en javascript, comme je l'ai trouvé sur ce fil :

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

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

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

  }
 }
}

Lorsque je clique sur le lien, la demande ajax n'est pas appelée mais la boîte de dialogue apparaît. C'est bon. Le problème est qu'après avoir cliqué sur "Annuler" dans la boîte de dialogue de confirmation, la demande Ajax est ensuite appelée après la fermeture de la boîte de dialogue de confirmation.

Quelqu'un peut-il aider, comment faire fonctionner la boîte de dialogue de confirmation?

8
tomas.teicher

Je ne pense pas que ce soit la meilleure façon de procéder, car vous jouez directement avec l'objet Ajax de Drupal.

La meilleure façon de le faire est d'écrire votre propre gestionnaire de clics et de gérer vous-même la confirmation, puis de déclencher un Drupal AJAX appelez-vous.

Voici un exemple:

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

Dans votre fichier js:

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

Essentiellement, cela signifie:

  1. Attache une fois la fonction handleAjax à vos liens ".toms-ajax" pour nous assurer de ne pas attacher plusieurs gestionnaires d'événements
  2. Au clic, la fonction handleAjax est appelée
  3. Un objet Drupal Ajax correspondant est créé avec son propre ID unique. Il est attaché au lien et déclenché lors de l'événement 'load'. Vous manipulez ensuite la boîte de confirmation.
  4. Si la boîte de confirmation confirme l'ajaxcall, nous déclenchons simplement l'événement 'load' sur l'objet lien et faisons donc l'objet Drupal AJAX object faire sa chose).
4
JNP Web Developer

Basé sur la réponse de @jnpWebDeveloper, mais avec quelques modifications:

  • Prise en charge de la réattachement des événements au contenu chargé via ajax.
  • Prise en charge du message personnalisé à partir de l'attribut data de l'élément.
  • Le code est prêt pour la production (pas besoin de modifier les variables, etc.).

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

Si vous cochez le fichier Drupal "ajax.js", le processus de liaison est un cas particulier.

Le commentaire sur "Drupal.ajax.prototype.beforeSerialize" indique que la fonction ne sera jamais appelée si ce n'est pas un formulaire.

Dans ce cas, "options.beforeSerialize" est utilisé avant l'appel jQuery ajax. Donc, si vous effectuez votre confirmation ici, vous pouvez cliquer sur ok ou annuler, l'appel ajax sera toujours déclenché.

Mais si vous surchargez la fonction "options.beforeSend" à la place, votre boîte de confirmation devrait fonctionner car si cette fonction retourne false, l'appel Ajax est annulé (jQuery Doc: http://api.jquery.com/jQuery. ajax / ).

Voici l'extrait utilisé dans le fichier "ajax.js"

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

La version mise à jour, vous pouvez l'essayer:

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

Je n'ai pas eu le temps de tester cet extrait, les mises à niveau et les commentaires sont les bienvenus :)

0
Payou