I use the following code to query my websql database to see if there are any records.
If records are found then I use an ajax request to submit these to an asp page which in turn pushes the form information on to a sql server.
So far everything is good however I now want to delete each of the records from the WebSql database only when the ajax request returns a success.
I can't for the life of me get my head around javascript functions and scope correctly when they are nested this big (i've only been writing js/jquery now for a couple of weeks).
I know I need to capture the ID which I have set as a variable vID an then execute another sql statement to delete the record, nested within the success criteria of my ajax call. I cant get vID to reference correctly and then I do not know how to set up the call to execute the sql again based on this.
function Web_SQL_Storage_Open_And_Check() {
if (window.openDatabase) {
var db = openDatabase("ER_Nonconformance", "1.0", "Non-conformance Report DB", 4 * 1024 * 1024); //creates our database if it does not exist at 4mb size
var db2 = db.transaction(function(tx) {
tx.executeSql("CREATE TABLE IF NOT EXISTS tbllog (ID INTEGER PRIMARY KEY ASC AUTOINCREMENT, DteOccur datetime, Pdetected nvarchar(50), DeptRaisedBy int, DeptResp int, NCDescrip nvarchar(255), NCCause nvarchar(255), NCImmediateAct nvarchar(255), NCLocation nvarchar(100), PNumOrRef nvarchar(30), EventCat int, ReportedEmailAddy nvarchar(100), Location_Category int)");
tx.executeSql("SELECT * FROM tbllog", [], function(tx, result) {
if (result.rows.length > 0) {
alert("we need to submit")
for (var i = 0; i < result.rows.length; i++) {
//Submit values to the asp page using the below loop
var vID = (result.rows.item(i)['ID'])
var vPdetected = result.rows.item(i)['Pdetected']
var vDteOccur = result.rows.item(i)['DteOccur']
var vDeptRaisedBy = result.rows.item(i)['DeptRaisedBy']
var vDeptResp = result.rows.item(i)['DeptResp']
var vNCDescrip = result.rows.item(i)['NCDescrip']
var vNCCause = result.rows.item(i)['NCCause']
var vNCImmediateAct = result.rows.item(i)['NCImmediateAct']
var vNCLocation = result.rows.item(i)['NCLocation']
var vPNumOrRef = result.rows.item(i)['PNumOrRef']
var vEventCat = result.rows.item(i)['EventCat']
var vReportedEmailAddy = result.rows.item(i)['ReportedEmailAddy']
var vLocation_Category = result.rows.item(i)['Location_Category']
var request = $.ajax({
url: "untitled.asp",
type: "post",
data: {
DteOccur: vDteOccur,
Pdetected: vPdetected,
DeptRaisedBy: vDeptRaisedBy,
DeptResp: vDeptResp,
NCDescrip: vNCDescrip,
NCCause: vNCCause,
NCImmediateAct: vNCImmediateAct,
NCLocation: vNCLocation,
PNumOrRef: vPNumOrRef,
EventCat: vEventCat,
ReportedEmailAddy: vReportedEmailAddy,
Location_Category: vLocation_Category
},
dataType: "html"
}
);
request.done(function() { alert("done"); })
request.fail(function() { alert("error"); })
request.always(function() { alert("complete"); });
}
}
else {
//no records found so do nothing
alert("do nothing")
} //end of if statement
}, function(tx, error) {
alert("error retrieving")
})
//tx.executeSql();
});
}
}
Define var vID outside function, not inside and that gives you the correct reference.
Related
How do i get list items from different lists in SharePoint using javascript. Given that all my list are stored in an array. And I need to loop through the array and execute similar functions on each list.
function initializePage() {
listcollections.forEach(function (value, index) { // listcollections is the array that contains the list url for different lists
var listtitle = value.listTitle;
var siteUrl = value.siteURL;
getItemsWithCaml(siteUrl, listtitle,
function (camlItems) {
var listItemEnumerator = camlItems.getEnumerator();
while (listItemEnumerator.moveNext()) {
var EventsItem = new Events();
var listItem = listItemEnumerator.get_current();
EventsItem.eventTitle = listItem.get_item('Title');
EventsItem.eventDate = listItem.get_item('EventDate');
EventsItem.eventId = listItem.get_id();
EventsItem.eventSite = siteUrl;
EventsItem.eventList = listtitle;
EventsCollection.push(EventsItem);
}
},
function (sender, args) {
alert('An error occurred while retrieving list items:' + args.get_message());
});
})
};
function getItemsWithCaml(siteUrl, listtitle, header, success, error)
{
var hostWebContext = new SP.ClientContext(siteUrl);
var list = hostWebContext.get_web().get_lists().getByTitle(listtitle);
var caml = new SP.CamlQuery();
//Create the CAML that will return only items expiring today or later
caml.set_viewXml("<View><Query><Where><Geq><FieldRef Name=\'Expires\'/><Value Type=\'DateTime\'><Today /></Value></Geq></Where> </Query></View>");
var camlItems = list.getItems(caml);
hostWebContext.load(camlItems);
hostWebContext.executeQueryAsync(
function () {
success(camlItems);
},
error
);
};
//need to execute certain functions to format each list item
// I am not able to retrieve all list items in a single variable to be able to display data from all lists together
In the example below, I create a JavaScript object named ListDataCollection that contain a property Lists that is an array of objects.
Each of those contain a Url property whit the url of the lists I want to get the content.
Then I loop trough the array of objects and call the Sharepoint REST api for each Url.
Each time a call is complete :
I create a Data property on the current object with the data received
by the ajax call to the REST api.
I also update the current object Completed property to true.
Then I call a function named ifAllCompleted that check if all ajax calls are ended.
When all data is received, I log the word Completed on the browser console.
At this point, you have an array of objects. Each object contains the data of one Sharepoint list.
For example :
ListDataCollection.Lists[0].Data.d.results[0].Title
will contain the value of the Title Column of the first element in the first list.
If you want, you can merge all data in one array using the concat function in JavaScript.
Look at the 4 lines of code following the word Completed.
Hope this can help!
<script>
var ListDataCollection = {
Lists:[{
Url:"http://Url.Of.Your.Site.Collection/_api/web/lists/getbytitle('List1')/Items",
Completed:false
},{
Url:"http://Url.Of.Your.Site.Collection/_api/web/lists/getbytitle('List2')/Items",
Completed:false
},{
Url:"http://Url.Of.Your.Site.Collection/_api/web/lists/getbytitle('List3')/Items",
Completed:false
}]
};
function ifAllCompleted() {
for (var i=0;i<ListDataCollection.Lists.length;i++) {
if (!ListDataCollection.Lists[i].Completed) {
return false;
}
}
console.log('Completed');
var arrayOfAllData = ListDataCollection.Lists[0].Data.d.results;
arrayOfAllData = arrayOfAllData.concat(ListDataCollection.Lists[1].Data.d.results);
arrayOfAllData = arrayOfAllData.concat(ListDataCollection.Lists[2].Data.d.results);
console.log('Total elements : ' + arrayOfAllData.length);
}
$(document).ready(function(){
for (var x=0;x<ListDataCollection.Lists.length;x++) {
$.ajax({
url:ListDataCollection.Lists[x].Url,
indexValue:x,
method: "GET",
headers: { "Accept": "application/json; odata=verbose" },
success: function (data, status, xhr) {
ListDataCollection.Lists[this.indexValue].Data = data;
ListDataCollection.Lists[this.indexValue].Completed = true;
ifAllCompleted();
},
error: function (xhr, status, error) {
console.log('error');
}
});
}
});
</script>
I posted something similar yesterday but it works but only deleted the last object in the data.
What I want to happen
This ajax upload will be handling a lot of data, so I'm using indexeddb. This will also be use on mobile phones. So I wanted it to upload one item at a time and if one item failed to have only deleted the previous items out of the data so they wouldn't need to upload everything again.
I have tried async = false, This works exactly how i want it but this freezers browser.
Current Code Tried to comment out any bits that could be confusing, currently this only deletes the last item once finished.
function uploadData(e) {
//Get Database
var transaction = db.transaction(["data"], "readonly");
var objectStore = transaction.objectStore("data");
var cursor = objectStore.openCursor();
//Starts Looping
cursor.onsuccess = function(e) {
var res = e.target.result;
if (res) {
if (navigator.onLine) {
$('.popup-heading').text('Uploading...');
var passData = {
client_id: res.value.client_id,
parent_id: res.value.parent_id,
storename: res.value.storename,
image: res.value.image,
key: res.key,
};
var jsonData = JSON.stringify(passData);
$.ajax({
url: "{{ path('destination_app_ajax') }}",
type: "post",
// Works but freezes browser
/*async, flase*/
data: {
"json": passData
},
success: function(JsonData) {
//Delete item once successfull
var t = db.transaction(["data"], "readwrite");
var request = t.objectStore("data").delete(passData.key);
t.oncomplete = function(event) {
console.log('item deleted');
};
},
error: function() {
$('.popup-heading').text('Upload Failed!');
}
});
} else {
$('.popup-heading').text('Please find stronger signal or wifi connection');
}
res.
continue ();
}
}
}
It sounds like you have a scope issue with passData. Inside of your loop, but before you defined var passData = ... try wrapping the codeblock with an anonymous function:
(function() {
/* Your code here */
}());
That should prevent passData from leaking into the global scope, which seems to be why your IDB code only works on the last loop. (passData is being redefined each time before your AJAX response is able to complete.)
Update: There is no loop, you're dealing with callbacks. What I see happening is that you're redefining your onsuccess handler on each Ajax request (and overwriting all values but the last), reusing the same transaction. Try moving this transaction code into the success callback for the AJAX request:
//Get Database
var transaction = db.transaction(["data"], "readonly");
var objectStore = transaction.objectStore("data");
var cursor = objectStore.openCursor();
That will create a closure and commit your delete transaction on each response. That means one transaction per AJAX request, and one onsuccess callback per AJAX request (with no redefining).
The only solution I found worked with this was to send the Key via ajax to php then delete from that.
HTML
var passData = {
.......
key: res.key,
};
.....
$.ajax({
url: "yourscript.php",
type: "post",
data: {
"json": passData
},
success: function(JsonData) {
jsonKey = JSON.parse(JsonData);
//Delete item once successfull
var t = db.transaction(["data"], "readwrite");
var request = t.objectStore("data").delete(parseInt(jsonKey.key));
t.oncomplete = function(event) {
console.log('item deleted', jsonKey.key);
};
}
PHP
$data = $_POST['json'];
$returnKey = json_encode(
array(
'key' => $data['key']
)
);
I have a series of ajax calls that fill columns on a page.
var doneDefers = function(defer) {
// leftColDefer is another deferred that sets some header info
$.when(defer, leftColDefer).done(function(req1, req2){
var data = req1[0],
head = req2[0];
// spit this data out to elements on the page
});
};
for(i=0;i<window.ids.length;i++){
defer[i] = $.ajax({
url: 'api/get_runs_stats.php',
type: 'GET',
dataType: 'json',
data: {
run_id: window.ids[i]
}
});
doneDefers(defer[i]);
}
This works fine. If an ajax call fails, nothing is spit out and all is right with the world.
Now I want to do some calculations based on all the data that got spit out.
$.when.apply(null, defer)
.done(function() {
var args = Array.prototype.slice.call(arguments);
calcDeltas();
})
.fail(function() {
var args = Array.prototype.slice.call(arguments);
console.log('in list fail');
});
The done function works fine none of the ajax calls fail. If one of them fail, I go into the fail function and I don't have access to any of the return data from the other runs. The arguments array only has the failed call's data.
I would like to do my calculations on the data sets that passed. How can I get to the data from the good calls when one of them fails?
I'm not sure this is the simplest solution but it stands a chance of working.
var ajax_always_promises = [],//to be populated with promises that (barring uncaught error) are guaranteed to be resolved.
data_arr = [],//an array to be (sparsely) populated with asynchronously delivered json data.
error_arr = [];//an array to be (sparsely) populated with ajax error messages.
$.each(window.ids, function(i, id) {
var dfrd = $.Deferred();
var p = $.ajax({
url: 'api/get_runs_stats.php',
type: 'GET',
dataType: 'json',
data: {
run_id: window.ids[i]
}
}).done(function(json_data) {
data_arr[i] = json_data;//intentionally not `data_arr.push(json_data);`
}).fail(function(jqXHR, textStatus, errorThrown) {
error_arr[i] = textStatus;//intentionally not `error_arr.push(textStatus);`
}).always(dfrd.resolve);
ajax_always_promises[i] = dfrd.promise();
doneDefers(p);
});
$.when.apply(null, ajax_always_promises).done(function() {
//The data in the (sparsely) populated arrays `data_arr` and `error_arr` is available to be used.
var i, id, success_count=0, error_count=0;
for(i=0; i<Math.max(data_arr.length,error_arr.length); i++) {
//Here, the index i corresponds to the original index of window.ids ...
//...that's the advantage of sparsely populating the arrays.
id = window.ids[i];
if(data_arr[i]) {
//Here, do whatever is required with `data_arr[i]`, and `id` if needed.
success_count++;
}
else if(error_arr[i]) {
//Here, do whatever is required with `error_arr[i]`, and `id` if needed.
error_count++;
}
}
console.log("Success:errors: " + success_count + ':' + error_count);
});
Untested - may well need debugging
Hello i am currently running a javascript on my php page (below) and it comes out with each data that i need is there any way i can connect this through to mysql database? (i am new to javascript)
<script>
var allItems = JSON.parse(localStorage.getItem('itemsArray')) || [];
for(var i = 0; i < allItems.length; i++) {
var item = allItems[i];
console.log('Current item: %o', item);
}
</script>
'itemsArray comes from a save function'
function save(){
var oldItems = JSON.parse(localStorage.getItem('itemsArray')) || [];
var newItem = {};
var num = document.getElementById("num").value;
newItem[num] = {
"methv": document.getElementById("methv").value
,'q1': document.getElementById("q1").value,
'q2':document.getElementById("q2").value,
'q3':document.getElementById("q3").value,
'q4':document.getElementById("q4").value,
'comm':document.getElementById("comm").value
};
oldItems.push(newItem);
localStorage.setItem('itemsArray', JSON.stringify(oldItems));
});
Thanks
PS I already have the connection for the database setup
Post your data with ajax/json request to a php function and do all database related work with php. Next return successful or failure status which will be catch in this called js function, and then you can display the success or failure message with javascript.
Example:
Include jQuery library:
<script src="http://code.jquery.com/jquery-1.9.1.min.js"></script>
Script for ajax request with jQuery:
var path = 'http:/your_url/your_php_script_file.php';
var data = 'json_data=' + JSON.stringify(newItem[num]);
$.ajax({
url: path,
type: "POST",
data: data,
cache: false,
success: function ($returm_msg){
alert($returm_msg);
}
});
PHP for save/update in database:
$receive_value = json_decode($_POST['json_data'], true));
You will get values like
$receive_value['methv'],$receive_value['q1'],....,$receive_value['comm'];
Now do save operation in database.
$result = mysql_query("INSERT INTO .....") or die(mysql_error());
if($result){
return "Success!"; // if not function then simply echo "Success!";
}else{
return "Failure!"; // if not function then simply echo "Failure!";
}
Helpful links:
http://www.bennadel.com/resources/presentations/jquery/demo21/index.htm
http://net.tutsplus.com/tutorials/javascript-ajax/5-ways-to-make-ajax-calls-with-jquery/
I have seen many of these questions on here but none seem to solve my problem. I have a multidimensional (nested) array which I am populating through query. I wish to send the final array over AJAX jQuery:
(function() {
var orderDetails = [];
orderDetails['retailer'] = [];
orderDetails['order'] = [];
db.transaction(function(qry){
qry.executeSql("SELECT * FROM retailers WHERE pending = '1' ", [], function(tx, results){
len = results.rows.length; //if rows.length, means retailer is pending so add details to array. If no length, means retailer exists
for (var i=0; i<len; i++){
console.log('start '+i+' loop in retailers qry');
orderDetails['retailer'][i] = [];
orderDetails['retailer'][i]['localID'] = results.rows.item(i).ID;
orderDetails['retailer'][i]['retailerName'] = results.rows.item(i).retailerName;
orderDetails['retailer'][i]['address'] = results.rows.item(i).address;
orderDetails['retailer'][i]['postcode'] = results.rows.item(i).postcode;
console.log('finish '+i+' loop in retailers qry');
}
}, function(err){console.log(err)})
}
This is how I am populating the array, and here is the AJAX request:
function(){
console.log('start orders qry success callback');
//alert(orderDetails['retailer'][0]['localID']);
var st = JSON.stringify(orderDetails['retailer']);
console.log(st);
$.ajax({//send retailer to server, bring back the ID of the retailer as it is on the server so we can insert it into the order
type: "POST",
cache: false,
//async: false,
url: "https://www.......processOrder.php",
data: { orderType: 'saved', orderDetails: st},
dataType: "json",
success: function(result){
}
})
});
When I log the above just before the ajax request, it returns [[],[],[],[],[],[],[],[],[],[],[]] so I know something is working, I just thought the whole contents of the object would be visible on the server side.
Also I have wrapped the whole thing in an anonymous function because I think this helps the array variable scope.
Change this orderDetails['retailer'][i] = []; to this orderDetails['retailer'][i] = {};
And if your item is not a function you want to call with parameter i, access it like this: results.rows.item[i].ID