PDA

View Full Version : form element array problems



Ultragames
Mar 27th, 2007, 10:55 PM
I'm not sure what the right name for this is, but here is what I have.

I have multiple select menus all with the same name, followed by [].

I cannot for the life of my figure out how to dynamicly find the value of each select menu with javascript. When I submit the form i get a nice array in the POST and I can deal with it in PHP just fine, but i cannot find a way to do this in Javascript. I simply need a way to find the value of all of the select menus in the array.

Thank you.

Bill Posters
Mar 27th, 2007, 11:16 PM
e.g.

var selectEls = document.getElementsByName('sel[]');
var selectArray = new Array();

for (var i=0, selectEl; selectEl= selectEls[i]; i++) {
selectArray.push(selectEl.value);
}

return selectArray;

Ultragames
Mar 27th, 2007, 11:17 PM
Unfortunatly, doing that only returns a length of 1, no matter how many elements I have with the same name followed by the []s. Any ideas?

david_kw
Mar 27th, 2007, 11:23 PM
If I read this right you are saying that you have

<select name="selname[]" ... ?

While this might work

var sel = document.getElementsByName("selname[]");

it will not work like this

var sel document.formname.selname[];

because the [] has a special purpose in javascript (arrays). The long and short is you are better off not using [] in a name attribute.

david_kw

Mr J
Mar 27th, 2007, 11:25 PM
Give this a try

function test(){
sel=document.getElementsByTagName("SELECT")

for(var i=0;i<sel.length;i++){
alert(sel[i].options[sel[i].selectedIndex].value)

}

}

liorean
Mar 28th, 2007, 01:59 AM
I'm not sure what the right name for this is, but here is what I have.

I have multiple select menus all with the same name, followed by [].Which is an error on your part. Select elements are self contained form controls and their name attribute must be unique within the form. The way browsers handle multiple select elements with the same name is undefined, meaning they can do whatever they want because the error is yours and not theirs.
I cannot for the life of my figure out how to dynamicly find the value of each select menu with javascript. When I submit the form i get a nice array in the POST and I can deal with it in PHP just fine, but i cannot find a way to do this in Javascript. I simply need a way to find the value of all of the select menus in the array.Give them unique names. Radio buttons and checkboxes may have non-unique names (they are treated as a single multivalue control), but none of the other form controls.

Ultragames
Mar 28th, 2007, 02:01 AM
Actually it's not an error. It's just a style of organizing the information. You can make any form element be part of an array, rather than a single value by adding [] to it.

Mr J's method of accessing the values is not my favorite way to access the information, but it did work, and I no longer need help. Thank you all for your assistance.

liorean
Mar 28th, 2007, 02:22 AM
Actually it's not an error. It's just a style of organizing the information. You can make any form element be part of an array, rather than a single value by adding [] to it.Nope, you're wrong on that. PHP may treat it like that, but it relies on browsers behaving in a certain way that is undefined and in other words not at all guaranteed. That it's becoming quite common on the web doesn't make it not be an error.

Only radio buttons and checkboxes may have non-unique names within the form, as per the HTML4.01 specification. A browser wouldn't be wrong if it decided to only submit the value of the first, or the last, control with a non-unique name. Or for that matter refusing to submit controls with non-unique names. It's an author error, plain and simple.

(As an aside, I can mention that the select element is extra problematic as there is already a multivalue form of it. With text controls treating non-unique names as a multivalue control is unambiguous, but that is not the case for select elements.)

Ultragames
Mar 28th, 2007, 03:12 AM
Then what would be the correct way to have multiple select menus submit in a way that PHP or other server side codes receive them as an array?

Note: My select menus do not have the multiple property turned on.

Bill Posters
Mar 28th, 2007, 08:59 AM
e.g.

var selectEls = document.getElementsByName('sel[]');
var selectArray = new Array();

for (var i=0, selectEl; selectEl= selectEls[i]; i++) {
selectArray.push(selectEl.value);
}

return selectArray;


Unfortunatly, doing that only returns a length of 1, no matter how many elements I have with the same name followed by the []s. Any ideas?

Fwiw, it worked perfectly well in FF/Mac, Op9/Mac and Safari, reflecting the correct number of values in the array (i.e. array length).

The use of getElementsByName and the push() method is likely to limit the function to use with v5+ browser, possibly v6+ in the case of IE.

I'd be interested to know how it performs in other Win-based browsers, but I would have expected it to work in IE6+, FF and Opera.
Fwiw, IE5/Mac choked on the push method, as expected.

The question of support can be dealt with simply by testing in the supported browsers. How it behaves outside of that, is largely irrelevant, particularly given that it relies on methods which are generally only supported by more recent browsers in the first place.

Kor
Mar 28th, 2007, 10:10 AM
The use of getElementsByName and the push() method is likely to limit the function to use with v5+ browser, possibly v6+ in the case of IE.

Don't confound arrays with collections. A collection of HTML elements does not accept all the array's methods, push() is one of them.


Fwiw, IE5/Mac choked on the push method, as expected.

You may use JSON to populate an array. Anyway, if the elements are multiple list boxes, you should also to circle through the options to check which is selected, thus to set an array of arrays. At least this looks safer for me.
This code works OK in IE6 and FF2 /Win:


<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>Untitled Document</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<meta http-equiv="Content-Style-Type" content="text/css">
<meta http-equiv="Content-Script-Type" content="text/javascript">
<script type="text/javascript">
function buildArr(){
var selectEls = document.getElementsByName('sel[]');
var selectArray = [];
for(var i=0; i<selectEls.length;i++){
selectArray[i]=[];
var selectOpt=selectEls[i].getElementsByTagName('option');
for(var j=0;j<selectOpt.length;j++){
if(selectOpt[j].selected){
selectArray[i][selectArray[i].length]=selectOpt[j].value;
}
}
}
writeArr(selectArray)
}
function writeArr(arr){
var span=document.getElementById('mydiv').getElementsByTagName('span');
for(var i=0; i<span.length;i++){
var txt=arr[i].length==0?'none':arr[i].toString();
span[i].firstChild.nodeValue=txt;
}
}
</script>
</head>
<body>
<form>
<select name="sel[]" size="3" multiple="multiple">
<option value="1">one</option>
<option value="2">two</option>
<option value="3">three</option>
</select>
<select name="sel[]" size="3" multiple="multiple">
<option value="1">one</option>
<option value="2">two</option>
<option value="3">three</option>
</select>
<select name="sel[]" size="3" multiple="multiple">
<option value="1">one</option>
<option value="2">two</option>
<option value="3">three</option>
</select>
<input type="button" value="Show the selected values" onclick="buildArr()">
</form>
<br>
<br>
<div id="mydiv">
<div>List box 0 selected values: <span>&nbsp;</span></div>
<div>List box 1 selected values: <span>&nbsp;</span></div>
<div>List box 2 selected values: <span>&nbsp;</span></div>
</div>
</body>
</html>

Ultragames
Mar 28th, 2007, 10:11 AM
I've heard JSON a lot when reading things about AJAX and XML, but nothing really says what is it.

Kor
Mar 28th, 2007, 10:17 AM
www.json.org

Kor
Mar 28th, 2007, 10:25 AM
Well, that is not necessarily JSON. It is rather just a simple method to populate an array using as index it's own length, in order to avoid the push() method.


var selectEls = document.getElementsByName('sel[]');
var selectArray = [];
for(var i=0; i<selectEls.length;i++){
selectArray[i]=[];
var selectOpt=selectEls[i].getElementsByTagName('option');
for(var j=0;j<selectOpt.length;j++){
if(selectOpt[j].selected){
selectArray[i][selectArray[i].length]=selectOpt[j].value;
}
}
}

Bill Posters
Mar 28th, 2007, 12:03 PM
Originally Posted by Kor

Originally Posted by Bill Posters
The use of getElementsByName and the push() method is likely to limit the function to use with v5+ browser, possibly v6+ in the case of IE.
Don't confound arrays with collections. A collection of HTML elements does not accept all the array's methods, push() is one of them.
I didn't confuse the two. I wasn't suggesting that getElementsByName and the push() method were being used together directly. I simply listed them both as potential backwards support issues appearing in the method which I originally posted.
(Tbh, I thought that would have been clear from how I'd used them both in the script which I posted.)


Re: replacing arrayObj.push(selectEl.value) with selectArray[i] = selectEl.value;

Good call. I don't understand why I missed such an obvious alternative in the first place.
IE5/Mac is more than happy to work with this approach. (It already supports getElementsByName.)

liorean
Mar 28th, 2007, 12:58 PM
Then what would be the correct way to have multiple select menus submit in a way that PHP or other server side codes receive them as an array?The correct way is to give them unique names. Now, controls with unique names won't work as an array in most server side languages, but PHP is quirky here. So, try giving them unique names according to the form "arrayname" where index is a number. I believe PHP will treat them as an array with that change while they will still have unique names according to HTML.

Note: My select menus do not have the [I]multiple property turned on.I gathered as much.