#ajaxボタンをクリックしたときにJS確認ポップアップを追加する方法


10

#ajaxが有効になっている基本的なFAPIボタン入力があり、それは正常に機能していますが、JSを追加しますか?「本当によろしいですか?」コードが実際に実行される前にボタンをクリックすると確認ポップアップが表示されます。FAPIのJSは、何をしようとそれに到達する前にクリックを食べているようなので、その方法はわかりません。

私は次のようにインラインのonclickハンドラーを追加しようとしました:

$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
  ),
);

...それは役に立たない、そして私はまた追加しようとしました:

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

私のモジュールのJSでも無視されます。

他のアイデアは?Drupal #ajaxが認識するスタックの最上部に送信ハンドラーを追加する方法はありますか?

回答:


15

DrupalはPHPフレームワークであり、それとFAPIを使用してどれだけ多くの豪華なAJAX要素を取得できるかは驚くべきことです。しかし、それには制限があり、このようなユースケースでは、カスタムJavaScriptを使用することをお勧めします。また、通常はJavaScriptダイアログを使用する代わりに、jQuery UIを使用してテーマ適用可能ダイアログを作成することもできます。

とにかく、あなたが直面している問題は、おそらく送信ボタンでAJAXを使用しているために引き起こされています。実際の削除呼び出しにAJAXを使用しているためpreventDefaultなどは機能しません。

あなたがしなければならないことは、このようなものです。(これは広くテストされていませんが、動作するはずです。)

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

$( '。confirm')。unbind( 'mousedown');も追加しました。Drupalは 'mousedown'イベントもリストしています。
milkovsky

ユーザーが確認ダイアログをキャンセルしてもう一度クリックすると、ボタンが壊れませんか?(なぜなら$('.confirm').unbind('click');)...または私はそれを間違って読んでいますか?よく知らないunbind
ErichBSchulz 2013年

1
@ErichBSchulz Unbindは、ページのロード時に呼び出されるattachメソッドによって1回だけ呼び出されます。
googletorp

gist.github.com/guoxiangke/0dffa7722a67f052c7ce Uncaught TypeError:未定義のプロパティ「クリック」を読み取れませんか?????? node / add / content-typeにフォームがあり、それをajaxします
。js

4

Jeroenがgoogletorpのコードを修正していることを確認します。

しかし、私自身、「マウスダウン」タイプのイベントは入札を解除して再度バインドする必要があることを発見しました。だから私のために働いたコードは次のとおりです:

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

実際に必要でない限り、DOMオブジェクトのクローンを作成することは、リソースの無駄遣いです。
googletorp

こんにちは、私は同じ質問に会いましたが、すべてうまくいきますが、jsエラーに遭遇しました。
bluesky_still 2014年

これが私が仕事に取りかかることができる唯一の解決策です。ここではクローニングが重要です。クローンがない場合、[OK]をクリックすると、アラートが即座に再表示されます。
Felix Eve

4

質問は古いですが、私も興味を持っていました。私の意見では、Drupalはデフォルトとしてmousedownイベントを使用するため、Ajax定義でクリックイベントを使用するのが最も簡単な方法です。

$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',
  ),
);

次に.mousedown()、JavaScriptイベントのボタンにイベントを追加する必要があります。これは、イベントがクリックイベントの前に発生するためです。

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

Ajaxリクエストをmousedownイベントで呼び出したい場合は、カスタムイベントを使用できます。

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

次に.mousedown()、JavaScriptファイルのイベントでこのイベントをトリガーできます。

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

どちらのバージョンでも機能します。


うん!これはあなたが望むことをするので、私はこれが好きです:必要なときに呼び出すことができるDrupalの既製のプロセスのハンドルを提供します。Nb。preventDefaultそれでも、フォームの通常の(非JS)送信を防ぐために、クリックハンドラーにが必要でした。
artfulrobot 2015年

0

Drupalビヘイビアー内でJSを実行してみましたか?Drupalの後にクリックハンドラーが接続されている可能性があります。

どちらの方法でも、ボタンでDrupalのクリックハンドラーのバインドを解除して、最初に呼び出され、DrupalのAjaxクリックハンドラーを手動で(および条件付きで)呼び出すことができるようにする必要があります。


0

googletorpのコードは100%正しくないことに注意してください。

イベントが格納されている行を次のように変更する必要があります。

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

このようにして、オブジェクト参照の問題を排除するため、クリックイベントのバインドを解除しても、変数のバインドは解除されません;)

また、jQuery 1.8以降、.data()メソッドは推奨されなくなりました。イベントデータの取得は、内部データ構造を介して行われます。

.data(“ events”):jQueryは、そのイベント関連データを、各要素のイベント(イベント待ち)という名前のデータオブジェクトに格納します。これは内部データ構造であるため、1.8ではユーザーデータの名前空間から削除されるため、同じ名前の項目と競合しません。jQueryのイベントデータはjQuery._data(element、 "events")を介して引き続きアクセスできますが、これはドキュメント化されていない内部データ構造であり、変更しないでください。

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


0

上記の多くの有用な答えを見つけ、フォームを機能させることができました。すべてをまとめると、これは私のアプリケーションで機能したものです。確認ダイアログと選択リストの内容を変更するためのAJAXコールバックを備えた削除フォームボタン。

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>
  ',
);

変更するフォーム要素(選択リスト):

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

ボタン:

$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',
    ),

);

そして最後に、AJAXコールバック:

function ajax_delete_callback ($form, $form_state) {

  // callback implementation code

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

-1

drupalのmisc / ajax.jxファイルを変更して、これを修正しました。

ajax.jsファイルのコピーを作成してカスタムモジュールを配置しDrupal.ajax = function (base, element, element_settings) { 、beforeSendで関数を変更します。

beforeSend: function (xmlhttprequest, options) {

    if( ajax.url =='/?q=field_collection/ajax'){ // condition for when click on the Remove button
      if (confirm('Are you sure you want to remove this?')) {
       ajax.ajaxing = true;
       return ajax.beforeSend(xmlhttprequest, options);
      }
      xmlhttprequest.abort();
    } else{
        ajax.ajaxing = true;
        return ajax.beforeSend(`xmlhttprequest`, options);   
     }    
},

私にとってはうまくいきます。


1
これはハッキングコアとしてカウントされ、おそらく回避する必要があります。
Mołot

1
そして完全に不要です-en.wikipedia.org/wiki/Monkey_patch
Clive

これが、この概念を二重の確認ボックスを表示せずに機能させる唯一の方法でした。唯一の例外は、ifステートメントでajax.url == 'field_collection_remove_js'をチェックする必要があったことです。多分それは私が使っているDrupalのバージョンのせいですか?
リチャード

-1

少し古いかもしれませんが、なぜ私たちは単に使用できないのか疑問に思っています:

(function($, Drupal, window, document, undefined) {

Drupal.behaviors.oc_ua_pc = {
  attach: function(context, settings) {
    $('#button').click(function () {
      if(confirm('This action cannot be undone and you cannot change the form later. Do you want to submit?')) {
        return;
      }

      return false;
    });
  }
}
})(jQuery, Drupal, this, this.document);

Drupalはmousedownイベントにバインドするので、クリックイベントハンドラーは起動しません。
Felix Eve

DrupalはPHPまたはJSの動作を変更しません。なぜクリックイベントをリッスンしないのですか?ここでは、DrupalはJSコードを添付するために使用されています。サイトが読み込まれると、Drupalはその役割を果たします。JSリスナーは全員揃っていますよね?;)
schlicki 2017年

あなたは良い質問を投げかけ、正直に言うと、クリックイベントが発生しない理由がわかりません。しかし、広範囲にわたるテストを行った結果、そうではないことが確認できました。理解を深めるには、おそらくDrupalのajax.jsを読む必要があります。
Felix Eve
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.