Eu tenho um módulo que atualiza um nó via ajax quando um link é clicado.
O link é uma alternância, ele deve atualizar o nó com o valor 1 no primeiro clique e, em seguida, com o valor 0 no clique subsequente, etc. Como ativar / desativar algo.
O código abaixo funciona no primeiro clique após o carregamento da página, mas não nos cliques subsequentes. Acredito que Drupal.attachBehaviors deve ser chamado / acionado após cada clique, mas não consigo descobrir como fazer isso.
O Módulo
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);
O que eu tentei até agora:
(a) Adicione um ajax_command_invoke(NULL, 'mymodule');
ao array $ ajax_commands juntamente com uma $.fn.mymodule
função
(b) Adicione $('body').ajaxSuccess(Drupal.attachBehaviors);
ao meu javascript. o ajaxComplete tentou também. Tentei no documento também.
(c) Crie um comando personalizado conforme detalhado aqui http://www.jaypan.com/tutorial/calling-function-after-ajax-event-drupal-7
Nota: Eu sei que é apenas uma questão de acionar o attachBehaviors após cada clique para 'ajaxify' o novo html sendo inserido / modificado. Se eu clicar no link e digitar Drupal.attachBehaviors () no console, o link será processado novamente pelo meu javascript, conforme evidenciado pela adição da classe 'middone', e poderá ser clicado novamente.
Nota: Também é interessante que, se eu deixar a caixa $ajax_commands
vazia e a retornar (matriz vazia) no final da função de retorno de chamada, o link permanecerá clicável nos primeiros e subsequentes cliques. Ele terá a funcionalidade que estou procurando (uma alternância). No entanto, como nenhuma alteração é feita no html após cada clique, não há como o usuário saber se a alternância está ativada ou desativada.
Qualquer ponteiro seria muito apreciado.
==================================================== =====
Resposta parcial:
A função de sucesso Drupal ajax.js reaparece apenas comportamentos para formulários (eu acho?)
if (this.form) {
var settings = this.settings || Drupal.settings;
Drupal.attachBehaviors(this.form, settings);
}
então decidi hackear a função de sucesso de todos os meus objetos ajax.
O Javascript agora se torna
(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);
A função success é uma pasta de cópia do padrão do ajax.js com uma linha adicionada para reconectar comportamentos. Por alguma razão, Drupal.attachBehaviors
deve estar dentro de um temporizador. Não posso simplesmente tê-lo por um motivo que ignoro.
Deixarei esta pergunta em aberto para poucos, caso alguém encontre uma solução mais elegante e / ou explique a singularidade do temporizador.
Muito Obrigado