drupaldrupal-7drupal-modulesdrupal-viewsdrupal-ajax

Loading views_accordion through an ajax request


I am currently loading my view through an ajax request in my custom module:

$.getJSON('/reports/summarized-progress/get_output_activities/'+nid, null,activities);

The drupal page for the above request returns the following:

$output_arg=arg(3);
$html="";
$activities=views_embed_view('activities','block_activities',$output_arg); //this returns a view accordion view
if(!empty($activities)) {
$html.='';
$html.=$activities;
$html.='';
}
drupal_json_output(array('data'=>$html));

The accordion/collapsible functionality is not working on the loaded content. Any ideas whether I need to include through module_load_include any files in my custom module? What needs to be done for this to work?


Solution

  • Whenever you load content through ajax request, you have to ensure that the needed js settings/files are loaded along with your content.

    In most cases, the $javascript static variable that is filled during a content load through drupal_add_js() is not sent to the browser, but you can do this manually :

      // Get the view content.
      $view = views_embed_view($name, $display_id);
    
      // Get javascript data.
      $js = drupal_add_js(NULL, NULL, 'header');
    
      // Prepare data to be processed clientside.
      $settings = drupal_to_js(call_user_func_array('array_merge_recursive', $js['setting']));
    
      // Tell the client to extend Drupal.settings with collected $settings.
      $script = '<script type="text/javascript"> 
                   jQuery.extend(true, Drupal.settings, ' . $settings . ');
                 </script>';
    
      drupal_set_header('Content-Type:text/html; charset=utf-8');
      print $script . $view;
      exit;
    
      $view = views_embed_view($name, $display_id);
    
      $js = drupal_add_js(NULL, array('type' => 'setting'));
      $settings = drupal_json_encode(call_user_func_array('array_merge_recursive', $js['settings']['data']));
    
      $script = '<script type="text/javascript"> 
                   jQuery.extend(true, Drupal.settings, ' . $settings . ');
                 </script>';
    
      drupal_add_http_header('Content-Type', 'text/html; charset=utf-8');
      print $script . $view;
      exit;
    

    Note : If your accordion view rely on a specific .js file, ensure this file is sourced inside every page where ajax requests take place. Usually, you'll have to explicitly source this file if such a page is loaded (full page load) without the view.

    You can achieve this in a hook_page_preprocess() implementation :

    function moduleName_preprocess_page(&$variables) {
      // Include .js to the page so views can rely on in future ajax request
      drupal_add_library('system', 'ui.accordion');
      drupal_add_js(drupal_get_path('module', 'views_accordion') . '/views-accordion.js');
    
      // Add the css for fixing/preventing accordion issues.
      drupal_add_css(drupal_get_path('module', 'views_accordion') . '/views-accordion.css');
    
      // ...
    }
    

    ... or by including the file when the content is requested (as we do for Drupal.settings), just add a script tag in the $script variable in the ajax callback :

    $script .= '<script type="text/javascript" src="sourcefile.js"></script>'
    

    Hope this helps!