Showing posts with label widget. Show all posts
Showing posts with label widget. Show all posts

Wednesday, June 4, 2008

A Simple YUI-Powered Accordion Widget

Accordion menus are all the rage at the moment (as are Carousels and Sliders). I wanted a snazzy way to show my resume during my recent job search so I went looking for an accordion-style menu. I had these requirements in mind:

1) be lightweight
2) use unobtrusive Javascript techniques (ie not have scattered Javascript all over the markup)
3) use simple CSS to make it look nice
4) needed to support both single and multiple sections opened at a time.

My search came up short. Most were overly complicated, or they required libraries other than what I already have running on my sites. Too much bloat. I guess I'd have to write my own. Since I already use the *radical* YUI libraries on my sites, making it YUI-powered was the way to go for me. I set my goal to <100 lines of good OO unobtrusive Javascript. The current version sits at 80 LOC with lots of comments. Here's what it looks like:
**note that the size of the menu is dynamic, however to embed it in a blogger post I had to use the ol <iframe> trick.

JILS_accordion will make an unordered list <ul> of your choice into a spiffy animated accordion menu. These are the steps to get it going on your site:

Massage the Markup:


While any <ul> will work, you need to make sure it has an id.
Next you need to create two divs inside of each <li>. One div for the title with class accordionTitleDiv, and one for the content with class accordionContentDiv The markup should look like this:
*Note it is not necessary for the individual <li> elements to have id's

Include the JS & CSS Files, initialize the JILS_accordion object:



The first argument for the constructor function is an object that can be left empty '{}' or you can specify things like {multiSelect:true, sectionExpandedSize:10}, etc. The code is heavily commented so most front end guys will be able to figure it out.

Open accordion example in a new page

Updated to v 1.1b following a heads up from Satyam that the widget was broken in IE. Turned out to be a different bug. A 'dangling' comma after the last item in my callback object definition was the culprit, but I still wrapped the init methods using YAHOO.util.Event.onDOMReady() -- just in case. Thanks Satyam!

Update #2 v1.2b A few performance tweaks: Switched to using the YUI aggregate file utilities.js, which includes everything we need in one line AND loads faster with a single HTTP request. Updated the initializing code to show how onDOMReady() can be used as an alternative to onload(). YUI's onDOMReady() makes sure the DOM is ready to go, but doesn't wait for images to be loaded for a snappier page load. The last tweak was to the default animation speed... now with 1/2 the Saturated Fat!

Update #3 v1.3 Per some user requests, the accordion should now toggle only when clicking on the title section, not the content. If you want the old behavior, set "onlyCollapseOnTitleClick" to true in the constructor args.

Wednesday, May 23, 2007

Roll your Own Simple AJAX Survey for Blogger

Update: With the recent addition of Forms to google spreadsheets, I think this tip is rendered obsolete


There are lots of companies out there that let you embed free and fancy survey widgets for your blog. However, I didn't want to sign up for anything and just wanted a simple way to get user feedback for my plugins site. I hacked together a YUI powered survey with a simple php backend to keep track of user responses. For me, the key to neat hacks is leveraging existing "stuff". In my case I have a blogger-powered site, gmail accounts and my own web server.


How it works:
Once the user selects an option from the survey and hits "Vote", the php script tied to the form's post action sends an email to my gmail account. Because I normalize the subject line with the survey name and the option selected, I can create quick gmail filters. Another freebie is that Gmail groups these similar messages and therefore getting a total-count is just a glance away...

The Javascript half of this is really quite simple. I embedded it all into a single html page so that I could get around the fact that you cannot easily include javascript in blogger posts. By embedding the Javascript in an html page, you can use this clever workaround, and embed the widget using an iframe.

I am using a standard YUI Dialog object, however, to have this work exactly the way I wanted, I needed to override a few of the "interesting moments", as Yahoo likes to call them. Specifically the hide() and validate() methods:


...
//prevent multiple votes, while adding some flair
myDialog.hide = function() {
var attributes = {
height: { to: 25}
};
var anim = new YAHOO.util.Anim('myDialog', attributes, 1.0,
YAHOO.util.Easing.backOut);
anim.animate();
this.setHeader('Thanks for your Feedback!');
};
//prevent en empty vote:
myDialog.validate = function () {
var data = myDialog.getData();
if(data.choice == null) {return false;}
else return true;
};

Right Click and choose Save As here to download the whole html/javascript file.

For those wondering, I chose YUI because we use it at work and it rocks the house. The developers are wizards, and YAHOO! even lets you choose to have the JS and CSS files hosted on their fast servers.
--
The only remaining tricky thing is that you'll need access to your own WWW server. For security purposes, AJAX and POSTS cannot be made to different domains (edit: unless you set up a proxy), so the .html and the .php files (or whatever your favorite server side scripting language is) must reside on the same server.

In PHP, I just grab the survey name and the option the user chose and use sendmail.
...
$surveyname = $_POST['surveyname'];
$surveychoice = $_POST['choice'];
$subject = 'iPhoto2Gmail Survey: '.$surveyname. ' '.$surveychoice ;
...
//set up your message and headers
mail('my-email-address@gmail.com', $subject, $message, $headers);


After that all you have to do is create some filters in your email client and you'll have a super simple way of quantifiying user response -- and by using some YUI animation, it looks pretty slick too!