I am trying to add a contact in a table. The logic is simple , if the contact already exist confirm modal will ask for confirmation for replacement. Otherwise the contact will be inserted as a new contact.
The addContact() method is called from a html page with onClick event .
The problem is newContact() is called but it's not doing anything , what is the problem ?
function addContact() {
var conName = document.getElementById("conName").value;
var conNumber = document.getElementById("conNumber").value;
newContact(conName, conNumber);
}
function newContact(conName, conNumber) {
var db = window.openDatabase("myDB", "1.0", "myDB", 200000);
db.transaction(function(tx) {
tx.executeSql("SELECT * FROM contact", [], function(tx, rs) {
var contactAlreadyExist=false;
for (var i = 0; i < rs.rows.length; i++) {
var row = rs.rows.item(i);
if(row['name']==conName){
if (confirm("Want to replace contact " + conName + "?")) {
var db = window.openDatabase("qpdio", "1.0", "QPDIO", 200000);
db.transaction(function(tx) {
var sql = "Update contact set number="+conNumber+" WHERE ID="+row['id'];
tx.executeSql(sql);
contactAlreadyExist=true;
return true;
});
}
}
}
});
if(!contactAlreadyExist){
tx.executeSql("INSERT INTO contact (name, number) VALUES ('" + conName + "','" + conNumber + "')");
console.log("Here");
}
},errorAddingContact, successAddingContact);
}
function errorAddingContact(err) {
navigator.notification.alert("Error Adding Contact " + err.code, null,
"Error", "Ok");
}
function successAddingContact() {
navigator.notification.alert("Contact Saved successfully!", null,
"Information", "Ok");
}
Can you try this? And let me know if there are errors? I'll edit this answer accordingly. Also if you can check the code alignment (tabs/spaces especially for lines with brackets), it would be good as I think it's a bit messy, maybe due to copy-paste
Note that
I am not a phonegap expert
The error and success call back now have alerts
executeSql now has 4 parameters (including error callback), yours seemed to have 5, but this might be because of the code alignment makes me misread the brackets
confirm doesn't need if, does it? Please check the API
note that the location of contactAlreadyExist check is now still within the successCallback of executeSQL
Code
function newContact(conName, conNumber) {
var db = window.openDatabase("myDB", "1.0", "myDB", 200000);
db.transaction(
function(tx) {
tx.executeSql
(
"SELECT * FROM contact",
[],
function(tx, rs) {
var contactAlreadyExist=false;
for (var i = 0; i < rs.rows.length; i++)
{
var row = rs.rows.item(i);
if(row['name']==conName)
{
confirm
(
"Want to replace contact " + conName + "?",
function()
{
var db = window.openDatabase("qpdio", "1.0", "QPDIO", 200000);
db.transaction(function(tx) {
var sql = "Update contact set number="+conNumber+" WHERE ID="+row['id'];
tx.executeSql(sql);
contactAlreadyExist=true;
return true;
});
}
);
}
}
if (!contactAlreadyExist)
{
tx.executeSql("INSERT INTO contact (name, number) VALUES ('" + conName + "','" + conNumber + "')");
console.log("Here");
}
},
errorAddingContact
);
}
,errorAddingContact, successAddingContact);
}
function errorAddingContact(err) {
alert(err.code);
navigator.notification.alert("Error Adding Contact " + err.code, null,
"Error", "Ok");
}
function successAddingContact() {
alert(err.code);
navigator.notification.alert("Contact Saved successfully!", null,
"Information", "Ok");
}
Related
I want to return multiple rows as an array from a particular table in a database in WebSQL inside a javaScript function. Below is my code.
function getCustomerAccountDetails(){
var dataset;
db.transaction(function(tx) {
tx.executeSql('SELECT * FROM contacts', [], function(tx, results) {
dataset = results.rows;
});
});
return dataset
}
Any suggestions?
I just managed to do that using Return a COUNT from a WebSQL query in a javaScript function
According to the link, using jQuery it goes like this and it works! But I would like to have a javaScript answer.
function getCustomerAccountDetails(){
var defer = $.Deferred();
db.transaction(function(tx) {
tx.executeSql('SELECT * FROM contacts', [], function(tx, results) {
defer.resolve(results.rows);
});
});
return defer.promise();
}
function exampleThatUsesUserArray(data) {
//do something that uses count here
return data;
}
var dataArray = getCustomerAccountDetails();
$.when(dataArray).done(function(data) {
//now use count, could be you call another function that needs to use count,
//getCustomerAccountDetails();
alert(exampleThatUsesUserArray(data.length) + " Row Count");
for(var i = 0; i < data.length; i++){
alert((i+1) + "-" + data.item(i)['id'] + "-" + data.item(i)['firstname'] + "-"
+ data.item(i)['lastname'] + "-" + data.item(i)['phonenumber']);
}
//or assign it to another variable, or trigger an event that someone else in you app is listening for
});
I'm trying to use a javascript form in my jqTouch web app, but when I click the "submit" button, it does nothing, and Chrome pops up with this: "Oops! error was could not prepare statement (1 near "when" syntax error) (Code 5)"
My HTML:
<div id="createEntry">
<div class="toolbar">
<h1>New Entry</h1>
<a class="button cancel" href="#">Cancel</a>
</div>
<form method="post">
<ul class="rounded">
<li><input type="text" placeholder="What" name="what" id="what"></li>
<li><input type="text" placeholder="When" name="when" id="when"></li>
<li><input type="text" placeholder="Comments" name="comments" id="comments"></li>
<li><input type="submit" class="submit" name="action" value="Save Entry"></li>
</ul>
</form>
</div>
and here is my javascript:
var jQT= $.jQTouch({
icon:'kilo.png'
});
var db;
$(document).ready(function(){
$('#createEntry form').submit(createEntry);
});
var shortName = 'AstronomersAid';
var version = '1.1';
var displayName = 'AstronomersAid';
var maxSize = 65536;
db = openDatabase(shortName, version, displayName, maxSize);
// database upgrade function as described on page 133.
if (db.version == '1.0') {
db.changeVersion('1.0', version,
function(transaction) {
transaction.executeSql(
'ALTER TABLE entries ' +
' ADD COLUMN longitude TEXT');
transaction.executeSql(
'ALTER TABLE entries ' +
' ADD COLUMN latitude TEXT');
},
function(e) {
alert('DB upgrade error: ' + e.message);
}
);
} else if (db.version == '') {
db.changeVersion('', version);
} // end database upgrade.
function refreshEntries() {
var currentDate = sessionStorage.currentDate;
$('#passport h1').text(currentDate);
$('#passport 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('#passport ul');
newEntryRow.find('.label').text(row.what);
newEntryRow.find('.when').text(row.when);
newEntryRow.find('.delete').click(function(e) {
var clickedEntry = $(this).parent();
var clickedEntryId = clickedEntry.data('entryId');
deleteEntryById(clickedEntryId);
clickedEntry.slideUp();
e.stopPropogation();
});
newEntryRow.click(entryClickHandler);
}
}, errorHandler
);
}
);
} // end refreshEntries function.
function entryClickHandler(e){
sessionStorage.entryId = $(this).data('entryId');
db.transaction(
function(transaction) {
transaction.executeSql(
'SELECT * FROM entries WHERE id = ?;',
[sessionStorage.entryId],
function (transaction, result) {
var row = result.rows.item(0);
var what = row.what;
var when = row.when;
var comments = row.comments;
$('#inspectEntry input[name="what"]').val(what);
$('#inspectEntry input[name="when"]').val(when);
$('#inspectEntry input[name="comments"]').val(comments);
jQT.goTo('#inspectEntry', 'slideup');
},
errorHandler
);
}
);
} // end entryClickHandler
function createEntry() {
var what = $('#what').val();
var when = $('#when').val();
var comments = $('comments').val();
db.transaction(
function(transaction) {
transaction.executeSql(
'INSERT INTO entries (what, when, comments)
VALUES (?, ?, ?, ?);',
[what, when, comments],
function(){
refreshEntries();
jQT.goBack();
},
errorHandler
);
}
);
return false;
}
function insertEntry(latitude, longitude) {
var what = $('#what').val();
var when = $('#when').val();
var comments = $('#comments').val();
db.transaction(
function(transaction) {
transaction.executeSql(
'INSERT INTO entries (what, when, comments) ' +
'VALUES (?, ?, ?);',
[what, when, comments],
function(){
refreshEntries();
checkBudget();
jQT.goBack();
},
errorHandler
);
}
);
} // end insertEntry function.
function errorHandler(transaction, error) {
alert('Oops! Error was ' + error.message + ' (Code ' + error.code + ')' );
return true;
} // end errorHandler
function deleteEntryById(id){
db.transaction( function(transaction) {
transaction.executeSql(
'DELETE FROM entries WHERE id=?;', [id], null, errorHandler);
}
);
} // end deleteEntryById function.
Can anybody help me out here? I've been trying different things for the last three days, and nothing has worked.
var when = $('#when').val();
"when" is a reserved word. Use another variable name.
I have here a broken function code that would retrieve a specific item from the SQLite database, my problem is I want to pass the value of the retrieved item to displayContent but I do not know how to do it, my code is only designed to retrieve a single row not multiple rows as the contents of SecondColumn are not identical. I am clueless right now.
Here is my code:
function ( content )
{
var displayContent;
db.transaction(function (tx) { tx.executeSql('SELECT FirstColumn FROM SampleTable WHERE SecondColumn = ?',[content]); });
}
Any additional ideas will be gladly accepted, I am stuck with this.
The tx.executeSql method takes a callback where you can then process the results of the query. Have a look here and you can see an example: http://www.tutorialspoint.com/html5/html5_web_sql.htm
As you can see there, they do the following:
db.transaction(function (tx) {
tx.executeSql('SELECT * FROM LOGS', [], function (tx, results) {
var len = results.rows.length, i;
msg = "<p>Found rows: " + len + "</p>";
document.querySelector('#status').innerHTML += msg;
for (i = 0; i < len; i++){
msg = "<p><b>" + results.rows.item(i).log + "</b></p>";
document.querySelector('#status').innerHTML += msg;
}
}, null);
});
In your case you'd probably do something like this:
function ( content )
{
db.transaction(function (tx) {
tx.executeSql('SELECT FirstColumn FROM SampleTable WHERE SecondColumn = ?',[content], function (tx, results) {
if (results.rows.length) {
var displayContent = results.rows.item(0).FirstColumn;
document.querySelector('...').innerHTML = ...; // Display something
}
});
});
}
If you want to try to wait for the query, have a look at this previous Stackoverflow question: HTML5 WebSQL: how to know when a db transaction finishes?
I write some simple app for windows 8 Metro UI with javascript. Because natural method from microsoft to use Sqlite with Javascript in Metro UI. I use 'doo' wrapper:
dooWrapper SQLite (github)
I create a method :
function addSomething(name) {
var dbPath = Windows.Storage.ApplicationData.current.localFolder.path + '\\a_db.sqlite';
SQLite3JS.openAsync(dbPath).then(function (db) {
return db.runAsync("INSERT INTO STH (nazwa) VALUES (:name)", { name: name }).
done(function () {
console.log('Add sth : ' + name);
db.close();
}, function (error) {
if (db) {
db.close();
}
console.log('ERROR Adding sth' + error.message);
})
});
}
I get error 'database is locked' I read about this error in documentation. But I have one question is other solution to add more rows without create 'insert' function with collections argument something like that : insert (array) ? I just want to use that function n-times without this error. That's possible?
Yes,it possible...i also got this error before....For that you just need to establish the database connection once...i have used this in my app and its working fine.
If there is no need of closing your db then then open database once like..
Add this code to default.js file
var myDatabase; //Global Variable
var dbPath = Windows.Storage.ApplicationData.current.localFolder.path + '\\db.sqlite';
//Create Table
SQLite3JS.openAsync(dbPath).then(function(db) {
myDatabase=db;
return db.runAsync('CREATE TABLE Item (name TEXT, price REAL, id INT PRIMARY KEY)');
});
Then you just need to use below code
// For Insert
return myDatabase.runAsync('INSERT INTO Item (name, price, id) VALUES ("'+ array[i].name+'", "48484", 1);
For array
var dbPromises = [];
var testArray = [];
//only for test purpose
//You can pass your array here directly
for (var a = 0; a < 300; a++) {
var obj = {
name: "Mango"+a,
price: 100+a,
id: a
};
testArray.push(obj);
}
for (var i = 0; i < testArray.length; i++) {
var query = 'INSERT OR REPLACE INTO Item (name, price, id) VALUES ("' + testArray[i].name + '",' + testArray[i].price + ',' + testArray[i].id + ')';
dbPromises.push(globalDatabase.allAsync(query));
}
WinJS.Promise.join(dbPromises).then(function () {
debugger;
}, function(err) {
debugger;
});
Above code is used only for less array size...bcz its taking too much time for insertion...
For fasst execution you should replace just below code
for (var i = 0; i < testArray.length; i++) {
var val = '("' + testArray[i].name + '",' + testArray[i].price + ',' + testArray[i].id + '),';
query = query + val;
if ((i + 1) % 300 == 0 || (i + 1) == testArray.length) {
query = query.replace(/,$/, "");
dbPromises.push(globalDatabase.allAsync(query));
query = 'INSERT OR REPLACE INTO Item (name, price, id) VALUES ';
}
}
Resources:
http://docs.phonegap.com/en/2.9.0/cordova_storage_storage.md.html#database_version
Device/Framework Info:
Nexus 4 - Android 4.2.2
Phonegap 2.9.0
Also using the bootstrap library for UI
I have followed the PhoneGap tutorial for version 2.9 on creating, and managing a database. So far I have found little to no places where people are talking about the specific error 23 when trying to write to a database.
I get this error after trying to write to a database after the insertBtn's click function, which executes the insertTemplate function.
The same thing happens when trying to delete a row when the deleteBtn event is fired, which executes the deleteTemplate function.
Any recommendations?
Controller File:
var databaseName = "blackbriar";
var version = 1;
var displayName = "lctv";
var size = 2097152; // two megabytes
var db = null;
$(document).ready(function(event){
// Gets shell for database
db = window.openDatabase("Database", "1.0", "Cordova Demo", 200000);
db.transaction(populateDb, errorCb, successCb);
db.transaction(loadTemplates, errorCb, successCb);
$('#insertBtn').click(function(event){
db.transaction(insertTemplate, errorCb, successCb);
});
$('#back').click(function(event){
$('#templates').show();
$('#templateEdit').hide();
$('#back').hide();
});
$('#deleteBtn').click(function(event){
db.transaction(deleteTemplate, errorCb, successCb);
$('#back').click();
});
});
$(document).on('click', '.pill', function(event){
// If window width is greater than 480px, isMobile variable is false
var isMobile = $(window).width() > 480 ? false : true;
$('#currentId').text($(this).attr('tempid'));
db.transaction(getTemplateById, errorCb, successCb);
if($('#currentId').text() == "-1"){
$('#insertBtn').show();
$('#saveBtn').hide();
$('#deleteBtn').hide();
$('#clearBtn').show();
} else {
$('#insertBtn').hide();
$('#saveBtn').show();
$('#deleteBtn').show();
$('#clearBtn').hide();
}
// Checks if pill is active for UI changes
if($(this).hasClass('active')){
$(this).removeClass('active');
if(!isMobile){$(this).find('.temp').attr('style', 'color: black;');}
} else {
$('.pill').removeClass('active');
$('.pill').find('.temp').attr('style', 'color: black;');
$(this).addClass('active');
if(!isMobile){$(this).find('.temp').attr('style', 'color: white;');}
}
if(isMobile) {
$('#templates').hide();
$('#templateEdit').show();
$('#back').show();
}
});
My function file:
function getShell(databaseName, version, displayName, size) {
return window.openDatabase(databaseName, version, displayName, size);
}
function populateDb(tx) {
tx.executeSql('CREATE TABLE IF NOT EXISTS templates (id INTEGER PRIMARY KEY AUTOINCREMENT, templateName, description, campus, account, department, programName, projectId, taskId)');
}
function errorCb(error) {
alert("Error processing SQL: "+error.code);
}
function successCb() {
alert("Success!");
}
function insertTemplate(tx) {
var templateName = $('#templateName').val();
var description = $('#descriptionField').val();
var campus = $('#campusField').val();
var account = $('#accountField').val();
var department = $('#departmentField').val();
var programName = $('#programNameField').val();
var projectId = $('#projectIdField').val();
var taskId = $('#taskIdField').val();
tx.executeSql('INSERT INTO templates (templateName, description, campus, account, department, programName, projectId, taskId) VALUES ('
+'"'+templateName+'"'+', '
+'"'+description+'"'+', '
+'"'+campus+'"'+', '
+'"'+account+'"'+', '
+'"'+department+'"'+', '
+'"'+programName+'"'+', '
+'"'+projectId+'"'+', '
+'"'+taskId+'"'
+')');
}
function loadTemplates(tx) {
tx.executeSql('SELECT * from templates', [], templatesSuccess, errorCb);
}
function templatesSuccess(tx, results) {
var length = results.rows.length;
$('#templateUl').html('');
$('#templateUl').append('<li class="templi"><a class="pill" tempid="-1"><text class="temp"><i style="color: green;" class="icon-plus"></i> Create</text></a></li>');
for(var i = 0; i < length; i++) {
$('#templateUl').append('<li class="templi"><a class="pill" tempid="'+results.rows.item(i).id+'"><text class="temp">'+results.rows.item(i).templateName+'</text></a></li>');
}
}
function getTemplateById(tx) {
var currentId = $('#currentId').text();
tx.executeSql('SELECT * FROM templates WHERE id = '+currentId, [], loadTemplateSuccess, errorCb);
}
function loadTemplateSuccess(tx, results) {
if(results.rows.length > 0){
var template = results.rows.item(0);
var templateName = $('#templateName').val(template.templateName);
var description = $('#descriptionField').val(template.description);
var campus = $('#campusField').val(template.campus);
var account = $('#accountField').val(template.account);
var department = $('#departmentField').val(template.department);
var programName = $('#programNameField').val(template.programName);
var projectId = $('#projectIdField').val(template.projectId);
var taskId = $('#taskIdField').val(template.taskId);
} else {
var templateName = $('#templateName').val('');
var description = $('#descriptionField').val('');
var campus = $('#campusField').val('');
var account = $('#accountField').val('');
var department = $('#departmentField').val('');
var programName = $('#programNameField').val('');
var projectId = $('#projectIdField').val('');
var taskId = $('#taskIdField').val('');
}
}
function deleteTemplate(tx) {
var currentId = $('#currentId').text();
alert(currentId);
tx.executeSql('DELETE FROM templates', [], templatesSuccess, errorCb);
alert("Authorize!!!");
}
Just came into this, i had to uninstall the app and re made it (Also changed the version but i dont think that did it).
Followed this so i uninstall the app everytime i debug. This can be annoying if you have to insert items each time, but atleast solved it.