jQuery Ratings – A Progressive Enhancement Approach

There are some site behaviors that are primed for progressive enhancement in this example we’ll look at a ratings system and how easy it is to transform a simple form to make it more visually appealing and also improve usability. For a simple rating system we want a radio button list (1-10) and a ‘vote’ button to submit our rating. The html would look something like this:

<form id="rate_this" action="/process/rating/" method="post">
    <div id="rating_scores">
        <label><input type="radio" value="1" name="rating" />1</label>
        <label><input type="radio" value="2" name="rating" />2</label>
        <label><input type="radio" value="3" name="rating" />3</label>
        <label><input type="radio" value="4" name="rating" />4</label>
        <label><input type="radio" value="5" name="rating" />5</label>
        <label><input type="radio" value="6" name="rating" />6</label>
        <label><input type="radio" value="7" name="rating" />7</label>
        <label><input type="radio" value="8" name="rating" />8</label>
        <label><input type="radio" value="9" name="rating" />9</label>
        <label><input type="radio" value="10" name="rating" />10</label>
        <input type="submit" value="Vote" />
    </div>
</form>

Which gives us this:

A simple radio list and a simple button to submit the form.

How can we make this 100x’s better? Simply clicking on a number to submit the form automagically would be the easiest and most friendly user interaction. So we lean on jQuery to provide progressive enhancement. Using these methods we can create a rating behavior infinitely better and more appealing like this:

rating_enhanced.png

jQuery

// hides the vote button
  $("form#ratethis input#votebutton").hide();

// hides all radio buttons $("form#rate_this input[@type=radio]").hide();

// format the labels to look clickable $("form#ratethis label").addClass("contestselector");

// change the formatting of the label when it is hovered over // by assigning a different class $("label.selector, #ratingscores a").hover(function(){ $(this).addClass("selectorh"); }, function() { $(this).removeClass("selector_h");
});

// submit the form when a label is clicked $("form#ratethis label").click(function() { $(this).find("input").attr("checked","checked"); $("input#votebutton").trigger('click'); }); }

CSS

#ratingscores {
margin: 20px 0 10px;
border: 1px solid #cacaca;
background-image: url("/images/ratingscoresbck.gif");
background-position: 0% 45%;
background-repeat: no-repeat;
background-color: #efefef;
padding: 5px 0;
padding-left: 130px;
}
.contestselector {
color: #000;
text-transform: uppercase;
cursor: pointer;
font-size: 167%;
font-weight:bold;
padding: 10px 13px 9px;
margin: 1px;
}
.contestselectorh {
background: #c00;
border: 1px solid #a00;
background: #00c705;
border: 1px solid #008004;
color: #fff !important;
text-decoration: none !important;
margin: 0px;
}

Why hide all the radio buttons? Aside from the fact that they’re ugly we don’t need to worry about them because we’re using <label&rt;s effectively.

The labels are surrounding the buttons with so they will still get focus

<label><input type="radio" value="1" name="rating" />1</label>

We let the user know that the numbered hot spots are indeed buttons by applying a mouseover behavior.

We submit the form when a label is clicked – not when the Vote Now button is pressed.

If Javascript was not available or the jQuery rules were not applied then the html would perfectly degrade and would be entirely usable otherwise.

For an example of this method in action venture over to the Costumzee Costume Contest.

Post Meta Love

6 Brain Droppings

  1. Nice!

    My only suggestion would be the addition of a legend element on the form for the “rate” text that you would then enhance via CSS to prettify it to what you’ve got now.

  2. Great point Steve!

    Use of the element would definitely improve the markup. I’ll have to roll that in!

  3. Although I like the approach and the concept is great, the implementation leaves much to be desired. This solution is inaccessible to users who are unable to use a mouse, as the labels do not receive focus by tabbing. (Tested in Fx 2 and 3b4, IE7)

  4. I forgot to mention in my previous post a solution to the problem I highlighted. The CSS declarations display:none and visibility:hidden will prohibit form elements from receiving focus, and as jQuery’s hide() method uses display:none (I believe), this is out. However, one can use position:absolute; and z-index:-1; to place the form element behind its label effectively hiding it. To save our graceful degradation, these CSS declarations would best be applied using a class that is added to the elements via JS. Otherwise, the form elements would be hidden in the JS-off, CSS-on scenario.

  5. Hello,

    One question: debugging with firebug its seems that it calls results.php twice ?

    http://kylebradshaw.com/presentations/jQuery/rating.html

    Andras

  6. Great catch Andras, In my haste before my presentation I focused on the label click event instead of the radio button click event.

    Since clicking a label will toggle the associated input it was doubling up the request. Fixed now!

    http://kylebradshaw.com/presentations/jQuery/rating.html

Drop some knowledge..


  • html is allowed