リンクをクリックしたときにajaxを介してノードを更新するモジュールがあります。
リンクはトグルです。最初のクリックでノードを値1で更新し、その後のクリックで値0でノードを更新する必要があります。
以下のコードは、ページの読み込み後の最初のクリックでは機能しますが、その後のクリックでは機能しません。クリックするたびにDrupal.attachBehaviorsを呼び出し/トリガーする必要があると思いますが、これを行う方法がわかりません。
モジュール
function mymodule_menu() { $items['mypath/%/%/ajax'] = array( 'title' => 'My title', 'page callback' => 'mymodule_ajax_callback', 'page arguments' => array(1,2), 'access arguments' => array('access content'), 'type' => MENU_CALLBACK, ); ... } function mymodule_ajax_callback($id, $status) { //Validation[...] //Node Update using $id as the nid and $status as the field value[...] // Define a new array to hold our AJAX commands. $ajax_commands = array(); // Create a new AJAX command that replaces the #div. $replacedivid = '#status'.$id; $replacestring = '<div id="status'.$id.'"><a data-url="'.base_path().'mypath/'.$id.'/'.$new_status.'/ajax" title="This item is marked as '.$status_text.'" id="statuslink'.$id.'" class="midui">'.$status_text.'</a></div>'; $ajax_commands[] = ajax_command_replace($replacedivid, $replacestring); return drupal_json_output($ajax_commands); }
Javascript
(function ($) { Drupal.behaviors.mymodule = { attach: function(context, settings) { var $uilink = $('.midui'); //find all links for (var i=0;i<$uilink.length;i++) { //Loop var $link = $('#' + $uilink[i].id); if (!$link.hasClass("middone")) { new Drupal.ajax('#' + $uilink[i].id, $link, { url: $link.attr('data-url'), effect: 'fade', settings: {}, progress: { type: 'throbber' }, event: 'click tap' }); $link.addClass("middone"); //add class when we're done } } } } })(jQuery);
これまでに試したこと:
(a)関数とajax_command_invoke(NULL, 'mymodule');
組み合わせた$ ajax_commands配列にを追加し$.fn.mymodule
ます
(b)$('body').ajaxSuccess(Drupal.attachBehaviors);
JavaScriptに追加します。ajaxCompleteも試しました。ドキュメントでも試してみました。
(c)ここで詳しく説明されているようにカスタムコマンドを作成しますhttp://www.jaypan.com/tutorial/calling-function-after-ajax-event-drupal-7
注:挿入または変更される新しいhtmlを「ajaxify」するためにクリックするたびにattachBehaviorsをトリガーするだけの問題であることはわかっています。リンクをクリックして、コンソールにDrupal.attachBehaviors()と入力すると、「middone」クラスが追加されたことからわかるように、リンクはJavaScriptによって再び処理され、再度クリックできるようになります。
注:また興味深いことに、$ajax_commands
コールバック関数の最後で空のままにしてそれ(空の配列)を返すと、1回目以降のクリックでリンクがクリック可能なままになります。私が探している機能(トグル)があります。ただし、クリックするたびにhtmlは変更されないため、ユーザーがトグルがオンかオフかを知る方法はありません。
どんなポインタでも大歓迎です。
================================================== =====
部分的な答え:
Drupalのajax.js成功関数は、フォームの動作のみを再アタッチします(私はそう思いますか?)
if (this.form) {
var settings = this.settings || Drupal.settings;
Drupal.attachBehaviors(this.form, settings);
}
そこで、すべてのajaxオブジェクトの成功関数をハックすることにしました。
Javascriptは次のようになります
(function ($) {
Drupal.behaviors.mymodule = {
attach: function(context, settings) {
var $uilink = $('.midui'); //find all links
for (var i=0;i<$uilink.length;i++) { //Loop
var $link = $('#' + $uilink[i].id);
if (!$link.hasClass("middone")) {
myAjax = new Drupal.ajax('#' + $uilink[i].id, $link, {
url: $link.attr('data-url'),
effect: 'fade',
settings: {},
progress: {
type: 'throbber'
},
event: 'click tap'
});
myAjax.options.success = function (response, status) {
//Trigger Attach Behaviors
setTimeout(function(){Drupal.attachBehaviors($(myAjax.selector))}, 0);
// Sanity check for browser support (object expected).
// When using iFrame uploads, responses must be returned as a string.
if (typeof response == 'string') {
response = $.parseJSON(response);
}
return myAjax.success(response, status);
}
$link.addClass("middone"); //add class when we're done
}
}
}
}
})(jQuery);
成功関数は、動作を再接続するための行が追加されたajax.jsからのデフォルトのコピーペーストです。何らかの理由Drupal.attachBehaviors
で、タイマー内にある必要があります。私が無視する理由のために、それだけでそれを手に入れることはできません。
誰かがよりエレガントな解決策を見つけたり、タイマーの奇妙さを説明したりできる場合に備えて、この質問はほとんど公開しません。
どうもありがとう