...

View Full Version : Resolved Issue passing array through function



wldrumstcs
07-15-2009, 05:35 AM
I have created an array composed of textfield values, but it isn't passing at all. Here is my code:



// the _____.value strings below are all set correctly. I know it is because if I put an alert() after defining all of stringArr's values, it outputs properly
var stringArr = new Array(5);
stringArr[0] = i;
stringArr[1] = editRestaurant.value;
stringArr[2] = editFood.value;
stringArr[3] = editissensitive.value;
stringArr[4] = editNotes.value;
editSubmit.setAttribute("onclick", "submitform("+stringArr+")");

function submitform(stringArr)
{
alert(stringArr[0] + "," + stringArr[1] + "," + stringArr[2] + "," + stringArr[3] + "," + stringArr[4]);
}


I am not sure if this might have to do with the fact that arrays are passed by ref, not value. Even still, I have tried using slice() to send it by value, and the alert() in the function is still never called. I have also wondered if the quotation marks weren't right, but I have tried a million different combinations, and nothing works. An ideas??

ckeyrouz
07-15-2009, 05:43 AM
Why don't you try to attach event like this:

editSubmit.attachEvent("onclick", "submitform("+stringArr+")");

besides if you want you can pass the array as a string variable using the method join(",")

var arrStr = stringArr.join(",");

wldrumstcs
07-15-2009, 05:48 AM
I tried both solutions, but still no luck :confused:

Kor
07-15-2009, 10:32 AM
Attaching an event is a tricky mission, as there are two models : Moz and IE. Fortunately there are a couple of crossbrowser workarounds. One of them, in case you need to create an event, is the old DOM 0 classical model, an anonymous function and a closure:


...
editSubmit.arr=stringArr; // creates a custom property for the object
editSubmit.onclick=function(){submitform(this.arr)}
...

Shannon Blonk
07-15-2009, 02:07 PM
When you add an array to a string, like in
"submitform("+stringArr+")"it will quietly call the array's toString method. By default thats .join(",") Test that by changing to
stringArr[4] = editNotes.value;
alert("submitform("+stringArr+")");
editSubmit.setAttribute("onclick", "submitform("+stringArr+")");
alert(editSubmit.onclick);
If you're happy with the joined string, just put quotes around it and use it as single piece in your function
"submitform('"+stringArr+"')"

function submitform(str){
alert(str)
}If you want the whole array as an array, Kor's suggestion is good (even though that's not a closure -- no variables are bound to the scope the anon function was created in).

Kor
07-15-2009, 02:37 PM
Shannon Blonk

setAttributte() method simply woun't work for IE. IE does not consider the events as attributes, thus you have to chose between a crossbrowser simple way to create an event (see my post above) like:


...
editSubmit.arr=stringArr; // creates a custom property for the object
editSubmit.onclick=function(){submitform(this.arr)}
...


or a workaround to create and/or add functions to an already existent event:


function AttachEvent(obj,evt,fnc,useCapture){
if (!useCapture) useCapture=false;
if (obj.addEventListener){
obj.addEventListener(evt,fnc,useCapture);
return true;
} else if (obj.attachEvent) return obj.attachEvent("on"+evt,fnc);
else{
MyAttachEvent(obj,evt,fnc);
obj['on'+evt]=function(){ MyFireEvent(obj,evt) };
}
}
function MyAttachEvent(obj,evt,fnc){
if (!obj.myEvents) obj.myEvents={};
if (!obj.myEvents[evt]) obj.myEvents[evt]=[];
var evts = obj.myEvents[evt];
evts[evts.length]=fnc;
}

function MyFireEvent(obj,evt){
if (!obj || !obj.myEvents || !obj.myEvents[evt]) return;
var evts = obj.myEvents[evt];
for (var i=0,len=evts.length;i<len;i++) evts();
}

and to call the first function, an example for onclick:


AttachEvent([I]element,'click',function(){somefunction(someargument)},false);

Kor
07-15-2009, 02:40 PM
Kor's suggestion is good (even though that's not a closure -- no variables are bound to the scope the anon function was created in).
It is a closure. :) Because of the self reference this:

editSubmit.onclick=function(){submitform(this.arr)}

Now this is not anymore the "parent" function itself, but the element itself.

Shannon Blonk
07-15-2009, 03:38 PM
is not anymore the "parent" function itself, but the element itself.

Exactly. this is local to the anon wrapper function.

A closure has variable bound to the scope of it creation. If you'd written

editSubmit.onclick=function(){submitform(editSubmit.arr)}

then editSubmit in the anon function would be bound to editSubmit in the parent scope and you would have a closure.

Anonymous [wrapper] function != closure

P.S. Nobody uses IE anymore :)

Kor
07-15-2009, 03:55 PM
Exactly. this is local to the anon wrapper function.

A closure has variable bound to the scope of it creation. If you'd written

editSubmit.onclick=function(){submitform(editSubmit.arr)}

then editSubmit in the anon function would be bound to editSubmit in the parent scope and you would have a closure.

Anonymous [wrapper] function != closure

P.S. Nobody uses IE anymore :)
1. Read more about closures, it looks like you are a little bit confused about the term:

http://www.jibbering.com/faq/faq_notes/closures.html

2. IE still has about 65% of the browsers' market.

http://marketshare.hitslink.com/report.aspx?qprid=0&qpdt=1&qpct=0&qpcal=1&qptimeframe=M&qpsp=124

Than means, for you, 65% of the users are nobody :rolleyes:

Let's make things clear: I don't love IE, I don't love FF, I don't love any particular browser. For myself as an ordinary user, I use FF. I consider it the best for the moment. But as a web designer and client-side programmer I have to code according to the whole market. As a professional, I code for all the people, not for myself. You should do the same.

wldrumstcs
07-15-2009, 04:05 PM
Thanks guys. Shannon - your solution worked. However, I am having a bit of an issue. The _____.value are being sent as the initial values and not the current values. How do I grab the current values for the onClick() event if the textfields are being created on the fly? Here is my entire code:



<script type="text/javascript">

function change(i) {
// create textboxes
var editRestaurant = document.createElement("input");
var editFood = document.createElement("input");
var editissensitive = document.createElement("input");
var editNotes = document.createElement("input");
var editSubmit = document.createElement("input");

// disable edit button
document.getElementById('Edit'+i).disabled = true;

//Assign different attributes to the element.
editRestaurant.setAttribute("type", "text");
editRestaurant.setAttribute("value", document.getElementById('restaurantNode'+i).firstChild.nodeValue);
editRestaurant.setAttribute("name", "editrestaurant");

editFood.setAttribute("type", "text");
editFood.setAttribute("value", document.getElementById('foodNode'+i).firstChild.nodeValue);
editFood.setAttribute("name", "editfood");

editissensitive.setAttribute("type", "text");
editissensitive.setAttribute("value", document.getElementById('sensitiveNode'+i).firstChild.nodeValue);
editissensitive.setAttribute("name", "editissensitive");

editNotes.setAttribute("type", "text");
// check to see if notes is empty
if (document.getElementById("notesNode"+i).firstChild == null)
editNotes.setAttribute("value", "");
else
editNotes.setAttribute("value", document.getElementById('notesNode'+i).firstChild.nodeValue);
editNotes.setAttribute("name", "editnotes");

editSubmit.setAttribute("type", "button");
editSubmit.setAttribute("value", "Save");
editSubmit.setAttribute("name", "editSubmit");

// create onclick command for button
var stringArr = new Array(5);
stringArr[0] = i;
stringArr[1] = editRestaurant.value;
stringArr[2] = editFood.value;
stringArr[3] = editissensitive.value;
stringArr[4] = editNotes.value;

editSubmit.setAttribute("onclick", "submitform('"+stringArr+"')");

// make text disappear
document.getElementById('restaurantNode'+i).style.display = 'none';
document.getElementById('foodNode'+i).style.display = 'none';
document.getElementById('sensitiveNode'+i).style.display = 'none';
document.getElementById('notesNode'+i).style.display = 'none';
document.getElementById('xNode'+i).style.display = 'none';

document.getElementById('restauranttextbox'+i).appendChild(editRestaurant);
document.getElementById('foodtextbox'+i).appendChild(editFood);
document.getElementById('sensitivetextbox'+i).appendChild(editissensitive);
document.getElementById('notestextbox'+i).appendChild(editNotes);
document.getElementById('deletetextbox'+i).appendChild(editSubmit);


}

function submitform(stringArr)
{
alert(stringArr);
}

Kor
07-15-2009, 04:23 PM
wldrumstcs

I have tried by best to drive to to a simple, nice and cross-browser solution. You see, this huge Web doesn't belong to me, nor to you, nor to Shannon Blonk. It belongs to us: people all over the world. When you create a site and you post it, you make a public act. And if it is public, you should care about the public. I guess you have something to say to the World, haven't you? Now, if you have that something to say, wouldn't be a pity to hide your something by making it almost invisible? Don't you care about your, let's say, rating?

Once again: what will cost you to try my small crossbrowser piece of code?

You have to find out that your form will not be submitted under the IE browsers, as you must create the name attribute otherwise.

Believe me, javascript is not a simple language. I am quite old within this field. Unfortunately, maybe, but you must care about the main browsers particularities.

wldrumstcs
07-15-2009, 04:36 PM
Kor - I do understand where you are coming from. I will care about cross-compatibility in the future. However, I am creating this site to help myself keep track of which foods set off reactions with my Colitis. I will make this public, but as for right now, I'm just trying to get the thing to work.

wldrumstcs
07-15-2009, 04:41 PM
Fixed my issue. I am an idiot. Kor - thanks for your help. Don't worry - an IE compatible version of my site will soon be coming to a city near you ;)



EZ Archive Ads Plugin for vBulletin Copyright 2006 Computer Help Forum