Skip to content

Using jQueryUI within Drupal 7

August 11, 2011

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.

About these ads
5 Comments leave one →
  1. Ivo permalink
    November 8, 2011 2:19 pm

    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…

  2. Chad permalink
    November 13, 2011 1:03 pm

    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

    • Matt Bernhardt permalink*
      November 13, 2011 3:43 pm

      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.

      • November 14, 2011 2:03 am

        Hi Matt,

        Thanks for getting back so quickly. I’m having issues doing anything but the simplest of alert boxes from an external .js file. Cycle is fine inline, but does nothing inside the js file.

        Pretty sure it’s me… But can’t see how :(

  3. Howard Jacobson permalink
    January 15, 2012 12:29 am

    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

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Follow

Get every new post delivered to your Inbox.

%d bloggers like this: