सफल अजाक्स के बाद Drupal.attachBehaviors को कैसे ट्रिगर किया जाए


10

मेरे पास एक मॉड्यूल है जो लिंक पर क्लिक करने पर ajax के माध्यम से एक नोड को अपडेट करता है।

लिंक एक टॉगल है, इसे पहले क्लिक पर मान 1 के साथ नोड को अपडेट करना चाहिए, फिर बाद के क्लिक पर मूल्य 0 के साथ, जैसे कुछ चालू / बंद करना।

नीचे दिए गए कोड पृष्ठ लोड के बाद पहले क्लिक पर काम करते हैं, लेकिन बाद के क्लिक पर नहीं। मेरा मानना ​​है कि Drupal.attachBehaviors को प्रत्येक क्लिक के बाद कॉल / ट्रिगर करना पड़ता है, लेकिन मैं यह पता नहीं लगा सकता कि यह कैसे करना है।

  1. मॉड्यूल

    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);
    }
  2. जावास्क्रिप्ट

    (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);
  3. मैंने अब तक क्या प्रयास किया है:

(ए) ajax_command_invoke(NULL, 'mymodule');एक $.fn.mymoduleफ़ंक्शन के साथ युग्मित $ ajax_commands सरणी में जोड़ें

(b) $('body').ajaxSuccess(Drupal.attachBehaviors);मेरी जावास्क्रिप्ट में जोड़ें । ajaxComplete भी कोशिश की। इसे दस्तावेज़ पर भी आज़माया।

(ग) एक कस्टम आदेश बनाएं जैसा कि यहाँ विस्तृत http://www.jaypan.com/tutorial/calling-function-after-ajax-event-drupal-7

नोट: मुझे पता है कि नए html सम्मिलित किए जाने / संशोधित किए जाने के लिए प्रत्येक क्लिक के बाद अनुलग्नक को ट्रिगर करने की बात है। यदि मैं लिंक पर क्लिक करता हूं और फिर कंसोल में Drupal.attachBehaviors () टाइप करता हूं, तो लिंक को मेरे जावास्क्रिप्ट द्वारा फिर से संसाधित किया जाएगा, जैसा कि 'मिडोन' वर्ग के अतिरिक्त द्वारा दर्शाया गया है, और फिर से क्लिक किया जा सकता है।

नोट: ब्याज के अलावा, अगर मैं $ajax_commandsखाली छोड़ता हूं और कॉलबैक फ़ंक्शन के अंत में इसे (खाली सरणी) वापस करता हूं, तो लिंक पहले और बाद के क्लिकों पर क्लिक करने योग्य रहेगा। इसकी कार्यक्षमता होगी जिसे मैं (टॉगल) ढूंढ रहा हूं। हालांकि, चूंकि प्रत्येक क्लिक के बाद html में कोई परिवर्तन नहीं किया जाता है, इसलिए उपयोगकर्ता के पास यह जानने का कोई तरीका नहीं है कि टॉगल चालू है या बंद है।

किसी भी प्वाइंटर की अत्यधिक सराहना की जाएगी।

================================================== =====

आंशिक उत्तर:

Drupal ajax.js सफलता समारोह केवल रूपों के लिए व्यवहार को फिर से संलग्न करता है (मुझे लगता है?)

    if (this.form) {
      var settings = this.settings || Drupal.settings;
      Drupal.attachBehaviors(this.form, settings);
    }

इसलिए मैंने अपने सभी ajax ऑब्जेक्ट्स के फंक्शन को हैक करने का फैसला किया।

अब जावास्क्रिप्ट बन जाता है

    (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एक टाइमर के भीतर होना चाहिए। मैं इसे केवल एक कारण के लिए नहीं कर सकता, जिसे मैं अनदेखा करता हूं।

मैं इस प्रश्न को कुछ समय के लिए खुला छोड़ दूँगा जब कोई व्यक्ति अधिक सुरुचिपूर्ण समाधान पा सकता है और / या टाइमर विषमता की व्याख्या कर सकता है।

बहुत धन्यवाद


आप बार-बार व्यवहार क्यों करना चाहेंगे? वे AJAX का उपयोग करके बनाए गए किसी भी नए तत्व पर स्वचालित रूप से फिर से चल रहे हैं, इसलिए यह पर्याप्त नहीं है?
21

व्यवहार स्वचालित रूप से मेरे मामले में reattched नहीं हैं। thx
JSL

जवाबों:


1

यह एक अजाक्स व्यवहार से अजाक्स व्यवहार को जोड़ने के लिए मुश्किल हो सकता है जो अजाक्स अनुरोध से ही वापस आ जाता है। हालांकि, यह संभव है।

यद्यपि आपका हुक_मेनू कोड स्निपेट अधूरा लगता है, यह सही मानते हुए ($ आइटम लौटाता है और फ़ंक्शन बंद हो जाता है) - आपके मामले में, आपको केवल डिलीवरी कॉलबैक को 'ajax_deliver' में समायोजित करने की आवश्यकता हो सकती है

अर्थात:

/**
 * Implements hook_menu
 */
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'),
    'delivery callback' => 'ajax_deliver',
    'theme callback' => 'ajax_base_page_theme',
    'type' => MENU_CALLBACK,
  );

  return $items;

}

सुझाव के लिए धन्यवाद, लेकिन यह भी काम नहीं करता है। मैं आपके कोड का उपयोग हुक_मेनू में करता हूं और व्यवहार फिर से स्वचालित रूप से संलग्न नहीं होते हैं।
JSL

1

कुछ डिबगिंग के बाद, मुझे एहसास हुआ कि समस्या मेरे कोड के साथ नहीं थी।

समस्या एक अन्य मॉड्यूल के साथ झूठ बोलती है, मेरे मामले में कलरबॉक्स मॉड्यूल, जो अपने स्वयं के व्यवहार फ़ंक्शन में एक जेएस त्रुटि का स्रोत था। मेरा मानना ​​है कि त्रुटि व्यवहार प्रक्रिया को रोकने का कारण बनती है, और इस तरह, मेरे स्वयं के व्यवहार समारोह फिर से संलग्न नहीं हो रहे थे। कंसोल में त्रुटि देखी जा सकती है।

Colorbox त्रुटि: 7.24 में

Uncaught TypeError: Cannot read property 'transition' of undefined colorbox_inline.js?

और 7.25 में

Uncaught TypeError: Cannot read property 'mobiledetect' of undefined

मेरा समाधान colorbox मॉड्यूल को अक्षम करना था।

सभी ने मदद करने के लिए बहुत धन्यवाद।


1

मैं पहले उत्तर पर टिप्पणी नहीं कर सकता , लेकिन आप सेटिंग्स में कलरबॉक्स के लिए संपत्ति सेट कर सकते हैं। उदाहरण के लिए:

myAjax = new Drupal.ajax('#' + $uilink[i].id, $link, {
  url: $link.attr('data-url'),
  effect: 'fade',
  settings: {
    colorbox: {
      mobiledetect: false
    }
  },
  progress: {
    type: 'throbber'
  },
  event: 'click tap'
});
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.