12

I am making a site with a lots of JS, and I am wondering where I should put the JS code. Optimally I would like to keep the JS with each module and not the theme layer. Some content could be exposed as blocks etc.

But I am having some issues with the cache. In my example I need to add JS & CSS to the node edit form. I have used hook_block_view, but it is cached. So if there is an error in the node edit form, the drupal_add_js & drupal_add_css functions are not called. The same seems to be true for hook_node_prepare.

Where would you input the JS & CSS layer? and are there hooks that get's called even if there is an error in the node edit form?

6

If you wish to add JS and CSS to the node edit page in particular (or any form in general), the best and the right place to do so is the hook_form_alter() and the property you should be using is #after_build.

This comment on DO tells you exactly what to do - http://drupal.org/node/1253520#comment-4881588

Hope this helps :-)

5
  • Thanks, just what I needed. Got a nice form now, much better than the default he he. Any opinions about the architecture of such a site? – Jens Feb 13 '12 at 6:41
  • Glad it worked. When it is so you should you should mark the answer as 'answer accepted' so the question does not appear in the list of unanswered questions and the person helping you out gets "karma". I see that you are new here. I am too, but I have more active accounts on other StackOverflow services, and I love this place. – Sumeet Pareek Feb 13 '12 at 8:19
  • And oh.. just knowing that you need JS CSS on a form and trying to comment on the architecture of the site would be no less than a crime :-p – Sumeet Pareek Feb 13 '12 at 8:21
  • Sure, answered now. – Jens Feb 17 '12 at 7:06
  • 1
    @SumeetPareek I downvoted your answer (but no offense) because using #attached is recommended in almost any case. Moreover, drupal_add_js/css will be deprecated in Drupal 8. – AKS Sep 4 '13 at 1:15
6

You should use the #attached property to ensure that JS/CSS always get's loaded properly together with another render element.

2
  • I felt this would really benefit from an example of how to use #attached, and maybe some additional info about the problem you're avoiding. – Michael Greisman Jun 4 '15 at 17:03
  • @MichaelGreisman I have to say I don't immediately see the value of adding the code inline here. It will be better maintained at the link I provided, which is the official documentation on how to do it. My answer explains what to do, but the form api documentation is the right place for how. – Letharion Jun 8 '15 at 8:02
3

I felt these answers & comments desperately needed example code, particularly those of @AyeshK and @Letharion. This is too long for a comment, so please forgive the answer. If it's useful to you, please up-vote either Sumeet or Letharion's answer. Also, the following example obviously adds CSS, but would be nearly identical for adding javascript.

Using @Sumeet's answer, but using the #attached property instead of drupal_add_css, looks like this:

/* Implements hook_form_FORM_ID_alter() */
function MY_MODULE_form_MY_FORM_ID_alter(&$form, &$form_state, $form_id) {
  $form['#after_build'][] = 'MY_MODULE_some_function_name_after_build';
}

function MY_MODULE_some_function_name_after_build($form, &$form_state) {
  $style_path = drupal_get_path('module','MY_MODULE') . '/css/my_css.css';
  // drupal_add_css('file', $style_path);
  $form['#attached']['css'][] = $style_path;
  return $form;
}

Finally, the deprecation of drupal_add_css can be found in this post. That may be news to many for whom drupal_add_xxx was working just fine, as it was for me.

1
  • The #after_build bit is, to the best of my knowledge nonsense, and should simply be removed. (There is a similar comment on the answer providing the #after_build solution) I think this in itself explains why my brief answer is good. If you simple looked at the link I provided, you'd find the same code, but without the unnecessary bits. – Letharion Jun 8 '15 at 8:04
0

For Drupal 8, I would advise you to look at this article

libraries.yml

something: 
  version: VERSION
  js: 
    js/something.js: {}
  dependencies: 
    - core/jquery

.module

function MODULE_page_attachments(array &$page) {
  $page['#attached']['library'][] = MODULE/something;
}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.