4. Deleting Rows
To make our Delete buttons do something when clicked, we need to bind
a click event handler to them with jQuery. We did the same sort of thing
earlier with the items on the Date panel using jQuery’s click() method.
Unfortunately, that approach won’t work in
this case. Unlike the items on the Dates panel, the entries on the Date
panel are not static. This means they are added and removed throughout
the course of the user’s session. In fact, when the application
launches, there are no entries visible on the Date panel at all.
Therefore, we have nothing to bind the click to at
launch.
The solution is to bind click events to the
delete buttons as they are created by the refreshEntries() function. To do so, add the
lines shown in bold to the end of the for
loop:
...
newEntryRow.find('.calories').text(row.calories);
newEntryRow.find('.delete').click(function(){
var clickedEntry = $(this).parent();
var clickedEntryId = clickedEntry.data('entryId');
deleteEntryById(clickedEntryId);
clickedEntry.slideUp();
});
}
Add the following deleteEntryById() function to
kilo.js to remove the entry from the
database:
function deleteEntryById(id) {
db.transaction(
function(transaction) {
transaction.executeSql('DELETE FROM entries WHERE id=?;',
[id], null, errorHandler);
}
);
}
As we’ve done in previous examples, we open a
transaction, pass it a callback function with the transaction object as
the parameter, and call the executeSql() method. We’re
passing in the SQL query and the ID of the clicked record as the first
two arguments. The third argument is where the success handler would go,
but we don’t need one, so we just specify null. As the fourth argument,
we specify the same error handler that we’ve been using all
along.
And there you have it. It may have taken a
lot of description to get to this point, but in reality we haven’t had
to write all that much code. In fact, kilo.js only
contains about 100 lines of JavaScript (Example 1).
Example 1. The complete JavaScript listing for Kilo database
interaction
var jQT = $.jQTouch({ icon: 'kilo.png' }); var db; $(document).ready(function(){ $('#createEntry form').submit(createEntry); $('#settings form').submit(saveSettings); $('#settings').bind('pageAnimationStart', loadSettings); $('#dates li a').click(function(){ var dayOffset = this.id; var date = new Date(); date.setDate(date.getDate() - dayOffset); sessionStorage.currentDate = date.getMonth() + 1 + '/' + date.getDate() + '/' + date.getFullYear(); refreshEntries(); }); var shortName = 'Kilo'; var version = '1.0'; var displayName = 'Kilo'; var maxSize = 65536; db = openDatabase(shortName, version, displayName, maxSize); db.transaction( function(transaction) { transaction.executeSql( 'CREATE TABLE IF NOT EXISTS entries ' + ' (id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, ' + ' date DATE NOT NULL, food TEXT NOT NULL, ' + ' calories INTEGER NOT NULL);' ); } ); }); function loadSettings() { $('#age').val(localStorage.age); $('#budget').val(localStorage.budget); $('#weight').val(localStorage.weight); } function saveSettings() { localStorage.age = $('#age').val(); localStorage.budget = $('#budget').val(); localStorage.weight = $('#weight').val(); jQT.goBack(); return false; } function createEntry() { var date = sessionStorage.currentDate; var calories = $('#calories').val(); var food = $('#food').val(); db.transaction( function(transaction) { transaction.executeSql( 'INSERT INTO entries (date, calories, food) VALUES (?, ?, ?);', [date, calories, food], function(){ refreshEntries(); jQT.goBack(); }, errorHandler ); } ); return false; } function refreshEntries() { var currentDate = sessionStorage.currentDate; $('#date h1').text(currentDate); $('#date ul li:gt(0)').remove(); db.transaction( function(transaction) { transaction.executeSql( 'SELECT * FROM entries WHERE date = ? ORDER BY food;', [currentDate], function (transaction, result) { for (var i=0; i < result.rows.length; i++) { var row = result.rows.item(i); var newEntryRow = $('#entryTemplate').clone(); newEntryRow.removeAttr('id'); newEntryRow.removeAttr('style'); newEntryRow.data('entryId', row.id); newEntryRow.appendTo('#date ul'); newEntryRow.find('.label').text(row.food); newEntryRow.find('.calories').text(row.calories); newEntryRow.find('.delete').click(function(){ var clickedEntry = $(this).parent(); var clickedEntryId = clickedEntry.data('entryId'); deleteEntryById(clickedEntryId); clickedEntry.slideUp(); }); } }, errorHandler ); } ); } function deleteEntryById(id) { db.transaction( function(transaction) { transaction.executeSql('DELETE FROM entries WHERE id=?;', [id], null, errorHandler); } ); } function errorHandler(transaction, error) { alert('Oops. Error was '+error.message+' (Code '+error.code+')'); return true; }
|