I am trying to use indexedDB to store offline data, and then upload the data when connected. In the following code a loop is used to read the data from indexedDB, and for each record (object) in the table (store), a JSON object is created and posted to a PHP file. However, this indexedDB loop only executes once. Is this because the JSON object was sent to server asynchronously?
var trans = LocalDB.indexedDB.db.transaction(storename,
IDBTransaction.READ_WRITE);
var store = trans.objectStore(storename);
var keyRange = IDBKeyRange.lowerBound(0);
var cursorRequest = store.openCursor(keyRange);
cursorRequest.onsuccess = function (e) {
var result = e.target.result;
var obj = new Object;
obj.name = result.value.Name;
obj.Date = result.value.Date;
if (window.XMLHttpRequest)
xmlhttp = new XMLHttpRequest();
else
xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
xmlhttp.onreadystatechange = function () {
if (xmlhttp.readyState == 4 && xmlhttp.status == 200)
{
alert(xmlhttp.responseText);//problem: only shown once
result.continue();
}
};
xmlhttp.open("POST", "upload.php");
xmlhttp.setRequestHeader("Content-type", "application/json", true);
xmlhttp.send(JSON.stringify(obj));
};
cursorRequest.onerror = function (e) { alert("Error uploading"); };
If you check your Console for errors, you'll probably see an:
Uncaught Error: TransactionInactiveError
This does seem to be due to the Ajax request delaying the result.continue(). In the meantime, the transaction apparently becomes inactive and can no longer be used by the cursor.
You'll want to move the result.continue() out of the onreadystatechange:
// ...
xmlhttp.send(JSON.stringify(obj));
result.continue();
You could also opt for Sjax (synchronous). But, that's not generally recommended.
Also, note that the onsuccess callback will be called an additional time with a null result to signify the cursor has completed, so you'll want to test for this:
cursorRequest.onsuccess = function (e) {
var result = e.target.result;
if (!result) {
console.log('Done');
return; // exit callback
}
// ...
};
You could also use this to send the entire collection in an Array with a single Ajax request:
var storedCollection = [];
cursorResult.onsuccess = function (e) {
var result = e.target.result;
if (result) {
storedCollection.push(result.value);
result.continue();
return; // exit callback
}
// else: the cursor is "done"
var xmlhttp = new XMLHttpRequest();
// ...
xml.send(JSON.stringify(storedCollection));
};
Example: http://jsfiddle.net/CZBrd/ (check Console)
Related
I'm using Code Igniter and the Googlemaps library. This library generates a lot of Javascript code dynamically, including the contents of the InfoWindows for each new marker, but I'd like to keep that in a separate template file, like a regular View.
I have this Javascript code (from Googlemaps' library):
var lat = marker.getPosition().lat();
var long = marker.getPosition().lng();
var windowContent = "";
if( _new ) {
var newIW = new google.maps.InfoWindow( { content: windowContent } );
What I want to do is to load windowContent from a template file. I have already succeeded in dynamically generating a form for this variable and using lat and long variables defined just above, but how can I achieve this in Code Igniter? I can't use load->view because I'm not in a Controller's context. And I cannot use include() or readfile() either because of CI's security constraints.
Any hints?
Using pure javascript, get the lat and long, make a url with the lat and long in the query string, and use xhr to do the ajax call.
var lat = marker.getPosition().lat();
var long = marker.getPosition().lng();
var xhr;
var url = "http://myurl.to/script.php?lat="+lat+"&lng="+long;
if(typeof XMLHttpRequest !== 'undefined')
xhr = new XMLHttpRequest();
else {
//Get IE XHR object
var versions = ["MSXML2.XmlHttp.5.0",
"MSXML2.XmlHttp.4.0",
"MSXML2.XmlHttp.3.0",
"MSXML2.XmlHttp.2.0",
"Microsoft.XmlHttp"];
for(var i = 0, len = versions.length; i < len; i++) {
try {
xhr = new ActiveXObject(versions[i]);
break;
}
catch(e){}
}
}
xhr.onreadystatechange = function(){
//This function is called every so often with status updates
//It is complete when status is 200 and readystate is 4
if(xhr.status == 200 && xhr.readyState === 4) {
//Returned data from the script is in xhr.responseText
var windowContent = xhr.responseText;
//Create the info window
var newIW = new google.maps.InfoWindow( { content: windowContent } );
//Pass newIW to whatever other function to use it somewhere
}
};
xhr.open('GET', url, true);
xhr.send();
if using a library like jQuery it would be like
var lat = marker.getPosition().lat();
var long = marker.getPosition().lng();
var url = "http://myurl.to/script.php";
jQuery.ajax({
"url":url,
"data":{ //Get and Post data variables get put here
"lat":lat,
"lng":long
},
"dataType":"html", //The type of document you are getting, assuming html
//Could be json xml etc
"success":function(data) { //This is the callback when ajax is done and successful
//Returned data from the script is in data
var windowContent = data;
//Create the info window
var newIW = new google.maps.InfoWindow( { content: windowContent } );
//Pass newIW to whatever other function to use it somewhere
}
});
Quick notes. I am not using jQuery so don't suggest it.
When pressing the button which has the onclick="ajaxfunction();" i get an alert saying "Error during AJAX call. Please try again " and then I get the alert saying success, twice :S ... Why is this happening?
I don't understand why this is happening, as it calls the error, and then goes to the other part of the if statement...
Thanks in advance!
<script>
function getXMLObject() //XML OBJECT
{
var xmlHttp = false;
try {
xmlHttp = new ActiveXObject("Msxml2.XMLHTTP") // For Old Microsoft Browsers
}
catch (e) {
try {
xmlHttp = new ActiveXObject("Microsoft.XMLHTTP") // For Microsoft IE 6.0+
}
catch (e2) {
xmlHttp = false // No Browser accepts the XMLHTTP Object then false
}
}
if (!xmlHttp && typeof XMLHttpRequest != 'undefined') {
xmlHttp = new XMLHttpRequest(); //For Mozilla, Opera Browsers
}
return xmlHttp; // Mandatory Statement returning the ajax object created
}
var xmlhttp = new getXMLObject(); //xmlhttp holds the ajax object
var url="insertProduct.php";
function ajaxFunction() {
var getdate = new Date(); //Used to prevent caching during ajax call
if(xmlhttp) {
var name = document.getElementById("name");
var code = document.getElementById("code");
xmlhttp.open("POST",url,true); //calling insertProduct.php using POST method
xmlhttp.onreadystatechange = handleServerResponse;
xmlhttp.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
xmlhttp.send("name=" + encodeURIComponent(name.value) + "&code=" + encodeURIComponent(code.value)); //Posting to PHP File
}
}
function handleServerResponse() {
if (xmlhttp.readyState == 4 || xmlhttp.readyState=="complete") {
alert("Success");
document.getElementById("message").innerHTML=xmlhttp.responseText; //Update the HTML Form element
}
else {
alert("Error during AJAX call. Please try again " + xmlhttp.status);
}
}
</script>
After finishing the task you can call return;
Likes below.
function handleServerResponse() {
if (xmlhttp.readyState == 4 || xmlhttp.readyState=="complete") {
alert("Success");
document.getElementById("message").innerHTML=xmlhttp.responseText;
return;
}
else {
alert("Error during AJAX call. Please try again " + xmlhttp.status);
return;
}
}
I hope this will help to you.
i have page that do add new record by old way ajax, this code was add new record and return the error or done result message , how can i print the message on div and print result on other div. i try but some one tell me to use JOSN, how can i do that
<script language="JavaScript">
$(document).ready(function() {
});
$("#closeerr").live('click', function() {
$("#gadget").hide();
});
var HttPRequest = false;
function doCallAjax(Mode,Page,ID) {
HttPRequest = false;
if (window.XMLHttpRequest) { // Mozilla, Safari,...
HttPRequest = new XMLHttpRequest();
if (HttPRequest.overrideMimeType) {
HttPRequest.overrideMimeType('text/html');
}
} else if (window.ActiveXObject) { // IE
try {
HttPRequest = new ActiveXObject("Msxml2.XMLHTTP");
} catch (e) {
try {
HttPRequest = new ActiveXObject("Microsoft.XMLHTTP");
} catch (e) {}
}
}
if (!HttPRequest) {
alert('Cannot create XMLHTTP instance');
return false;
}
var url = 'AjaxItemsGroupsRecord.php';
var pmeters = "titems_groups_GroupName=" + encodeURI( document.getElementById("items_groups_GroupName").value) +
"&titems_groups_sys_type_ID=" + encodeURI( document.getElementById("items_groups_sys_type_ID").value ) +
'&myPage='+Page +
"&tID=" + ID +
"&tMode=" + Mode;
HttPRequest.open('POST',url,true);
HttPRequest.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
HttPRequest.setRequestHeader("Content-length", pmeters.length);
HttPRequest.setRequestHeader("Connection", "close");
HttPRequest.send(pmeters);
HttPRequest.onreadystatechange = function()
{
if(HttPRequest.readyState == 3) // Loading Request
{
document.getElementById("mySpan").innerHTML = "looding";
}
if(HttPRequest.readyState == 4) // Return Request
{
document.getElementById("mySpan").innerHTML = HttPRequest.responseText;
}
}
}
</script>
If jQuery is an option... As mentioned in my comment I'd recommend you try out jQuery http://jquery.com/ as you look to be fairly new to JavaScript.
It makes AJAX requests a lot simpler and you don't have to worry about making XMLHttpRequest work cross browser.
For making an actual AJAX request see: http://api.jquery.com/jQuery.ajax/
Now if you want to use JSON you need to convert the data to return in your PHP script.
This is really easy, you just pass the data in json_encode() and it will convert the data to a JSON string. You then just echo it out so that it's returned to the AJAX request.
echo json_encode($data);
Now if you've setup your AJAX request to expect a JSON response then you can use the data that comes back. So something like this:
$.ajax({
url: 'request.php', // the php you want to call
dataType: 'json' // the type of data being returned
}).done(function(json) {
// you now have a json object
});
If you can only use native JavaScript...
If you can't use jQuery then it roughly works the same way. You'd have the code in your example for the AJAX request. You'd still use json_encode() in the PHP. The only difference is when the data comes back you'd need to parse it like so:
JSON.parse(json);
For more info on this last bit checkout: Parse JSON in JavaScript?
These are my three functions that I am using in javascript :
function postRequest()
{
var xmlHttp;
if(window.XMLHttpRequest)
{ // For Mozilla, Safari, ...
var xmlHttp = new XMLHttpRequest();
}
else if(window.ActiveXObject)
{ // For Internet Explorer
var xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");
}
xmlHttp.open('GET', 'effort.php', true);
xmlHttp.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
xmlHttp.onreadystatechange = function()
{
if (xmlHttp.readyState == 4)
{
get_string(xmlHttp.responseText);
dij();
}
}
xmlHttp.send(null);
}
function get_string(str)
{
get_integer = str.split(" ");
for(var i=0;i<214;i++)
{
vertex_i[j] = get_integer[i]*1;
j++;
}
j=0;
for(var i=214;i<427;i++)
{
vertex_f[j] = get_integer[i]*1;
j++;
}
j=0;;
for(var i=427;i<517;i++)
{
x[j] = get_integer[i]*1;
j++;
}
j=0;
for(var i=517;i<607;i++)
{
y[j] = get_integer[i]*1;
j++;
}
for(var m=0;m<90;m++)
{
for(var n=0;n<90;n++)
{
L[m][n] = -1;
}
}
for(var m=0;m<212;m++)
{
x1 = x[vertex_i[m]];
x2 = x[vertex_f[m]];
y1 = y[vertex_i[m]];
y2 = y[vertex_f[m]];
L[vertex_i[m]][vertex_f[m]] = parseInt(find_dist(x1,x2,y1,y2));
}
}
function point_it(event)
{
postRequest();
}
namely :
point_it(event),then postRequest(); and finally dij();
In these functions I use the data in three globally defined arrays,the elements of whose are derived from the data sent by the server(get_string function).
if I call dij() function from within the postRequest() function(after the get_string function I am able to access the correct data within the arrays.
However if I call it immediately after the postRequest() function the value of elements in the array become equal to null.
I am unable to understand the proper reason for this and have tried several ways to get through but with no progress.
CAn sm1 please help me out !
postRequest fires an asynchronous request to the server. Calling a function directly after it doesnt mean that the request has finished and youve doen anything with the response data. It works inside postRequest because that where you actually handle processing the request and response.
if you want to do this all from within point it i would recommend doing the following:
function postRequest(callback)
{
var callbackFunc = callback||null;
var xmlHttp;
if(window.XMLHttpRequest)
{ // For Mozilla, Safari, ...
var xmlHttp = new XMLHttpRequest();
}
else if(window.ActiveXObject)
{ // For Internet Explorer
var xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");
}
xmlHttp.open('GET', 'effort.php', true);
xmlHttp.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
xmlHttp.onreadystatechange = function()
{
if (xmlHttp.readyState == 4)
{
get_string(xmlHttp.responseText);
if(callbackFunc){
callbackFunc();
}
}
}
xmlHttp.send(null);
}
function point_it(event)
{
postRequest(dij);
}
this allows you to vary the callback that uses the array thats been populated by the post request and in a away that it always fires after that request cycle is complete.
XMLHttpRequest is asynchronous.
That means, it will return as soon as the request was send. If you now call dij() the request will still be pending and get_string wasn't called yet.
As soon as the requests completes, the callback will be called, and then execute get_string.
You need to leave dij() inside the callback too.
Visually:
postRequest is made, sets the callback, but does not execute it, postRequest then returns
the code after the call to postRequest executes
some time passes...
the XMLHttpRequest finally completes and the callback executes, which now calls get_string
Global variables are not a good practice. It is better to combine your get_string and dij functions into one with your arrays as local variables inside the single function.
Is it possible to send Ajax requests to two or more Php scripts simultaneously? I know that this can be achieved serially (getting response from 1 and then getting response from the other) but I am wondering is it possible simultaneously. Please assist me with the following code:
function calShowUpload(){
if (http.readyState == 4) {
res = http.responseText;
document.getElementById('maincontent').innerHTML=res;
}
}
function showUpload(obj)
{
http.open("GET", "./showUpload.php", true);
http.onreadystatechange = calShowUpload;
http.send(null);
}
function getXHTTP() {
var xhttp;
try { // The following "try" blocks get the XMLHTTP object for various browsers…
xhttp = new ActiveXObject("Msxml2.XMLHTTP");
}
catch (e) {
try {
xhttp = new ActiveXObject("Microsoft.XMLHTTP");
}
catch (e2) {
// This block handles Mozilla/Firefox browsers...
try {
xhttp = new XMLHttpRequest();
}
catch (e3) {
xhttp = false;
}
}
}
return xhttp; // Return the XMLHTTP object
}
var http = getXHTTP(); // This executes when the page first loads.
In the above example I know that I can call another function like showUpload(obj) inside calShowUpload() to achieve my objective, but I need something like this:
function showUpload(obj)
{
http.open("GET", "./showUpload.php", true);
http.open("GET", "./showDelete.php", true);
http.onreadystatechange = calShowUpload;
http.send(null);
}
You need two instances of the XMLHttpRequest or the second will stomp the first. The very, very easiest way to do this with your existing code is simply to create two instances and write your JS to use whichever one is appropriate to the task.
var http1 = getXHTTP(); // Use this for one request.
var http2 = getXHTTP(); // Use this for the other request.