jQuery

Quick Drupal Tips and Tricks

Easy enough to copy and paste

It's been a LONG time since my last post (roughly a year) so I thought it was time to finally post something new. I've been lucky enough to build quite a few Drupal themes lately and below are some bits of code that I use on a dailly basis when adding to or developing custom themes. The nice part is everything below should be easy enough to copy and paste! *Note: All code below is for Drupal 6.

Views horizontal scrollbar

You know that annoying horizontal scroll bar that appears on your browser everytime you hover over a View on your site? This short bit of CSS gets rid of that. Place the following code in your theme's CSS file and away goes the horizontal scroll. div.view div.views-admin-links { width: auto; }

Admin page columns

Ever built a theme only to have the "/admin" columns display one on top of each other? That's typically due to not enough width in the content area to properly float the two columns. Add this bit of CSS to your theme's CSS file and you will no longer have the problem of floating your admin page columns. div.admin .left, div.admin .right { margin-left: 1%; margin-right: 1%; }

Rounded tabs from Zen

I'm a big fan of the rounded "edit" and "view" tabs on the Zen theme and wanted to incorporate them into my own themes. There's a couple of files you'll need to edit but it's really quite simple copy and paste. Be sure to download the tabs images and place them in your themes folder in the "images/tabs" folder so the paths below match up.

CSS For Tabs

/* styling for node tabs (e.g., View, Edit) */ #content-tabs { margin: 0 0 1em 0; } #content-tabs ul.primary { background: url(images/tabs/tab-bar.png) repeat-x left bottom; border-width: 0; line-height: normal; list-style: none; margin: 0; padding: 0 0 0 10px; white-space: nowrap; } #content-tabs ul.primary li { float: left; margin: 0; padding: 0; } #content-tabs ul.primary li a { background-color: transparent; background: url(images/tabs/tab-left.png) no-repeat left -38px; border-width: 0; color: #777; display: block; font-weight: bold; height: 24px; margin: 0; padding: 0 0 0 5px; /* width of tab-left.png */ text-decoration: none; } #content-tabs ul.primary li a .tab { background: url(images/tabs/tab-right.png) no-repeat right -38px; border-width: 0; display: block; height: 20px; /* 24px (parent) - 4px (padding) */ line-height: 20px; margin: 0; padding: 4px 13px 0 6px; } #content-tabs ul.primary li a:hover, #content-tabs ul.primary li a:focus { background-color: transparent; background: url(images/tabs/tab-left.png) no-repeat left -76px; border-width: 0; color: #4e4e4e; } #content-tabs ul.primary li a:hover .tab { background: url(images/tabs/tab-right.png) no-repeat right -76px; } #content-tabs ul.primary li.active a, #content-tabs ul.primary li.active a:hover, #content-tabs ul.primary li.active a:focus { background-color: transparent; background: url(images/tabs/tab-left.png) no-repeat left 0; border-width: 0; color: #000; } #content-tabs ul.primary li.active a .tab, #content-tabs ul.primary li.active a:hover .tab { background: url(images/tabs/tab-right.png) no-repeat right 0; } #content-tabs ul.secondary { background: url(images/tabs/tab-secondary-bg.png) repeat-x left bottom; border-bottom: 1px solid #c0c0c0; font-size:0.8em; list-style: none; margin: 0; padding: 0; white-space: nowrap; } #content-tabs ul.secondary li { border-right: none; float: left; margin: 0 5px 0 0; padding: 3px 0; } #content-tabs ul.secondary a { background: url(images/tabs/tab-secondary.png) repeat-x left -56px; border: 1px solid #c0c0c0; color: #777; display: block; height: 24px; margin: 0; padding: 0; text-decoration: none; } #content-tabs ul.secondary a .tab { display: block; height: 18px; /* 24px (parent) - 6px (padding) */ line-height: 18px; margin: 0; padding: 3px 8px; } #content-tabs ul.secondary a:hover, #content-tabs ul.secondary a:focus { background: url(images/tabs/tab-secondary.png) repeat-x left bottom; } #content-tabs ul.secondary a.active, #content-tabs ul.secondary a.active:hover, #content-tabs ul.secondary a.active:focus { background: url(images/tabs/tab-secondary.png) repeat-x left top; border: 1px solid #c0c0c0; color: #000; }

CSS for tabs - IE7

#content-tabs ul.primary li a:hover { color: #555; cursor: pointer; text-decoration: none; } #content-tabs ul.secondary li a:hover{ color: #555; cursor: pointer; text-decoration: none; }

CSS for tabs - IE6

#content-tabs ul.primary li a, #content-tabs ul.primary li a .tab, #content-tabs ul.secondary li a, #content-tabs ul.secondary li a .tab { display: inline; /* Otherwise the blocks mistakenly get 100% width in IE5 */ display: inline-block; /* Otherwise the blocks mistakenly get 100% width in IE6 */ } #content-tabs ul.primary, #content-tabs ul.secondary { width: 100%; /* Otherwise IE5 treats the ul as floated */ width: auto; /* Reset to auto width for IE6 */ } #content-tabs ul.primary li a { background: url(images/tabs/tab-left-ie6.png) no-repeat left -38px; } #content-tabs ul.primary li a .tab { background: url(images/tabs/tab-right-ie6.png) no-repeat right -38px; } #content-tabs ul.primary li a:hover { background: url(images/tabs/tab-left-ie6.png) no-repeat left -76px; color: #555; cursor: pointer; /* Minor fix for primary and secondary tabs in IE */ text-decoration: none; } #content-tabs ul.secondary li a:hover{ color: #555; cursor: pointer; /* Minor fix for primary and secondary tabs in IE */ text-decoration: none; } #content-tabs ul.primary li a:hover .tab { background: url(images/tabs/tab-right-ie6.png) no-repeat right -76px; } #content-tabs ul.primary li.active a, #content-tabs ul.primary li.active a:hover { background: url(images/tabs/tab-left-ie6.png) no-repeat left 0; } #content-tabs ul.primary li.active a .tab, #content-tabs ul.primary li.active a:hover .tab { background: url(images/tabs/tab-right-ie6.png) no-repeat right 0; }

Template.php

/** * Adds class of "tab" to tab menu items so they can be styled. */ function phptemplate_menu_item_link($link) { if (empty($link['options'])) { $link['options'] = array(); } // If an item is a LOCAL TASK, render it as a tab if ($link['type'] & MENU_IS_LOCAL_TASK) { $link['title'] = ''. check_plain($link['title']) .''; $link['options']['html'] = TRUE; } if (empty($link['type'])) { $true = TRUE; } return l($link['title'], $link['href'], $link['options']); } /** * Duplicate of theme_menu_local_tasks() but adds clear-block to tabs. */ function phptemplate_menu_local_tasks() { $output = ''; if ($primary = menu_primary_local_tasks()) { $output .= "

    \n". $primary ."

\n"; } if ($secondary = menu_secondary_local_tasks()) { $output .= "

    \n". $secondary ."

\n"; } return $output; } After making these changes go to the Performance page and clear your site's cache "/admin/settings/performance".

Hover working on non-links in IE6

Since IE6 isn't capable of handling hovers on anything other than links (a href), it requires a specific bit of jQuery to get things working right. Thankfully Drupal 6 ships with jQuery so we can leverage it's power for the site's needs. For this example I am using a background image for my submit buttons on the site and I wanted to have the hover work for all browser, including IE6. You'll need to create a "script.js" file and add this bit of code. The reason I said to create a "script.js" file is that Drupal 6 picks that up by default, just as how it picks up the "style.css" file automatically.

script.js

Drupal.behaviors.myModuleBehavior = function (context) { // IE6 & less-specific functions // Add hover class to primary menu li elements on hover if ($.browser.msie && ($.browser.version < 7)) { $('.form-submit').hover(function() { $(this).addClass('hover'); }, function() { $(this).removeClass('hover'); }); }; }; Now that we have the code in place for the script, it's time to edit the CSS to make it all come together. Normally we do the ".form-submit:hover" to make the style change per hover on the submit button. Since IE6 doesn't understand that, we need to change that a little bit. We need to add a "form-submit.hover" along with the "form-submit:hover". The above Javascript code goes in and makes things work so IE6 can understand what we are trying to do.

CSS

.form-submit { background: url(images/input-submit.png) repeat-x top center; color: #000; } .form-submit:hover, .form-submit.hover { background-position: bottom center; color: #fff; } Well that should do it for now. I've got a LOT more tips and tricks with Drupal theming, just need to get them out of my mind an up here. Hopefully I'll get around to soon. If you have any tips or tricks and it's easy enough to copy and paste please leave a comment below. Would love to hear what other's are using with their themes.

Miscellaneous:

jQuery fun with lists and more lists

jQuery - So simple even a designer can do it!

This week I had the task of taking a rather long and complicated list and shortening it down into categories with sub lists. jQuery seemed like the best way to go as I've seen accordion style sliding list and things of that sort before. The only thing I hadn't come across was a list with a drop down menu which controlled the list and content below...so I set out to build one as well as teach myself some jQuery (I knew what it was, just never wrote my own jQuery code before).

So the idea here was I wanted a list to appear on the right side of my div which contained categories in which I could click on and have the content on the page, in lists, expand to show the selected list all while sliding away the previously displayed list.

This screenshot/mockup will help better explain the desired look and feel as well as functionality I was going for.

idea

Sounds quite tricky but after a bit of messing around with some basic jQuery code and functionality I was able to get everything working somewhat well.

I first started out by building the header area with the "MOST RECENT" list and "SORT BY CATEGORY" text. I made it so when you click on the "MOST RECENT" link it would drop down a menu with the category listings. These category listings control what is shown on the page, it controls what list will appear when you click on your desired category.

So once I got the header portion built, I then begin making a list wrapped in custom divs for each of the category lists' content. Being that I have five categories I had to make 5 custom wrapped divs. For these divs were controlled by the category drop down list on right.

Now that I had my header portion and my category lists it was time to add some CSS to hide these lists until jQuery told them to show themselves. When the page loads I wanted one list to appear, the "MOST RECENT" list, so I didn't hide that list in CSS so it would display right away. I hid the other lists but not the first one.


#list-item2.sortlist,
#list-item3.sortlist,
#list-item4.sortlist,
#list-item5.sortlist {
display: none;
}

Now that the lists were hiding through CSS it was time to make them show by using jQuery. But first I needed to make the category drop down list actual function. So when the user clicks on the text for "MOST RECENT" it is to drop down and reveal categories which are also clickable and that changes the list which is displayed to the user.

Here is the magic jQeury code for that:

$("#sort").click(function(){
$("#sort-options").slideToggle("slow");
$(this).toggleClass("active"); return false;
});

What that says is when you click on the div "sort" it will expand or contract the div "sort-options" and give it a class of "active" or none. Of course these div names and id's are all specified in my HTML, so they actually relate to a working div.

The "active" class here is what allows me to change the red arrow pointing down to a red arrow pointing up. So "active" shows an arrow pointing down and no class shows an arrow pointing up.

Since the drop down category menu is working correctly it's now time to make the category options/links actually do something.

Here is yet more magic jQuery code to do just that:

$("#sort_item1").click(function(event) {
event.preventDefault();
$("#sort-options").slideToggle();
$("#list-item1").slideDown();
$("#list-item2").slideUp();
$("#list-item3").slideUp();
$("#list-item4").slideUp();
$("#list-item5").slideUp();
$("#sort em").empty();
$("#sort em").append("Most Recent");
$("#sort").toggleClass("active"); return false;
});

What's going on here is if the user clicks on the "a href id" of "sort_item1", which in this case is "MOST RECENT", all lists wrapped in the appropriate divs are to slide up and collapse/disappear and the text in the top portion of the category area (next to the red arrow) is to be removed and replaced with the text "MOST RECENT".

The stripping of text and adding is done by these two lines of code:

$("#sort em").empty();
$("#sort em").append("Most Recent");

Pretty neat isn't it. You can take out text and replace it based on what the user clicks on in the category list. I took this chunk of code about and copied/pasted it for each category and changed which lists were to slide up and down and which text was to be replaced with what.

Be sure to check out a working example of what I was trying to explain above. I'm sure that if you view it in action and read/re-read my post it will make more sense. It took me a little time to really understand what all was going on with each click but once I got things in order it all seemed to fall into place and be more understandable.

All of this code is available for download so you can mess with it and use it anywhere you'd like. I included all of the HTML/CSS/jQuery code/images as well so those can also be used anywhere else as well.

I'm sure there are better ways to go about this but this is what I was able to come up with and understand. It works in all browsers I have tested it in too such as IE6, IE7, FireFox (Mac and PC) and Safari. Of course there are some IE specific CSS code to make some text and boxes align correctly, but that's just about the norm anyways.

I've just scratched the surface as to what jQuery is capable of and I can't wait to see what else it can do. This is just a pretty effect which simplifies the use of categories and lists, jQuery can handle much more complex code and situations that this, so I plan on continuing to learn more about it in hopes of applying it to my future projects.

Miscellaneous:

Subscribe to RSS - jQuery