Javascript with Ajax working fine in Mozilla but not in Chrome - javascript

I'm using XMLHTTPREQUEST synchronous and while the request is getting fulfilled, I hide everything on page and show a progress message. This works fine in Mozilla but doesn not in Chrome.
Mozilla firefox:
For chrome:
[after submit][3]
here is my javascript code:
if (valid) {
document.getElementById('contentwrapper').style.display="none";
document.getElementById('contentwrapper').style.visibility="hidden";
var cboxes = document.getElementsByName('items[]');
var len = cboxes.length;
var res1;
var res2;
var res3;
var res4;
var arrResult;
for (var i = 0; cboxes[i]; ++i) {
if (cboxes[i].checked) {
checkedValue = cboxes[i].value;
arrResult = checkedValue.split(',');
mobileNo=arrResult[0];
if(arrResult[0].trim().startsWith('0')){
res1 = arrResult[0].substring(1,arrResult[0].length);
}else{
res1 = arrResult[0];
}
res2 = arrResult[1];
res3 = arrResult[2];
res4 = arrResult[3];
requestSender(1, res1, res2, res3, res4);
}
}
function requestSender(code, mobile, operator, productCode, amount) {
var http = getHTTPObject();
var enterKeyHandler = true;
var reqNum = 0;
var seqNum = 0;
var dataCount = 0;
var Values = "";
var code;
var comments = "";
reqCode = code;
if (code == 1) {
var agentcode = '<%=payeeaccountno%>';
var pin = document.getElementById("mpin").value;
source = agentcode; // source and agent code both are same.
operator = operator;
destination = mobile;
productCode = productCode;
if (destination.charAt(0) == '0') {
destination = destination.replace(/^0+/, "");
}
var amt = amount;
var amtPrd = new Array();
amtPrd = amt.split("#");
if (amtPrd.length > 0)
{
amount = amtPrd[0];
// productCode = amtPrd[1];
}
else
{
amount = 0;
}
clienttype = "SELFCARE";
vendorcode = '<%=vendorcode%>';
dataCount = '<%=cryptHandler.encrypt("8",session.getId()+session.getId())%>';
reqNum = '<%=cryptHandler.encrypt("1",session.getId()+session.getId())%>';
seqNum = '<%=cryptHandler.encrypt("2",session.getId()+session.getId())%>';
Values = "&var1=" + escape(agentcode) + "&var2=" + escape(pin) + "&var3=" + escape(amount) + "&var4=" + escape(mobile) + "&var5=" + escape(productCode) + "&var6=" + escape(clienttype) + "&var7=" + escape(operator) + "&var8=" + escape(vendorcode);
}
var varReq = "../Comman/requestForwarder.jsp?page=" + escape("<%=reqPageName%>") + "&reqNum=" + escape(reqNum) + "&seqNum=" + escape(seqNum) + "&dataCount=" + escape(dataCount) + Values;
varReq = varReq.replace(/\+/g, "%2B");
http.open("GET", varReq, false);
httpBuffer = http;
reqCodeBuffer = reqCode;
http.onreadystatechange = responseHandler;
http.send(null);
}

You should actually post some code or at least print the messages in the developer console (ctr + shift + J)
However, the stem of your issue is probably the fact that you are trying to use a synchronous xmlhttpRequest on the "main" execution thread.
Its a bad practice (since It blocks all code from running until the server "answers" your request) and browsers are starting to phase it out. So, if you are using a newer version of chrome, its likely not running the code and complaining about the sync request.
Either use a Web Worker (js version of thread) to run the synchronous XMLHTTPRequest(s) or, better yet, if possible, use the asynchronous version.
Further reading:
https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/Synchronous_and_Asynchronous_Requests

Related

count total number of word in pdf book using node js? [duplicate]

I wonder if is possible to get the text inside of a PDF file by using only Javascript?
If yes, can anyone show me how?
I know there are some server-side java, c#, etc libraries but I would prefer not using a server.
thanks
Because pdf.js has been developing over the years, I would like to give a new answer. That is, it can be done locally without involving any server or external service. The new pdf.js has a function: page.getTextContent(). You can get the text content from that. I've done it successfully with the following code.
What you get in each step is a promise. You need to code this way: .then( function(){...}) to proceed to the next step.
PDFJS.getDocument( data ).then( function(pdf) {
pdf.getPage(i).then( function(page){
page.getTextContent().then( function(textContent){
What you finally get is an string array textContent.bidiTexts[]. You concatenate them to get the text of 1 page. Text blocks' coordinates are used to judge whether newline or space need to be inserted. (This may not be totally robust, but from my test it seems ok.)
The input parameter data needs to be either a URL or ArrayBuffer type data. I used the ReadAsArrayBuffer(file) function in FileReader API to get the data.
Note: According to some other user, the library has updated and caused the code to break. According to the comment by async5 below, you need to replace textContent.bidiTexts with textContent.items.
function Pdf2TextClass(){
var self = this;
this.complete = 0;
/**
*
* #param data ArrayBuffer of the pdf file content
* #param callbackPageDone To inform the progress each time
* when a page is finished. The callback function's input parameters are:
* 1) number of pages done;
* 2) total number of pages in file.
* #param callbackAllDone The input parameter of callback function is
* the result of extracted text from pdf file.
*
*/
this.pdfToText = function(data, callbackPageDone, callbackAllDone){
console.assert( data instanceof ArrayBuffer || typeof data == 'string' );
PDFJS.getDocument( data ).then( function(pdf) {
var div = document.getElementById('viewer');
var total = pdf.numPages;
callbackPageDone( 0, total );
var layers = {};
for (i = 1; i <= total; i++){
pdf.getPage(i).then( function(page){
var n = page.pageNumber;
page.getTextContent().then( function(textContent){
if( null != textContent.bidiTexts ){
var page_text = "";
var last_block = null;
for( var k = 0; k < textContent.bidiTexts.length; k++ ){
var block = textContent.bidiTexts[k];
if( last_block != null && last_block.str[last_block.str.length-1] != ' '){
if( block.x < last_block.x )
page_text += "\r\n";
else if ( last_block.y != block.y && ( last_block.str.match(/^(\s?[a-zA-Z])$|^(.+\s[a-zA-Z])$/) == null ))
page_text += ' ';
}
page_text += block.str;
last_block = block;
}
textContent != null && console.log("page " + n + " finished."); //" content: \n" + page_text);
layers[n] = page_text + "\n\n";
}
++ self.complete;
callbackPageDone( self.complete, total );
if (self.complete == total){
window.setTimeout(function(){
var full_text = "";
var num_pages = Object.keys(layers).length;
for( var j = 1; j <= num_pages; j++)
full_text += layers[j] ;
callbackAllDone(full_text);
}, 1000);
}
}); // end of page.getTextContent().then
}); // end of page.then
} // of for
});
}; // end of pdfToText()
}; // end of class
I couldn't get gm2008's example to work (the internal data structure on pdf.js has changed apparently), so I wrote my own fully promise-based solution that doesn't use any DOM elements, queryselectors or canvas, using the updated pdf.js from the example at mozilla
It eats a file path for the upload since i'm using it with node-webkit.
You need to make sure you have the cmaps downloaded and pointed somewhere and you nee pdf.js and pdf.worker.js to get this working.
/**
* Extract text from PDFs with PDF.js
* Uses the demo pdf.js from https://mozilla.github.io/pdf.js/getting_started/
*/
this.pdfToText = function(data) {
PDFJS.workerSrc = 'js/vendor/pdf.worker.js';
PDFJS.cMapUrl = 'js/vendor/pdfjs/cmaps/';
PDFJS.cMapPacked = true;
return PDFJS.getDocument(data).then(function(pdf) {
var pages = [];
for (var i = 0; i < pdf.numPages; i++) {
pages.push(i);
}
return Promise.all(pages.map(function(pageNumber) {
return pdf.getPage(pageNumber + 1).then(function(page) {
return page.getTextContent().then(function(textContent) {
return textContent.items.map(function(item) {
return item.str;
}).join(' ');
});
});
})).then(function(pages) {
return pages.join("\r\n");
});
});
}
usage:
self.pdfToText(files[0].path).then(function(result) {
console.log("PDF done!", result);
})
Just leaving here a full working sample.
<html>
<head>
<script src="https://npmcdn.com/pdfjs-dist/build/pdf.js"></script>
</head>
<body>
<input id="pdffile" name="pdffile" type="file" />
<button id="btn" onclick="convert()">Process</button>
<div id="result"></div>
</body>
</html>
<script>
function convert() {
var fr=new FileReader();
var pdff = new Pdf2TextClass();
fr.onload=function(){
pdff.pdfToText(fr.result, null, (text) => { document.getElementById('result').innerText += text; });
}
fr.readAsDataURL(document.getElementById('pdffile').files[0])
}
function Pdf2TextClass() {
var self = this;
this.complete = 0;
this.pdfToText = function (data, callbackPageDone, callbackAllDone) {
console.assert(data instanceof ArrayBuffer || typeof data == 'string');
var loadingTask = pdfjsLib.getDocument(data);
loadingTask.promise.then(function (pdf) {
var total = pdf._pdfInfo.numPages;
//callbackPageDone( 0, total );
var layers = {};
for (i = 1; i <= total; i++) {
pdf.getPage(i).then(function (page) {
var n = page.pageNumber;
page.getTextContent().then(function (textContent) {
//console.log(textContent.items[0]);0
if (null != textContent.items) {
var page_text = "";
var last_block = null;
for (var k = 0; k < textContent.items.length; k++) {
var block = textContent.items[k];
if (last_block != null && last_block.str[last_block.str.length - 1] != ' ') {
if (block.x < last_block.x)
page_text += "\r\n";
else if (last_block.y != block.y && (last_block.str.match(/^(\s?[a-zA-Z])$|^(.+\s[a-zA-Z])$/) == null))
page_text += ' ';
}
page_text += block.str;
last_block = block;
}
textContent != null && console.log("page " + n + " finished."); //" content: \n" + page_text);
layers[n] = page_text + "\n\n";
}
++self.complete;
//callbackPageDone( self.complete, total );
if (self.complete == total) {
window.setTimeout(function () {
var full_text = "";
var num_pages = Object.keys(layers).length;
for (var j = 1; j <= num_pages; j++)
full_text += layers[j];
callbackAllDone(full_text);
}, 1000);
}
}); // end of page.getTextContent().then
}); // end of page.then
} // of for
});
}; // end of pdfToText()
}; // end of class
</script>
Here's some JavaScript code that does what you want using Pdf.js from http://hublog.hubmed.org/archives/001948.html:
var input = document.getElementById("input");
var processor = document.getElementById("processor");
var output = document.getElementById("output");
// listen for messages from the processor
window.addEventListener("message", function(event){
if (event.source != processor.contentWindow) return;
switch (event.data){
// "ready" = the processor is ready, so fetch the PDF file
case "ready":
var xhr = new XMLHttpRequest;
xhr.open('GET', input.getAttribute("src"), true);
xhr.responseType = "arraybuffer";
xhr.onload = function(event) {
processor.contentWindow.postMessage(this.response, "*");
};
xhr.send();
break;
// anything else = the processor has returned the text of the PDF
default:
output.textContent = event.data.replace(/\s+/g, " ");
break;
}
}, true);
...and here's an example:
http://git.macropus.org/2011/11/pdftotext/example/
Note: This code assumes you're using nodejs. That means you're parsing a local file instead of one from a web page since the original question doesn't explicitly ask about parsing pdfs on a web page.
#gm2008's answer was a great starting point (please read it and its comments for more info), but needed some updates (08/19) and had some unused code. I also like examples that are more full. There's more refactoring and tweaking that could be done (e.g. with await), but for now it's as close to that original answer as it could be.
As before, this uses Mozilla's PDFjs library. The npmjs package is at https://www.npmjs.com/package/pdfjs-dist.
In my experience, this doesn't do well in finding where to put spaces, but that's a problem for another time.
[Edit: I believe the update to the use of .transform has restored the whitespace as it originally behaved.]
// This file is called myPDFfileToText.js and is in the root folder
let PDFJS = require('pdfjs-dist');
let pathToPDF = 'path/to/myPDFfileToText.pdf';
let toText = Pdf2TextObj();
let onPageDone = function() {}; // don't want to do anything between pages
let onFinish = function(fullText) { console.log(fullText) };
toText.pdfToText(pathToPDF, onPageDone, onFinish);
function Pdf2TextObj() {
let self = this;
this.complete = 0;
/**
*
* #param path Path to the pdf file.
* #param callbackPageDone To inform the progress each time
* when a page is finished. The callback function's input parameters are:
* 1) number of pages done.
* 2) total number of pages in file.
* 3) the `page` object itself or null.
* #param callbackAllDone Called after all text has been collected. Input parameters:
* 1) full text of parsed pdf.
*
*/
this.pdfToText = function(path, callbackPageDone, callbackAllDone) {
// console.assert(typeof path == 'string');
PDFJS.getDocument(path).promise.then(function(pdf) {
let total = pdf.numPages;
callbackPageDone(0, total, null);
let pages = {};
// For some (pdf?) reason these don't all come in consecutive
// order. That's why they're stored as an object and then
// processed one final time at the end.
for (let pagei = 1; pagei <= total; pagei++) {
pdf.getPage(pagei).then(function(page) {
let pageNumber = page.pageNumber;
page.getTextContent().then(function(textContent) {
if (null != textContent.items) {
let page_text = "";
let last_item = null;
for (let itemsi = 0; itemsi < textContent.items.length; itemsi++) {
let item = textContent.items[itemsi];
// I think to add whitespace properly would be more complex and
// would require two loops.
if (last_item != null && last_item.str[last_item.str.length - 1] != ' ') {
let itemX = item.transform[5]
let lastItemX = last_item.transform[5]
let itemY = item.transform[4]
let lastItemY = last_item.transform[4]
if (itemX < lastItemX)
page_text += "\r\n";
else if (itemY != lastItemY && (last_item.str.match(/^(\s?[a-zA-Z])$|^(.+\s[a-zA-Z])$/) == null))
page_text += ' ';
} // ends if may need to add whitespace
page_text += item.str;
last_item = item;
} // ends for every item of text
textContent != null && console.log("page " + pageNumber + " finished.") // " content: \n" + page_text);
pages[pageNumber] = page_text + "\n\n";
} // ends if has items
++self.complete;
callbackPageDone(self.complete, total, page);
// If all done, put pages in order and combine all
// text, then pass that to the callback
if (self.complete == total) {
// Using `setTimeout()` isn't a stable way of making sure
// the process has finished. Watch out for missed pages.
// A future version might do this with promises.
setTimeout(function() {
let full_text = "";
let num_pages = Object.keys(pages).length;
for (let pageNum = 1; pageNum <= num_pages; pageNum++)
full_text += pages[pageNum];
callbackAllDone(full_text);
}, 1000);
}
}); // ends page.getTextContent().then
}); // ends page.then
} // ends for every page
});
}; // Ends pdfToText()
return self;
}; // Ends object factory
Run in the terminal:
node myPDFfileToText.js
Updated 02/2021
<script src="https://npmcdn.com/pdfjs-dist/build/pdf.js"></script>
<script>
function Pdf2TextClass(){
var self = this;
this.complete = 0;
this.pdfToText = function(data, callbackPageDone, callbackAllDone){
console.assert( data instanceof ArrayBuffer || typeof data == 'string' );
var loadingTask = pdfjsLib.getDocument(data);
loadingTask.promise.then(function(pdf) {
var total = pdf._pdfInfo.numPages;
//callbackPageDone( 0, total );
var layers = {};
for (i = 1; i <= total; i++){
pdf.getPage(i).then( function(page){
var n = page.pageNumber;
page.getTextContent().then( function(textContent){
//console.log(textContent.items[0]);0
if( null != textContent.items ){
var page_text = "";
var last_block = null;
for( var k = 0; k < textContent.items.length; k++ ){
var block = textContent.items[k];
if( last_block != null && last_block.str[last_block.str.length-1] != ' '){
if( block.x < last_block.x )
page_text += "\r\n";
else if ( last_block.y != block.y && ( last_block.str.match(/^(\s?[a-zA-Z])$|^(.+\s[a-zA-Z])$/) == null ))
page_text += ' ';
}
page_text += block.str;
last_block = block;
}
textContent != null && console.log("page " + n + " finished."); //" content: \n" + page_text);
layers[n] = page_text + "\n\n";
}
++ self.complete;
//callbackPageDone( self.complete, total );
if (self.complete == total){
window.setTimeout(function(){
var full_text = "";
var num_pages = Object.keys(layers).length;
for( var j = 1; j <= num_pages; j++)
full_text += layers[j] ;
console.log(full_text);
}, 1000);
}
}); // end of page.getTextContent().then
}); // end of page.then
} // of for
});
}; // end of pdfToText()
}; // end of class
var pdff = new Pdf2TextClass();
pdff.pdfToText('PDF_URL');
</script>
For all the people who actually want to use it on a node server:
/**
* Created by velten on 25.04.16.
*/
"use strict";
let pdfUrl = "http://example.com/example.pdf";
let request = require('request');
var pdfParser = require('pdf2json');
let pdfPipe = request({url: pdfUrl, encoding:null}).pipe(pdfParser);
pdfPipe.on("pdfParser_dataError", err => console.error(err) );
pdfPipe.on("pdfParser_dataReady", pdf => {
//optionally:
//let pdf = pdfParser.getMergedTextBlocksIfNeeded();
let count1 = 0;
//get text on a particular page
for (let page of pdf.formImage.Pages) {
count1 += page.Texts.length;
}
console.log(count1);
pdfParser.destroy();
});
It is possible but:
you would have to use the server anyway, there's no way you can get content of a file on user computer without transferring it to server and back
I don't thing anyone has written such library yet
So if you have some free time you can learn pdf format and write such a library yourself, or you can just use server side library of course.

Editing PDFs with Hummus.js problem with certain pages

i am currently trying to edit a pdf with hummus.js to replace certain placeholder characters in the pdf with others.
This works perfectly fine for almost every page, but for certain pages I get the following error:
TypeError:
pageObject.getDictionary(...).toJSObject(...).Contents.getObjectID is
not a function for:
const textObjectID = pageObject.getDictionary().toJSObject().Contents.getObjectID();
Whenever that error happens and it doesnt work,
pageObject.getDictionary().toJSObject().Contents returns a PDFArray {}, while, when it works, it returns an PDFIndirectObjectReference {}
Does anybody know how I could solve this issue or any other way to edit a pdf that way (replacing certain placeholder characters with others)
UPDATE 1: I can now differentiate between IndirectObjectReferences and arrays containing IndirectObjectReferences, but for some reason it removes all text but keeps the images from pdf pages which i access through these arrays, the rest of the pdf pages still work perfectly fine
async function replacetext(filePath, callback) {
var pageCount = 0;
const modPdfWriter = hummus.createWriterToModify(filePath+'.pdf', { modifiedFilePath: `${filePath}-modified.pdf`, compress: false })
const numPages = modPdfWriter.createPDFCopyingContextForModifiedFile().getSourceDocumentParser().getPagesCount()
var log="";
for (let page = 0; page < numPages; page++) {
const copyingContext = modPdfWriter.createPDFCopyingContextForModifiedFile()
const objectsContext = modPdfWriter.getObjectsContext()
const pageObject = copyingContext.getSourceDocumentParser().parsePage(page)
pageCount = pageCount + 1;
try
{
var replaceTextRight = " " + pageCount.toString();
if(pageCount > 9 && pageCount < 100)
{
replaceTextRight = " " + pageCount.toString();
}
else if(pageCount > 99)
{
replaceTextRight = " " + pageCount.toString();
}
const textStream = copyingContext.getSourceDocumentParser().queryDictionaryObject(pageObject.getDictionary(), 'Contents')
console.log(textStream);
if(textStream.toString() == 'Array')
{
let data = []
streamArray = textStream.toJSArray();
for(var i = 0; i<streamArray.length; i++)
{
var streamo = copyingContext.getSourceDocumentParser().queryArrayObject(textStream, i);
const readStream = copyingContext.getSourceDocumentParser().startReadingFromStream(streamo)
while (readStream.notEnded()) {
const readData = readStream.read(10000)
data = data.concat(readData)
}
var redactedPdfPageAsString = new Buffer.from(data).toString();
var replacedBuffer = replace(redactedPdfPageAsString, "12345", pageCount.toString());
log = log+" \n Replaced " +page +" with " + pageCount.toString();
var replacedBuffer = replace(replacedBuffer, "67890", replaceTextRight);
log = log+" \n Replaced " +page +" with " + replaceTextRight;
var textObjectID = streamArray[i].getObjectID();
objectsContext.startModifiedIndirectObject(textObjectID)
var stream = objectsContext.startUnfilteredPDFStream();
stream.getWriteStream().write(strToByteArray(replacedBuffer));
objectsContext.endPDFStream(stream);
objectsContext.endIndirectObject();
}
}
else
{
let data = []
const readStream = copyingContext.getSourceDocumentParser().startReadingFromStream(textStream)
while (readStream.notEnded()) {
const readData = readStream.read(10000)
data = data.concat(readData)
}
var redactedPdfPageAsString = new Buffer.from(data).toString();
var replacedBuffer = replace(redactedPdfPageAsString, "12345", pageCount.toString());
log = log+" \n Replaced " +page +" with " + pageCount.toString();
var replacedBuffer = replace(replacedBuffer, "67890", replaceTextRight);
log = log+" \n Replaced " +page +" with " + replaceTextRight;
const textObjectID = pageObject.getDictionary().toJSObject().Contents.getObjectID();
var content = pageObject.getDictionary().toJSObject().Contents;
objectsContext.startModifiedIndirectObject(textObjectID)
const stream = objectsContext.startUnfilteredPDFStream();
stream.getWriteStream().write(strToByteArray(replacedBuffer));
objectsContext.endPDFStream(stream);
objectsContext.endIndirectObject();
}
}
catch(e){
console.log(e);
}
}
fs.writeFile('C:\\Users\\Administrator\\Downloads\\PDFModifyDebugging\\PDFWRITELOG.txt', log, function (err) {
if (err) return console.log(err);
console.log('written in file');
});
modPdfWriter.end()
hummus.recrypt(`${filePath}-modified.pdf`, filePath)
callback();
}

How to empty an Array in a Script

I have a script that uses AJAX/PHP/SQL to query data and pushes it into an array with a bunch of IF's statements. The changeData function is called every 6 seconds. The first query I return I have 6 arrays. The second time i send a request, my push array(IsVacant1) is double and went to 12. after a while, I have over 500 arrays going into my .each statement.
How do I 'clear' this every time I make a request so that I am not adding arrays? Any help is most appreciated.
function changeData() {
isPaused = true;
var mydata0 = null;
$.post('php/ProductionChange.php', {
'WC': cc
}, function(data) { // This is Where I use an AJAX call into a php file.
mydata0 = data; // This takes the array from the call and puts it into a variable
var pa = JSON.parse(mydata0); // This parses the data into arrays and elements
var temp = {};
var bayData = '';
if (pa != null) {
for (var i = 0; i <= pa.length - 1; i++) {
var job = pa[i][0];
var shipdate = pa[i][1];
var status = pa[i][2];
var name = pa[i][3];
var EnclLoc = pa[i][13];
var Enclsize = pa[i][14];
var backpan = pa[i][15];
var percentCom = pa[i][16];
var IsVisible = pa[i][17];
var png = pa[i][18];
var WorkC = pa[i][20];
baydata = 'bayData' + i + '';
temp = {
job, shipdate, name, EnclLoc, Enclsize, backpan, percentCom, IsVisible, png, WorkC, status
};
isVacant1.push({
baydata: temp
});
}
} else {
ii = 1;
//alert("There are no more job numbers in this bay location. Thank you. ");
}
$.each(isVacant1, function(key, value) {
var job = value.baydata.job;
var ship = value.baydata.shipdate;
var name = value.baydata.name;
var encl = value.baydata.EnclLoc;
var EnclSize = value.baydata.EnclLoc;
var percentCom = value.baydata.percentCom;
var backpan = value.baydata.backpan;
var PngLogo = value.baydata.png;
var IsVisible = value.baydata.IsVisible;
var WorkC = value.baydata.WorkC;
var status = value.baydata.status;
var p = WorkC;
WorkC = (WorkC < 10) ? ("0" + WorkC) : WorkC;
//// remember if the encl location matches the workcell cell then do stuff based on that....... hint encl image not hiding becase of duplicate 17s
if (((encl == p) || (backpan == p)) && job != 123) {
$('#WC' + p).show();
document.getElementById("bayData" + p).innerHTML = name + ' ' + ship; // Work Cell Name and Ship Date
document.getElementById("bayData" + p + "a").innerHTML = job; // Work cell Job Number
document.getElementById("percentCom" + p).innerHTML = percentCom + '%'; // Work Cell Percent Complete
} else {
$('#WC' + p).hide();
From your question it looks like you want to clear the isVacant1 array.
In your ajax callback just put isVacant1 = []; as the first line. Like this
function(data) { // This is Where I use an AJAX call into a php file.
isVacant1 = [];
mydata0 = data; // This takes the array from the call and puts it into a variable
var pa = JSON.parse(mydata0); // This parses the data into arrays and elements
var temp = {};
var bayData = '';
..................
From your code it's not clear how you are declaring/initializing isVacant1 so i have suggested isVacant1 = [] otherwise you can also use isVacant1.length = 0.
You can also take a look here How do I empty an array in JavaScript?

Asynchronous execution of javascript code

I am studying javascript and json but I've some problems: I have a script that works with json but the performances of what I wrote aren't that good. The code works only if I do a debug step by step with firebug or other tools and that makes me think that the execution of the code (or a part of it ... the one that creates the table as you'll see) requires too much time so the browser stops it.
The code is:
var arrayCarte = [];
var arrayEntita = [];
var arraycardbyuser = [];
function displayArrayCards() {
var richiestaEntity = new XMLHttpRequest();
richiestaEntity.onreadystatechange = function() {
if(richiestaEntity.readyState == 4) {
var objectentityjson = {};
objectentityjson = JSON.parse(richiestaEntity.responseText);
arrayEntita = objectentityjson.cards;
}
}
richiestaEntity.open("GET", "danielericerca.json", true);
richiestaEntity.send(null);
for(i = 0; i < arrayEntita.length; i++) {
var vanityurla = arrayEntita[i].vanity_urls[0] + ".json";
var urlrichiesta = "http://m.airpim.com/public/vurl/";
var richiestaCards = new XMLHttpRequest();
richiestaCards.onreadystatechange = function() {
if(richiestaCards.readyState == 4) {
var objectcardjson = {};
objectcardjson = JSON.parse(richiestaCards.responseText);
for(j = 0; j < objectcardjson.cards.length; j++)
arrayCarte[j] = objectcardjson.cards[j].__guid__; //vettore che contiene i guid delle card
arraycardbyuser[i] = arrayCarte;
arrayCarte = [];
}
}
richiestaCards.open("GET", vanityurla, true);
richiestaCards.send(null);
}
var wrapper = document.getElementById('contenitoro');
wrapper.innerHTML = "";
var userTable = document.createElement('table');
for(u = 0; u < arrayEntita.length; u++) {
var userTr = document.createElement('tr');
var userTdcard = document.createElement('td');
var userTdinfo = document.createElement('td');
var br = document.createElement('br');
for(c = 0; c < arraycardbyuser[u].length; c++) {
var cardImg = document.createElement('img');
cardImg.src = "http://www.airpim.com/png/public/card/" + arraycardbyuser[u][c] + "?width=292";
cardImg.id = "immaginecard";
userTdcard.appendChild(br);
userTdcard.appendChild(cardImg);
}
var userdivNome = document.createElement('div');
userdivNome.id = "diverso";
userTdinfo.appendChild(userdivNome);
var userdivVanity = document.createElement('div');
userdivVanity.id = "diverso";
userTdinfo.appendChild(userdivVanity);
var nome = "Nome: ";
var vanityurl = "Vanity Url: ";
userdivNome.innerHTML = nome + arrayEntita[u].__title__;
userdivVanity.innerHTML = vanityurl + arrayEntita[u].vanity_urls[0];
userTr.appendChild(userTdcard);
userTr.appendChild(userTdinfo);
userTable.appendChild(userTr);
}
wrapper.appendChild(userTable);
}
The problem is that the code that should make the table doesn't wait for the complete execution of the code that works with the json files. How can I fix it? I would prefer,if possible, to solve that problem with something easy, without jquery and callbacks (I am a beginner).
You'll have to move som code around to make that work. at first, split it up in some functions, then it is easier to work with. I dont know if it works, but the idea is that first it loads the arrayEntita. When that is done, it fills the other 2 arrays. And when the last array has been filled, it builds the table.
var arrayCarte = [];
var arrayEntita = [];
var arraycardbyuser = [];
function displayArrayCards() {
var richiestaEntity = new XMLHttpRequest();
richiestaEntity.onreadystatechange = function () {
if (richiestaEntity.readyState == 4) {
var objectentityjson = {};
objectentityjson = JSON.parse(richiestaEntity.responseText);
arrayEntita = objectentityjson.cards;
BuildArrayEntita();
}
}
richiestaEntity.open("GET", "danielericerca.json", true);
richiestaEntity.send(null);
}
function BuildArrayEntita() {
for (i = 0; i < arrayEntita.length; i++) {
var vanityurla = arrayEntita[i].vanity_urls[0] + ".json";
var urlrichiesta = "http://m.airpim.com/public/vurl/";
var richiestaCards = new XMLHttpRequest();
richiestaCards.onreadystatechange = function () {
if (richiestaCards.readyState == 4) {
var objectcardjson = {};
objectcardjson = JSON.parse(richiestaCards.responseText);
for (j = 0; j < objectcardjson.cards.length; j++)
arrayCarte[j] = objectcardjson.cards[j].__guid__; //vettore che contiene i guid delle card
arraycardbyuser[i] = arrayCarte;
arrayCarte = [];
//If it is the last call to populate arraycardbyuser, build the table:
if (i + 1 == arrayEntita.length)
BuildTable();
}
}
richiestaCards.open("GET", vanityurla, true);
richiestaCards.send(null);
}
}
function BuildTable() {
var wrapper = document.getElementById('contenitoro');
wrapper.innerHTML = "";
var userTable = document.createElement('table');
for (u = 0; u < arrayEntita.length; u++) {
var userTr = document.createElement('tr');
var userTdcard = document.createElement('td');
var userTdinfo = document.createElement('td');
var br = document.createElement('br');
for (c = 0; c < arraycardbyuser[u].length; c++) {
var cardImg = document.createElement('img');
cardImg.src = "http://www.airpim.com/png/public/card/" + arraycardbyuser[u][c] + "?width=292";
cardImg.id = "immaginecard";
userTdcard.appendChild(br);
userTdcard.appendChild(cardImg);
}
var userdivNome = document.createElement('div');
userdivNome.id = "diverso";
userTdinfo.appendChild(userdivNome);
var userdivVanity = document.createElement('div');
userdivVanity.id = "diverso";
userTdinfo.appendChild(userdivVanity);
var nome = "Nome: ";
var vanityurl = "Vanity Url: ";
userdivNome.innerHTML = nome + arrayEntita[u].__title__;
userdivVanity.innerHTML = vanityurl + arrayEntita[u].vanity_urls[0];
userTr.appendChild(userTdcard);
userTr.appendChild(userTdinfo);
userTable.appendChild(userTr);
}
wrapper.appendChild(userTable);
}
i dont know if this check:
if (i + 1 == arrayEntita.length)
BuildTable();
but else you have to check if alle responseses have returned before executing buildtable();
AJAX requests are asynchronous. They arrive at an unknown period during execution and JavaScript does not wait for the server to reply before proceeding. There is synchronous XHR but it's not for ideal use. You'd lose the whole idea of AJAX if you do so.
What is usually done is to pass in a "callback" - a function that is executed sometime later, depending on when you want it executed. In your case, you want the table to be generated after you receive the data:
function getData(callback){
//AJAX setup
var richiestaEntity = new XMLHttpRequest();
//listen for readystatechange
richiestaEntity.onreadystatechange = function() {
//listen for state 4 and ok status (200)
if (richiestaEntity.readyState === 4 && richiestaEntity.status === 200) {
//execute callback when data is received passing it
//what "this" is in the callback function, as well as
//the returned data
callback.call(this,richiestaEntity.responseText);
}
}
richiestaEntity.open("GET", "danielericerca.json"); //third parameter defaults to true
richiestaEntity.send();
}
function displayArrayCards() {
//this function passed to getData will be executed
//when data arrives
getData(function(returnedData){
//put here what you want to execute when getData receives the data
//"returnedData" variable inside this function is the JSON returned
});
}
As soon as you have made the ajax call, put all of the rest of the code inside the readystatechange function. This way, it will execute everything in order.
Edit: #Dappergoat has explained it better than I can.

How do get param from a url

As seen below I'm trying to get #currentpage to pass client params
Can someone help out thanks.
$(document).ready(function() {
window.addEventListener("load", windowLoaded, false);
function windowLoaded() {
chrome.tabs.getSelected(null, function(tab) {
document.getElementById('currentpage').innerHTML = tab.url;
});
}
var url = $("currentpage");
// yes I relize this is the part not working.
var client = jQuery.param("currentpage");
var page = jQuery.param("currentpage");
var devurl = "http://#/?clientsNumber=" + client + "&pageName=" + page ;
});
This is a method to extract the params from a url
function getUrlParams(url) {
var paramMap = {};
var questionMark = url.indexOf('?');
if (questionMark == -1) {
return paramMap;
}
var parts = url.substring(questionMark + 1).split("&");
for (var i = 0; i < parts.length; i ++) {
var component = parts[i].split("=");
paramMap [decodeURIComponent(component[0])] = decodeURIComponent(component[1]);
}
return paramMap;
}
Here's how to use it in your code
var url = "?c=231171&p=home";
var params = getUrlParams(url);
var devurl = "http://site.com/?c=" + encodeURIComponent(params.c) + "&p=" + encodeURIComponent(params.p) + "&genphase2=true";
// devurl == "http://site.com/?c=231171&p=home&genphase2=true"
See it in action http://jsfiddle.net/mendesjuan/TCpsD/
Here's the code you posted with minimal changes to get it working, it also uses $.param as it's intended, that is to create a query string from a JS object, this works well since my suggested function returns an object from the url
$(document).ready(function() {
// This does not handle arrays because it's not part of the official specs
// PHP and some other server side languages support it but there's no official
// consensus
function getUrlParams(url) {
var paramMap = {};
var questionMark = url.indexOf('?');
if (questionMark == -1) {
return paramMap;
}
var parts = url.substring(questionMark + 1).split("&");
for (var i = 0; i < parts.length; i ++) {
var component = parts[i].split("=");
paramMap [decodeURIComponent(component[0])] = decodeURIComponent(component[1]);
}
return paramMap;
}
// no need for the extra load listener here, jquery.ready already puts
// your code in the onload
chrome.tabs.getSelected(null, function(tab) {
document.getElementById('currentpage').innerHTML = tab.url;
});
var url = $("currentpage");
var paramMap = getUrlParams(url);
// Add the genphase parameter to the param map
paramMap.genphase2 = true;
// Use jQuery.param to create the url to click on
var devurl = "http://site.com/?"+ jQuery.param(paramMap);
$('#mydev').click( function(){
window.open(devurl);
});
});

Categories

Resources