Sports Tournament Style Brackets with jQuery and jQuery UI (3)

Welcome to the third and final (as far as I know!) blog entry on my jQuery-based sports tournament picker. Before reading this entry, please be sure to read the first and second entries so the code makes sense. If you really don't want to read them, the basic idea is this: Use jQuery to render a sports tournament (N pairs of teams). Allow the user to pick winners in each pairings. When a round is complete, render the next round where the winners face off. At the end of the last entry the program had two issues. There was no way to know when you had selected the final winner and there was no way to pass the selections to the server for processing.

Handling the 'we are done' logic was pretty simple. The function I had written before, checkComplete, worked by counting the selected entries in each game. If each game had one selected entry, then the round was complete. At the same time, it created an array of winning teams. This was used to populate the next round, but could also be used to determine if the entire game was done. How? Simple - if we only had one winning team, then it must be the final round. Here is the modified checkComplete function, note the check on the winningTeam size.

function checkComplete() {
	//get all the games at this round
	var round = rounds[currentRound]
	var allGood = true
	var winningTeams = []
	for(var i=0;i<round.length;i++) {
		//for each, if both aren't selected, allGood is false
		var totalselected = $("#round_"+currentRound+" #selectable_"+i+" > li.selected").size()
		if(totalselected != 1) {
			allGood=false
			break
		} else {
			//this is the id of selected team
			var winningid = $("#round_"+currentRound+" #selectable_"+i+" > li.selected").attr("id")
			//its in the form team_
			var id = winningid.split("_")[1]
			var winningname = $("#round_"+currentRound+" #selectable_"+i+" > li.selected").attr("innerHTML")
			winningTeams[winningTeams.length] = {id:id,name:winningname}
			round[i].winningTeam = id
		}
	}
	
	if(allGood) {

		//Before going on, see if we are on the last round. If winningTeams.length == 1, that means the end
		if(winningTeams.length == 1) { wrapUp(); return; }
		currentRound++
		//first round
		rounds[currentRound] = []
			
		//assign new games
		for(i=0;i < winningTeams.length; i=i+2) {
			var game = {}
			game.team1 = winningTeams[i]
			if(winningTeams[i+1] != null) game.team2 = winningTeams[i+1]
			rounds[currentRound][rounds[currentRound].length] = game
		}
			
		//draw the games
		drawGames(currentRound)
	
	}
}


The wrapup function will be fired off if the final winner is selected. I began by simply turning on a button that will be used to submit the data. I added this button at the end of my page:

<button id="saveData" style="display:none">Send Picks</button>	


My wrapup function fades the button in and binds a click even:

function wrapUp() {
	$("#saveData").fadeIn().click(function() {


The click logic needs to send the data to the server. Normally that's easy enough. but our data isn't a simple flat set of form fields. Each round consists of games, and each game is an array of teams. For some reason, I'm always suprised when I remember that jQuery doesn't include a native way to serialize to JSON. A quick Google search turned up jquery-json, a JSON serialization plugin for jQuery. I converted my round data into JSON like so:

var jdata = $.toJSON(rounds)


Once converted to JSON, I then posted it to the server:

$.post('handleresult.cfm',{info:jdata},function(data) {
	alert('Result from server: '+$.trim(data))			
})


I made one small change to my earlier logic. While you could determine of a game by looking at the games in the next round, that involved a bit too much work and wouldn't be usable in the final round. I modified my earlier code to add a winningTeam property to each game when checking to see if the game was complete. Remember that you can view the entire source on the demo (link coming up at the end). The server side code doesn't actually do anything fancy. It grabs the final winning ID and echos it back:

<cfparam name="form.info" default="">

<cfif isJSON(form.info)>
	<cfset info = deserializeJSON(form.info)>
	<cfset lastRound = arrayLen(info)>
	<cfset lastGame = arrayLen(info[lastRound])>
	<cfset winnerId = info[lastRound][lastGame].winningTeam>
	<cfoutput>Winning id = #winnerId#</cfoutput>
<cfelse>
	<cfoutput>Bad data was sent.</cfoutput>
</cfif>


While there is definitely some room for improvement here, I'm going to wrap things up for now. I'd love to get some feedback, and perhaps even modified/sexier versions, so please share!

Final Demo: http://www.coldfusionjedi.com/demos/tourny/test3.html

About this Entry

This page contains a single entry by Raymond Camden published on May 27, 2009 6:53 PM.

FlashBuilder 4 will support FlexUnit 4 - tutorials and feature overview was the previous entry in this blog.

Writing the Pac-Man Game in JavaFX - Part 3 is the next entry in this blog.

Find content using the provided navigation or look in the archives to find all content.

Authors

Archives

This content archive is licensed under a Creative Commons License.