web-dev-qa-db-ja.com

確認をajaxリンクに追加するにはどうすればよいですか?

私は次のようにajaxリンクをレンダリングしています:

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

Ajaxリクエストが呼び出される前に確認ダイアログを表示する方法は?

私は this thread で見つけたように、javascriptで次のように実行します。

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

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

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

  }
 }
}

リンクをクリックすると、ajaxリクエストが呼び出されず、ダイアログが表示されます。大丈夫です。問題は、確認ダイアログで[キャンセル]をクリックした後、確認ダイアログを閉じた後にAjaxリクエストが呼び出されることです。

確認ダイアログを機能させる方法を教えてください。

8
tomas.teicher

DrupalのAjaxオブジェクトを直接いじっているので、これが最善の方法だとは思いません。

これを行う最良の方法は、基本的に独自のクリックハンドラーを記述し、確認を自分で処理してから、Drupal AJAX自分を呼び出すことです。

次に例を示します。

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

あなたの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);

基本的に、これは次のことを行います。

  1. 複数のイベントハンドラーをアタッチしないように、handleAjax関数を「.toms-ajax」リンクに1回アタッチします。
  2. クリックすると、handleAjax関数が呼び出されます
  3. 対応するDrupal Ajaxオブジェクトは独自の一意のIDで作成されます。これはリンクに接続され、イベント「load」でトリガーされます。次に、確認ボックスを処理します。
  4. 確認ボックスがajaxcallを確認した場合、リンクオブジェクトで「load」イベントをトリガーするだけなので、Drupal AJAXオブジェクトにそれを実行させます。
4

@jnpWebDeveloperの回答に基づいていますが、いくつかの変更があります。

  • Ajax経由でロードされたコンテンツへのイベントの再アタッチのサポート。
  • 要素のdata属性からのカスタムメッセージのサポート。
  • コードは本番環境に対応しています(変数などを変更する必要はありません)。

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

Drupal "ajax.js"ファイルを確認すると、リンクプロセスは特殊なケースです。

「Drupal.ajax.prototype.beforeSerialize」に関するコメントには、フォームでない場合、関数が呼び出されることは決してないとのことです。

その場合、jQuery ajax呼び出しの前に "options.beforeSerialize"が使用されます。したがって、ここで確認を実行すると、[OK]または[キャンセル]をクリックできます。ajax呼び出しは常にトリガーされます。

しかし、代わりに "options.beforeSend"関数をオーバーロードすると、おそらく確認ボックスが機能するはずです。その関数がfalseを返すと、Ajax呼び出しがキャンセルされるためです(jQuery Doc: http://api.jquery.com/jQuery。 ajax / )。

これが「ajax.js」ファイルで使用されるスニペットです

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

更新されたバージョン、それを試すことができます:

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

私はこのスニペットをテストする時間がありませんでした、アップグレードとコメントは大歓迎です:)

0
Payou