Drupal #Attached
What is drupal attached?
Drupal #Attached allows loading of CSS, Javascript, libraries, or custom types when the render array is built.
Drupal #Attached VS drupal_add_js / drupal_add_css
If you are using drupal_add_js() in your form building function, you are attaching JavaScript to a page, and that's it.
If you are using $form['#attached']['js'], other modules may interact.
If something gets rendered in drupal and you cache it, then drupal saves the render array and drupal will not execute drupal_add_js/drupal_add_css/drupal_add_library. So when drupal reads the render array and check if #attached is in there. Drupal will always execute the drupal add functions.
Here is an example of adding a custom javascript file with drupal attached in a custom module.
In your custom module or form you can add the #attached to your render array.
In this array you specify to add css or javascript of a library using
$content['#attached']['js'];<br>$content['#attached']['css'];<br>$content['#attached']['library'];
Then you want to specify what type of file you want to add.
Just like drupal_add_js you can set a type to use inline code or a file or a external file.
Example:
1. File
$form['#attached']['js'][] = array( 'data' => 'file.js', 'type' => 'file');
2. Inline code
$form['#attached']['js'][] = array( 'data' => '/* some javascript here */', 'type' => 'inline');
3. External file
$form['#attached']['js'][] = array('data' => '<a href="http://domain.com/file.js'">http://domain.com/file.js'</a>, 'type' => 'external');
Then you can set options like preprocess and every page, like
'options' => array(<br> 'preprocess' => TRUE,<br> 'every_page' => TRUE,<br> ),
For more information see Drupal Form #Attached API
Then you want to add your data/variables so you can read them from your javascript.
Here we use custom_data as the identifier, we use that later in the javascript. And the variable $my_data is our data we wish to use in the javascript. This could be just a variable or an array.
array(<br> 'data' => array(<br> 'custom_data' => $my_data,<br> ),<br> 'type' => 'setting',<br><br> ),
Now your code should look something like this:
$content = array();<br> $content['#markup'] = "<div class='rendered-div'></div>";<br><br> $content['#attached']['js'] = array(<br> array(<br> 'data' => drupal_get_path('module', 'custom_module') . '/js/script.js',<br> 'options' => array(<br> 'preprocess' => TRUE,<br> 'every_page' => TRUE,<br> ),<br> ),<br> array(<br> 'data' => array(<br> 'custom_data' => $my_data,<br> ),<br> 'type' => 'setting',<br><br> ),<br> );<br> return $content;
Now for the javascript we use this is the code below.
Drupal.behaviors is not simply a replacement for jQuery.ready since the latter only runs once (when DOM is ready for manipulation): behaviors can be fired multiple times during page execution and can be run whenever new DOM elements are inserted into the document.
When your using Drupal.behaviors be sure you use a unique name that is not been used.
Then we use the attach:function
In here we can load our data we had in our php file using Drupal.settings
To get the data we have set befor in the php just type the array key we used.
In this case it was 'custom_data'.
A reminder from our php file below.
array(<br> 'data' => array(<br> //See here<br> 'custom_data' => $my_data,<br> ),<br> 'type' => 'setting',<br><br> ),
So the javascript file would something like this:
(function ($) {<br> Drupal.behaviors.uniquename = {<br> attach:function (context, settings) {<br> var obj = Drupal.settings['custom_data'];<br> alert(obj);<br> }<br> };<br>})(jQuery);