Using jQueryUI within Drupal 7
jQuery is crazy powerful – and the jQueryUI set of plugins is excellent for adding commonly-needed user interface controls like accordions, tabs, carousels, etc. Even better, with the release of Drupal7 we now have jQueryUI included in the core. But how do we actually get to use all this magic? I just had to figure this out, so in the hope of paying it forward, I’d like to share what I did, and how. There may be better ways to do this, but this is what has worked for me – if you can find a better way, please let me know!
Credit – I found the post “jQuery UI in Drupal” from jromero to be very helpful; I’d suggest reading it as well. He talks about tabs in the second half.
What I Needed
Our site has a “featured content” area on the front page, and in several locations inside the site. Click on a thumbnail, see that featured slide. That slide can be many things, a video, an image, HTML, etc. I’m converting the site from a custom CMS over to Drupal, and I used some hand-rolled javascript originally but want to take more advantage of jQuery and other plugins this time. After playing around with a number of different options, it looks like the Tabs plugin is the piece I’m going to use. The look isn’t what I want, but the markup is – so I’m pretty sure I can re-do the CSS styles to make the presentation more what I want.
What I Did
Step 1: Brute Force
The first thing I did, after much searching, was try to follow jromero’s tutorial. I made sure I had enabled the PHP filter module in core, and created an article node. Using the “PHP code” input filter, I dumped the following into the node body field:
<?php
drupal_add_library('system', 'ui.tabs');
drupal_add_js('jQuery(document).ready(function(){jQuery("#tabsTest").tabs();});', 'inline');
?>
<div id="tabsTest">
<ul>
<li><a href="#tabs-1">Tab 1</a></li>
<li><a href="#tabs-2">Tab 2</a></li>
<li><a href="#tabs-3">Tab 3</a></li>
</ul>
<div id="tabs-1">
<p>Proin elit arcu...</p>
</div>
<div id="tabs-2">
<p>Morbi tincidunt, dui sit...</p>
</div>
<div id="tabs-3">
<p>Mauris eleifend est et turpis...</p>
</div>
</div>
One note about the above – jromero’s post uses the id “tabs”, but that felt a bit too generic so I’ve changed it to “tabsTest” for this purpose.
This worked as I hoped – but it isn’t really sustainable, as I don’t want to have to train the content managers to switch to PHP mode and drop in lines of code every time the need a tabbed carousel. Not to mention the security implications. So, I needed to offload the javascript into the theme, or a module, or something.
Step 2: To the Theme!
The first thing I did was create a simple, one-line javascript file – “tabsTest.js” – that replicated the contents of the drupal_add_js() call in the third line of the above snippet. Filtering out the Drupal business, the only thing in the file was the line:
jQuery(document).ready(function(){jQuery("#tabsTest").tabs();});
I placed this file in my theme, in a js directory – so the full path was /sites/all/themes/mytheme/js/tabsTest.js
If you’re somewhat familiar with jQuery (like I am – not an expert, but beginning to feel comfortable) then I should reinforce something here. This one-line file uses “jQuery()” rather than “$()” because Drupal uses .noconflict() to allow other libraries to also be used.
This one-line file was then added to my mytheme.info file using a script[] reference:
scripts[] = js/testTabs.js
See the “Structure of the .info file” article in the Drupal Theming Guide for information about where to add this line.
At this point, the PHP code block at the beginning of my article node read like this
<?php
drupal_add_library('system', 'ui.tabs');
?>
After saving the new node and clearing all caches (at “/admin/config/development/performance”), the tabs still worked – so I was halfway home.
Step 3: Editing page.tpl.php
The last step was to change where the Tabs plugin was called. After trying – and failing – to modify my theme’s template.tpl.php file, I decided to try adding the code to my page.tpl.php file. I moved the drupal_add_library() line to the top of my page.tpl.php file, making it read like this:
<?php
// $Id: page.tpl.php,v 1.1.2.2.4.2 2011/01/11 01:08:49 dvessel Exp $
?>
<?php
drupal_add_library('system', 'ui.tabs');
?>
<div id="page">
...more HTML...
Yes, this can probably be cleaned up a bit – but this works, and I’m happy. This left only HTML in my article node’s body field, allowing me to switch back to another input format that is friendlier for content editors. After clearing caches again, everything still worked – and when I created a brand new article node with just the HTML from jromero’s tutorial (again changing the outer <div>’s id value to be “tabsTest” rather than just “tabs”), everything worked.
Woohoo!
Step 4: Still To Do…
I’m not out of the woods yet – I’d still like to use the Tabs plugin on a view output, or a different node type with a multiple-value “slide” field. The presentation will need to be changed. However, as a first step, following these steps has allowed me to actually take advantage of the capabilities of jQueryUI. My hope is that this article is helpful to other developers and site builders who, like me, are transitioning from “beginning Drupal” types of tutorials but aren’t yet so familiar with the inner works of Drupal to instinctively know where to add drupal_add_library() calls, how to instantiate jQuery plugins, etc.





Thanks! You helped me out: i thought the ui.tabs where activated automatically by installing the jquery update module! This was driving me nuts until I followed your “step 3″. Great…
Hi,
I’m having real issues using cycle in an external file – which you might be able to help with (I hope!)
I had a more complex external file (based on cslider), but inside page.tpl.php got a version working with:
But this is pretty horrible as all the images are listed within the page – meaning that if there’s any hiccups you end up with 10 images underneath each other.
I tried putting the cycle into an external file and calling it with
drupal_add_js(‘[full relative path]/js/slide.js’);
which works fine slide.js contains alert(“Hello!”) so I know I’m pointing to the right file… but cycle doesn’t work!
Editing page.tpl.php I’ve tried tried expanding the cycle code to include something more like http://stackoverflow.com/questions/427192/preload-images-for-jquery-cycle-plugin (changing the $)… but have been unsuccessful with that too.
I’m pretty new to Drupal, but OK with Jquery and I’d love the jazz things up a little bit. But only being able to put up the simplest of alerts isn’t great.
Cheers,
Chad
I don’t have any immediate suggestions – I’d have to take a closer look at what you are attempting. It sounds like you’re attempting to load images dynamically, rather than using CSS to change visibility of pre-loaded slides? If so, I haven’t been able to achieve that myself, but I’d like to – it would make it possible to load multiple Flash videos or other content within a carousel that doesn’t like being hidden or stacked via z-index.
Seems that using the THEMENAME_preprocess_html function is the way to use template.php to include the jQuery / Javascript.
See http://drupal.org/node/1043478#comment-4307978