The Karma Project: Code Less, Teach More

January 12, 2010

Creating a Scoreboard Widget with jQuery UI

Filed under: News — bryanwb @ 1:30 pm

I really, really hope that OLE Nepal can move from developing its content in Adobe Flash to JavaScript and HTML5. As I explained to someone recently, this depends entirely on how easy we can make it to quickly stick together a lesson from flexible building blocks. The basic building blocks are user interface widgets. Since Karma only uses openweb technologies, those widgets can only be created using some combination of html5, javascript, and CSS.

I have no desire to create my own UI widget framework when a number of good ones already exist. But which framework to choose? There is extjs, dojox, cappuccino, sproutcore, jQuery UI, and others. I wanted a flexible toolkit that could be used in pieces and would have a very low learning curve. This disqualified cappuccino and Sproutcore because those frameworks are both very powerful and very different from other popular web development tools and paradigms.

I settled on jQuery UI for a number of reasons:

  1. It is very simple to create your own plugin
  2. It works with CSS and html, not against them
  3. There seems to be a lot of momentum behind jQuery UI
  4. Themeroller.com rocks
  5. A number of core developers have backgrounds in graphic design

I really like that actual graphic designers develop jQuery UI. That means that design issues and usability are the forefront.

Enough technology strategy, let’s get to the tutorial.

Om, myself, Roshan, and Vaibhaw sat down some days ago and created a custom theme for OLE Nepal’s lessons. This included things such as:

  • border thickness and color
  • default font and font-size
  • what buttons should look like when they have the focus, hover, are active
  • The drop shadow thickness and orientation
  • and a whole lot more

I highly recommend you take a look at themeroller.com. If you use the CSS classes in the jQuery UI CSS framework in your application, you get a consistent theme with very little work. A great benefit is that you can change your theme later without having to change your application code at all.

Then I downloaded the theme and renamed the main theme file ui.theme.css to karma.css

To add the theme to your application, add the following inside the <head> element of your html

<link rel="stylesheet" type="text/css" href="../../css/ui.core.css" />
<link type="text/css" rel="stylesheet" href="../../css/karma.css" />

The widget we needed most urgently was a scoreboard widget for displaying the user’s score in a game a place to stick game control buttons like “Play Again”, “Start”, and “Stop”. Between Vaibhaw, roxan, and myself we keep creating different scoreboards when one common widget will usually suffice. We decided we need a scoreboard that could be laid out vertically or horizontally as needed. We also wanted a simple set of functions for incrementing the score, decrementing, resetting it, etc.

I spent about two days writing the scoreboard widget, which wasn’t too bad considering that this was my first jQuery plugin and the end result works with our themeroller theme. Some other time, I will go into the details of how I created the widget, perhaps after I create a couple more.

To add the scoreboard to your application, you first have to include a number of files. Notice that you have to add ui.scoreboard.css and ui.scoreboard.js

        <link type="text/css" rel="stylesheet" href="../../css/ui.scoreboard.css" />
	<script type="text/javascript" src="../../js/jquery-1.3.2.js"></script>
	<script type="text/javascript" src="../../js/ui.core.js"></script>
	<script type="text/javascript" src="../../js/ui.scoreboard.js"></script>

You have to have an empty <div> element in your html to hold the scoreboard

    <div id='scoreArea'><div>

After including all these library files, it takes only one line of JavaScript to make the scoreboard appear on your page.

  $('#scoreArea').scoreboard();

The scoreboard defaults to a horizontal layout as you can see below

Laying out the scoreboard only requires one additional parameter

  $('#scoreArea').scoreboard({layout:'vertical});

You can override the defaults by passing in new values to the scoreboard constructor

$('#scoreArea').scoreboard({
     layout: 'vertical',
     winningScore: 6,
     score: 0
});

Any options you specify in the hash will override the default values; any options you don’t specify will use the default values. After you have initialized a plugin, you can change any option at any time using the option method:

$('#my-elem').scoreboard('option', 'winningScore', 8);

scoreboard currently has the following public methods

setScore(x)
setTotal(x)
getScore()
getTotal()
reset()
inc([val])     //increments score, defaults to 1 unless a value val is passed
dec([val])     //increments score, defaults to 1 unless a value val is passed
incTotal([val])
decTotal([val])

$('#scoreArea').scoreboard('getScore');  //invokes the getScore method
$('#scoreArea').scoreboard('setScore', 5);  //invokes setScore method with the argument 5

One really option of using jQuery, is that I can effortlessly issue custom events.

Usually a lesson has code like this to determine if the game has been won

function questionAnswered(answer) {
   if( answer === correctAnswer){
      //reward user

      if ( totalCorrect === winningScore ) {
            /* stop game and reward user */
     }
   } else {
       /* inform user their answer was wrong */

  }
};

The scoreboard emits a custom event ‘winGame’ when the winning score is reached. Rather than using an if statement to check if the winning score has been reached I can listen for the ‘winGame’ event using jQuery’s bind method. The benefit of doing this is that repeatable logic lives in the widget and the lesson code can listen for events to control the game rather than run a CPU-intensive game loop

Here is the super-easy code in the widget for emitting the ‘winGame’ event

//ui.scoreboard.js
 if(winningScore === currentScore){
			  this.element.trigger('winGame');
		      }

and here is the code for listening for the even

//lesson.js
 $('#scoreArea').bind('winGame', 
		function(){
		    /* reward user */
		});  

After scoreboard, I need to create widgets for help, simple tests, a Nepali typepad. I also need to figure out how to document these with jsdoc and how best to unit test them.

1 Comment »

  1. Hi

    I am new here. I’am sorry if the this category is the wrong place for this post but I was hoping that somebody here on karmaproject.wordpress.com would be able to help me with SAT vocabulary.

    Its a pain in the a$$!

    Any tricks ?

    Comment by Cageunliggisa — November 27, 2011 @ 11:56 am


RSS feed for comments on this post. TrackBack URI

Leave a comment

Create a free website or blog at WordPress.com.