Thursday, August 18, 2011

Html tutorial / database - part 3


Yesterday, we got about halfway through a tutorial on updating a databuse using HTML5. We'll finish that up with this post.

Here's the url we're learning from:

http://www.mobilehtml5.com/post/401111526/tutorial-your-first-mobile-html5-app-offline-storage


Now our simple app can record scores, and display all those scores back to users without any intervention from outside servers (read: no network access necessary). This is pretty fantastic, but let’s make it easy for a user to keep scores for multiple players at once. To do this, we’ll add another form to filter our scores by email address:

Here's the form with some of my comments:

!DOCTYPE html>
<html>
<head>
<title>Golf score keeper</title>
<script src="http://www.google.com/jsapi"></script>
<script>
google.load("jquery", "1.4.1");
</script>
<script>

// open the db with name, description, size
var db = window.openDatabase("scores", "", "Previous Scores", 1024*1000);


// This is pretty straightforward - the parameters fill in the question marks,
// and the array contains the data names

function insertScore(hole_num, num_strokes, course_id, email) {
db.transaction(function(tx) {
tx.executeSql('INSERT INTO Strokes (course_id, hole_num, num_strokes, email) VALUES (?, ?, ?, ?)', [course_id, hole_num, num_strokes, email]);
});
}


// This is a helper to renderScores (above). the tx and rs are the transaction object
// and rowset passed as parameters by the tx.executeSql statement call to to this method from "renderScores".
// The "#previous scores" refers to the name of the empty div where the scores are to be displayed.
// e.html writes html-formatted output.

function renderResults(tx, rs) {
e = $('#previous_scores');
e.html("");
for(var i=0; i < rs.rows.length; i++) {
r = rs.rows.item(i);
e.html(e.html() + 'id: ' + r['id'] + ', hole_num: ' + r['hole_num'] + ', num_strokes: ' + r['num_strokes'] + ', email: ' + r['email'] + '<br />');
}
}

// Selects data from the strokes table and invokes the above renderResults
// The email will be used as the parameter if it's defined

function renderScores(email) {
db.transaction(function(tx) {
if (!(email === undefined)) {
tx.executeSql('SELECT * FROM Strokes WHERE email = ?', [email], renderResults);
} else {
tx.executeSql('SELECT * FROM Strokes', [], renderResults);
}
});
}



// create the tables if not in existence;
$(document).ready(function() {
db.transaction(function(tx) {
tx.executeSql('CREATE TABLE IF NOT EXISTS Courses(id INTEGER PRIMARY KEY, name TEXT, latitude FLOAT, longitude FLOAT)', []);
tx.executeSql('CREATE TABLE IF NOT EXISTS Strokes(id INTEGER PRIMARY KEY, course_id INTEGER, hole_num INTEGER, num_strokes INTEGER, email TEXT)', []);
});

// the submit function for the score form
// It seems as if you can refer to anything with an "id" on the page
// with the hash, i.e. $('#xxx'), adding ".val", to get the value
// Iterates through the strokes array and inserts the data

$('#score_form').submit(function() {
strokes = { 1: $('#hole1').val(), 2: $('#hole2').val() };
for (var hole_num in strokes) {
insertScore(hole_num, strokes[hole_num], 1, $('#email').val());
}

renderScores();
return false;
});

// This calls renderScores using the email address submitted with the form

$('#filter_previous_scores_form').submit(function() {
e = $('#filter_by_email').val();
renderScores(e);
return false;
});

// what's this doing here?
renderScores();
});
</script>
</head>
<body>
<form method="get" id="score_form">
<div>
<label for="1">Hole 1</label>
<input type="number" min="1" value="4" id="hole1" name="hole1" size="2" step="1" />
</div>
<div>
<label for="2">Hole 2</label>
<input type="number" min="1" value="4" id="hole1" name="hole2" size="2" step="1" />
</div>
<div>
<input type="email" id="email" placeholder="Enter your email address" size="40"/>
</div>
<div>
<input type="submit" value="Upload Score" />
</div>
</form>
<div>
<h2>Previous Scores</h2>
<form id="filter_previous_scores_form">
<input type="email" placeholder="Filter scores by email" size="40" id="filter_by_email" /><br />
<input type="submit" value="Filter" />
</form>
</div>
<div id="previous_scores">

</div>
</body>
</html>
Essentially, it takes the email address created in the comments and displays the score using the logic previously reviewed.

Here are the comments:

We add the #filter_previous_scores_form form here (complete with placeholder text!) and the associated submit function in our document ready function. When you submit this form, users are able to SELECT just those scores related to the email address entered. Voila!

To me this is an almost fully functioning app (if a bit silly and poorly designed) for allowing one person to keep track of golf scores for multiple players. What’s best about it is that since there are no network calls, the app is (a) fast and (b) usable even without network access.

Still left to do to this app is add even more offline support, talk about background tasks, and learn about how to distribute and promote your mobile HTML5 app. We’ll tackle all these in future parts of this tutorial.

Let's check out how the html performs.

Looks good - you can see the now filtered results at the top of the blog.

Ok, so we've completed a nice little intro to Html5 and how it handles database. This is sure to be a fairly long journey, but we've now got that first step under our belts.



No comments:

Post a Comment