I'm studying JavaScript and I've some problems with the recall of functions...
These are my two functions:
the first:
function geisson() {
var iabile = new XMLHttpRequest();
iabile.onreadystatechange = function () {
if (iabile.readyState == 4) {
var objectjson = {};
var arrayCards = []; //creazione dell'array che conterrà le cards
objectson = JSON.parse(iabile.responseText);
arrayCards = objectson.cards;
var Ettore = []; //Vèttore di cards
//the results
for (i = 0; i < arrayCards.length; i++)
document.getElementById('image').src = "http://www.mysite.com/png/public/card/" + arrayCards[i].__guid__ + "?width=292";
}
}
iabile.open("GET", "gnekcard.json", true);
iabile.send(null);
}
and the second function:
function Entity() {
var iabile = new XMLHttpRequest();
iabile.onreadystatechange = function () {
if (iabile.readyState == 4) {
var objectjson = {};
var arrayCards = []; //creazione dell'array che conterrà le cards
objectson = JSON.parse(iabile.responseText);
arrayCards = objectson.cards;
//the results
for (i = 0; i < arrayCards.length; i++)
document.getElementById('informazioni').innerHTML += "\r\n" + "Nome : " + arrayCards[i].__title__ + "\r\n" + "Vanity url: " + arrayCards[i].vanity_urls[0] + "\r\n";
}
}
iabile.open("GET", "gnek.json", true);
iabile.send(null);
}
I would like to have a third function that prints the results of the other 2 functions. I'd prefer to have the "for" in only in the third function and recall the vectors of the others methods but they aren't global. I don't want to have global variables (if possible) so how can I do it?
In the geisson function you can do this:
geisson.arrayCards = arrayCards;
and you can do the same in the Entity function
Entity.arrayCards = arrayCards;
Then you can create a third function that can access the arrayCards of each function.
function displayArrayCards {
var geissonCards = geisson.arrayCards;
var EntityCards = Entity.arrayCards;
var i;
for(i = 0; i < geissonCards.length; i++) {
document.getElementById('image').src = "http://www.mysite.com/png/public/card/" + geissonCards[i].__guid__ + "?width=292";
}
for(i = 0; i < EntityCards.length; i++) {
document.getElementById('informazioni').innerHTML += "\r\n" + "Nome : " + EntityCards[i].__title__ + "\r\n" + "Vanity url: " + EntityCards [i].vanity_urls[0] + "\r\n";
}
}
Do what you should always do when you work with Ajax calls: Use callbacks.
For example:
function geisson(callback) {
var iabile = new XMLHttpRequest();
iabile.onreadystatechange = function () {
if (iabile.readyState == 4) {
// ...
callback(objectson.cards);
}
}
iabile.open("GET", "gnekcard.json", true);
iabile.send(null);
}
and in your third function:
function someName() {
geisson(function(data) {
for (var i = 0; i < data.length; i++) {
//... do something with data ...
}
});
// call Entity the same way here...
}
Btw, in your first function, you always override the src property of the same element (document.getElementById('image')). It does not make sense to iterate over the whole array here, sine eventually, src will have the value related to the last element. Either assign the values to multiple elements or just get the last element in the array.
Related
I have this code and i can add or edit the object if exists, but the "for" finish before the function onsuccess is called, then the index "for" is bad.
How to pass the index onSuccess?
Help!!!
var active = dataBase.result;
var data = "";
var object = "";
var index = null;
var request;
$(".layers").promise().done(function () {
var elements = document.getElementsByClassName('layers');
for (var i = 0; typeof (elements[i]) != 'undefined'; i++) {
if (elements[i].getAttribute("src").split("/")[4] !== "alpha.png") {
data = active.transaction([elements[i].getAttribute("src").split("/")[3]], "readwrite");
object = data.objectStore(elements[i].getAttribute("src").split("/")[3]);
index = object.index("by_Name");
request = index.get(String(elements[i].getAttribute("src").split("/")[4] + "/" + elements[i].getAttribute("src").split("/")[6]));
request.onsuccess = function (e) {
var result = e.target.result;
if (result === undefined) {
var resultPut = object.put({
Name: String(elements[i].getAttribute("src").split("/")[4] + "/" + elements[i].getAttribute("src").split("/")[6]),
Count: 1,
Type: String(elements[i].getAttribute("src").split("/")[4])
});
resultPut.onerror = function (e) {
alert(resultPut.error.name + '\n\n' + resultPut.error.message);
};
} else {
result.Count++;
var requestUpdate = object.put(result);
requestUpdate.onerror = function (event) {
alert(requestUpdate.error.name + '\n\n' + requestUpdate.error.message);
};
}
}(event);
}
}
alert("Finish");
})
The thing is that, by the time the for has ended, the transactions with the object store are not. What you could try is to encapsulate the index like this:
for(var i = 0; i < elements.length; i++) {
(function(myElement) {
if (myElement.getAttribute("src").split("/")[4] !== "alpha.png") {
...
}
})(elements[i]);
}
I have a problem with an object dict. When json datas are received, program calls LoadDict() function, where dict object gets filled with new data from server. I used FireBug to make sure that dict has all new elements with correct information, but when function is finished, dict gets empty again like it was before ajax request. This code executes in the global scope:
var dict = new Dictionary();
function LoadDict(words) {
for (var i in words) {
var word = new Word();
word.word = words[i].Word;
word.transcript = words[i].Transcript;
word.frequency = words[i].Frequency;
word.meanings = words[i].Meanings;
word.examples = words[i].Examples;
word.imgLinks = words[i].ImgLinks;
dict.Add(word);
}
}
$.getJSON("getall").done(LoadDict);
dict.PrintDictionary);
And this is some code of my Dictionary class
function Dictionary() {
this.collection = new Array();
this.count = 0;
this.sorted = false;
}
Dictionary.prototype.Add = function(word) {
if (word instanceof Word) {
word.id = this.count;
this.collection[this.count] = word;
this.count++;
this.sorted = false;
}
}
Dictionary.prototype.PrintDictionary = function() {
function WordToString(word) {
var line = "<strong>" + word.word + "</strong> [" + word.transcript + "] - " + word.meanings[0];
for (var j = 1; j < word.meanings.length; j++) {
line += ", " + word.meanings[j];
}
return line;
}
var result = "<ol>"
for (var i = 0; i < this.collection.length; i++)
result += "<li>" + WordToString(this.collection[i]) + "</li>";
result += "</ol>"
document.write(result);
}
Declaration of Dictionary class goes before creating dict object.
Help, please!
A timing problem.
In your code, PrintDictionary function have excuted before ajax call is complete.
The problem is that the $.getJSON is async.
This means that the dict.PrintDictionary(); line gets executed before the result is returned from the getJSON call
Im wondering in the following code, how could I set the callback property "value" to null?
The code takes a bunch of ids (31, 32 ,33) and then uses a callback function to monitor changes to values of these ids. When I run the code again using the same IDs, is there a way to set the callback property to null?
obsids = new Array();
function list() {
if (arguments.length) {
leng = arguments.length;
for (i = 0; i < leng; i++) {
obsids[i] = new LiveAPI(callback, "id "+arguments[i]);
obsids[i].property = "value";
}
}
function callback(args) {
outlet(0, args[0] + " " + args[1] + " " + this.id);
}
}
You will need a specific callback for each obsids[i], and you need to create them in a closure for not loosing i.
function list() {
var obsids = [];
for (var i=0, len = arguments.length; i < len; i++)
obsids[i] = createApi("id "+arguments[i]);
function createApi(id) {
var obsid = new LiveAPI(function callback(args) {
obsid.property = null;
outlet(0, args[0] + " " + args[1] + " " + this.id);
}, id);
obsid.property = "value";
return obsid;
}
return obsids;
}
i have a file banners.js
function addEvent(object, evName, fnName, cap) {
if (object.attachEvent)
object.attachEvent("on" + evName, fnName);
else if (object.addEventListener)
object.addEventListener(evName, fnName, cap);
}
var nextAd;
function makeBannerAds() {
var bannerBox = document.createElement("div");
bannerBox.id = "bannerBox";
document.body.appendChild(bannerBox);
for (var i=0; i<adsURL.length; i++) {
var bannerAd = document.createElement("div");
bannerAd.className = "bannerAd";
bannerAd.style.zIndex = i;
var urlLink = document.createElement("a");
urlLink.href = adsURL[i];
var bannerIndex = document.createElement("img");
bannerIndex.src = "banner" + i +".jpg";
bannerIndex.style.width="290px";
bannerIndex.style.height="55px";
bannerBox.appendChild(bannerAd);
}
bannerBox.appendChild(bannerAd);
setInterval("changeBannerAd()", 10000);
}
function changeBannerAd() {
var allAds = document.getElementById("bannerBox").childNodes;
alert('work');
for(var i=0; i<num; i++) {
if(allAds.style.zIndex == 0) {
allAds.style.top = "-50px";
nextAd = allAds;
}
}
for(var i=0; i<num; i++) {
allAds.style.zIndex--;
if(allAds.style.zIndex < 0)
allAds.style.zIndex = num-1;
}
var timeDelay = 0;
for(var i=-50; i<=0; i++) {
setTimeout("moveNextAd(" + i + ")", timeDelay);
timeDelay += 15;
}
}
function moveNextAd(top) {
nextAd.style.top = top + ".px"
}
addEvent(window, "load", makeBannerAds(), false);
the second file
ads.js
var adsURL = new Array();
//this stores each item in the array using a index place holder
adsURL[0] = "testpage0.htm";
adsURL[1] = "testpage1.htm";
adsURL[2] = "testpage2.htm";
adsURL[3] = "testpage3.htm";
adsURL[4] = "testpage4.htm";
adsURL[5] = "testpage5.htm";
adsURL[6] = "testpage6.htm";
adsURL[7] = "testpage7.htm";
adsURL[8] = "testpage8.htm";
adsURL[9] = "testpage9.htm";
adsURL[10] = "testpage10.htm";
adsURL[11] = "testpage11.htm";
//and an html file where these are included.
javascript is not showing any error and also all the statements are running but the images are not visible on the page. i couldnot figure the problem. working from last 2 days.
New answer:
Some of your code had to be revised I think. I just edited this off of what I thought it was supposed to look like.
Check the new jsFiddle
I think it might be getting you closer.
Briefly, the issue was that childNodes() returns an array of elements, so you need to reference that variable as you would an array
Secondly, you didn't have all the appends that were required.
var adsURL = new Array();
adsURL[0] = "testpage0.htm";
...
adsURL[11] = "testpage11.htm";
var nextAd;
var moveNextAd = function (top) {
nextAd.style.top = top + ".px"
}; //changed this to function as variable, answer explained below
var changeBannerAd = function () {
var num = adsURL.length
var allAds = document.getElementById("bannerBox")
allAds = allAds.childNodes;
//^^^ here is what was wrong
// Child nodes returns an array of elements
// So for allAds, you should reference it with allAds[i]
for (var i = 0; i < num; i++) {
if (allAds[i].style.zIndex == 0) {
allAds[i].style.top = "-50px";
nextAd = allAds[i++];
}
}
for (var i = 0; i < num; i++) {
allAds[i].style.zIndex--;
if (allAds[i].style.zIndex < 0) allAds[i].style.zIndex = num - 1;
}
var timeDelay = 0;
for (var i = -50; i <= 0; i++) {
setTimeout((function () {
moveNextAd(" + i + ");
}()), timeDelay);
timeDelay += 15;
}
}; //changed this to function as variable too.
function addEvent(object, evName, fnName, cap) {
if (object.attachEvent) object.attachEvent("on" + evName, fnName);
else if (object.addEventListener) object.addEventListener(evName, fnName, cap);
}
function makeBannerAds() {
var bannerBox = document.createElement("div");
bannerBox.id = "bannerBox";
document.body.appendChild(bannerBox);
for (var i = 0; i < adsURL.length; i++) {
var bannerAd = document.createElement("div");
bannerAd.className = "bannerAd";
bannerAd.style.zIndex = i;
bannerAd.style.position = "absolute";
var urlLink = document.createElement("a");
urlLink.href = adsURL[i];
var bannerIndex = document.createElement("img");
bannerIndex.src = "banner" + i + ".jpg";
bannerIndex.style.width = "290px";
bannerIndex.style.height = "55px";
urlLink.appendChild(bannerIndex); //Here is the other problem
bannerAd.appendChild(urlLink); //All these weren't appended
bannerBox.appendChild(bannerAd); // to each other
}
setInterval((function () {
changeBannerAd();
}()), 10000);
}
addEvent(window, "load", makeBannerAds(), false);
Secondly, not to be picky or anything but you should probably declare the functions you pass into setInterval or setTimeout as variables rather than explicit functions or run them through an anonymous function like I have done. These two functions use a form of eval, and as we all know eval is evil, eval is evil, and eval is evil
Old answer; ignore
Question: Is your ads.js added before or after banners.js
Try adding the script tag before banners.js
I just placed the ads.js content above the banners.js script in a jsFiddle and it worked just fine for me
Check the JS Fiddle for full code at the top.
I meet a trouble with a function. actually I need to make this function to perform a calculation on some text fields. When I worked on a single line no problems. But recently, someone asked to make a table with multiple lines (one line can be added dynamically) so, I do the following function so that it can not only duplicate line but id change all the fields concerned, so I add class to these fields. therefore I proceed as follows:
function clone(line) {
newLine = line.cloneNode(true);
line.parentNode.appendChild(newLine);
var tab = document.getElementsByClassName('libelle_debours')
var i = -1;
while (tab[++i]) {
tab[i].setAttribute("id", "_" + i);
};
var cab = document.getElementsByClassName('ht_no_tva')
var j = -1;
while (cab[++j]) {
cab[j].setAttribute("id", "_" + j);
};
var dab = document.getElementsByClassName('ht_tva')
var k = -1;
while (dab[++k]) {
dab[k].setAttribute("id", "_" + k);
};
var eab = document.getElementsByClassName('taux')
var l = -1;
while (eab[++l]) {
eab[l].setAttribute("id", "_" + l);
};
var fab = document.getElementsByClassName('tva')
var m = -1;
while (fab[++m]) {
fab[m].setAttribute("id", "_" + m);
};
}
function delRow() {
var current = window.event.srcElement;
//here we will delete the line
while ((current = current.parentElement) && current.tagName != "TR");
current.parentElement.removeChild(current);
}
The problem in fact is the second function that is used to make the calculation:
function calcdebours() {
var taux = document.getElementById('debours_taux_tva').value;
var ht_no_tva = document.getElementById('debours_montant_ht_no_tva').value;
var ht_tva = document.getElementById('debours_montant_ht_tva').value;
var tva = Math.round((((ht_tva) * (taux)) / 100) * 100) / 100;;
if (taux == '') {
taux = 0;
}
if (ht_no_tva == '') {
ht_no_tva = 0;
}
if (ht_tva == '') {
ht_tva = 0;
}
document.getElementById('debours_montant_tva').value = tva;
document.getElementById('debours_montant_ttc').value = (tva) + parseFloat(ht_tva) + parseFloat(ht_no_tva)
}
function
montant_debours() {
var ttc = document.getElementById('debours_montant_ttc').value;
var ttc2 = document.getElementById('debours_montant_ttc2').value;
if (ttc == '') {
var ttc = 0;
} else {
var ttc = document.getElementById('debours_montant_ttc').value;
}
if (ttc2 == '') {
var ttc2 = 0;
} else {
var ttc2 = document.getElementById('debours_montant_ttc2').value;
}
tx = parseFloat(ttc) + parseFloat(ttc2);
document.getElementById('ttc_cheque').value = Math.round(tx * 100) / 100;
}
As Id are not the same, do I have to create as many functions
there are lines?
Is it possible to fit a single function to process each line?
If so can you tell me how?
If I'm not mistaken you can use for loop and append increment to the end of element's id. Like this:
trs = document.getElementById('container Id').getElementsByTagName('tr');
For (var i = 1, i <= trs.length; i++)
{
var el = document.getElementById('debours_montant_ttc' + i);
}