SitePoint Sponsor

User Tag List

Results 1 to 10 of 10
  1. #1
    SitePoint Wizard TheRedDevil's Avatar
    Join Date
    Sep 2004
    Location
    Norway
    Posts
    1,190
    Mentioned
    3 Post(s)
    Tagged
    0 Thread(s)

    Problem using getElementsByName on 2 dimensional array in IE

    How can I fetch a part of the array in IE?

    The code works as expected in Opera and Firefox, but IE returns an error saying that matchPaid does not contain a value.

    As it seems IE does not pull any of the input fields belonging in the array.

    I believe the issue lies in this line:
    var matchPaid = document.getElementsByName("plan_bonus_amount["+key+"][]");

    The rest of the function:
    Code JavaScript:
    function updateMatchPowerline(total, newPlan) {
    	var totalPlan = parseInt(document.getElementById("total_plans").value);
    	var totalMatch = document.getElementById("total_match");
     
    	if (newPlan === true) totalPlans = totalPlan + 1;
    	else totalPlans = totalPlan;
     
    	var matchValue = 0;
     
    	for (var key=0;key < totalPlans;key++) {
    		var div = document.getElementById("match_table_"+key);
    		var newTbody = document.createElement("tbody");	
     
    		var match = new Array();
     
    		if (key < totalPlan && parseInt(totalMatch.value) > 0) {
    			/*Fetch the current values, then clear the table*/
    			var matchPaid = document.getElementsByName("plan_bonus_amount["+key+"][]");
     
    			for (var nr=0;nr < parseInt(totalMatch.value);nr++) {
    				match[nr] = parseFloat(matchPaid[nr].value);
    			} 
     
    			remove(div);
    		}
     
    		for (var nr=0;nr < total;nr++) {			
    			if (typeof(match[nr]) != 'undefined') matchValue = match[nr];
    			else matchValue = 0;
     
    			newTbody = createMatchPowerline(newTbody, key, nr, matchValue);
    		}
     
    		div.appendChild(newTbody);
    	}
     
    	totalMatch.value = total;
    }

    Does anyone have an idea on how I can fetch those values in IE?

    Thanks

  2. #2
    SitePoint Wizard TheRedDevil's Avatar
    Join Date
    Sep 2004
    Location
    Norway
    Posts
    1,190
    Mentioned
    3 Post(s)
    Tagged
    0 Thread(s)
    There has to be someone who has experienced a similar problem?

    Thanks

  3. #3
    SitePoint Addict miggl's Avatar
    Join Date
    Feb 2007
    Location
    Los Angeles, CA
    Posts
    286
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    I think the problem is the following:

    Check to see if your form element names match up EXACTLY as you have it in the getElementById() call. This means that your field names must look like this:
    Code:
    <inpyt type="text" name="plan_bonus_amount[test][]" />
    .

    The important part here is that IE requires the empty brackets (it's dumb). Firefox et. al are smart enough to see that this is actually an array of objects.

    Cross my fingers that I'm right. hehe
    Celebrate Liberty, Freedom, and Rights at The Constitutionalist.

  4. #4
    SitePoint Wizard TheRedDevil's Avatar
    Join Date
    Sep 2004
    Location
    Norway
    Posts
    1,190
    Mentioned
    3 Post(s)
    Tagged
    0 Thread(s)
    Thanks for your answer. The input fields look like that yes, only that the key is numeric instead of alphachar based.

    I have created a lighter version of the code , replicating the error.
    The code is identical to the one I use, with the exeption that its now working on only one 2d array instead of multiple.

    I have uploaded the page to:
    http://test.kaizen-web.com/javascrip...rray_issue.php

    When you open it, you will notice it visually only contain one text input field. Add any number into this field and click outside of the field. Now it will generate an additional number of text input fields according to the number you inputted. (This works in FF, Opera and IE).

    But if you now decide to change the number of boxes, and add a different number to the first box and click out it will crash in IE with the error "'value' is null or not an object"

    The error happens on this line:
    match[nr] = parseFloat(matchPaid[nr].value);

    This tells us that the matchPaid array is not populated, and that the real error is in this line:
    var matchPaid = document.getElementsByName("plan_bonus_amount["+key+"][]");


    If anyone has an idea what should be changed to make this work with IE it would be highly appreciated.


    I have tested it in IE ver. 6 with all security updates.

    The code in the test case is included below, it is the first javascript function that fails.

    Code JavaScript:
    function updateMatch(total) {
    	var totalMatch = document.getElementById("total_match");
    	var matchValue = 0;
    	var key = 1;
     
    	var div = document.getElementById("match_table_1");
    	var newTbody = document.createElement("tbody");	
     
    	var match = new Array();
     
    	if (parseInt(totalMatch.value) > 0) {
    		/*Fetch the current values, then clear the table*/
    		var matchPaid = document.getElementsByName("plan_bonus_amount["+key+"][]");
     
    		for (var nr=0;nr < parseInt(totalMatch.value);nr++) {
    			match[nr] = parseFloat(matchPaid[nr].value);
    		} 
     
    		remove(div);
    	}
     
    	for (var nr=0;nr < total;nr++) {			
    		if (typeof(match[nr]) != 'undefined') matchValue = match[nr];
    		else matchValue = 0;
     
    		newTbody = createMatch(newTbody, key, nr, matchValue);
    	}
     
    	div.appendChild(newTbody);
     
    	totalMatch.value = total;
    }

    Code JavaScript:
    function createMatch(div, key, nr, matchValue) {
    	var newTr = document.createElement("tr");
    	var newTd = document.createElement("td");
    	var newTd2 = document.createElement("td");
    	var newInput = document.createElement("input");
    	var newText = document.createTextNode("Level "+(nr+1)+":");
     
    	newInput.name = 'plan_bonus_amount['+key+'][]';
    	newInput.value = matchValue;
     
    	newTd.appendChild(newText);
    	newTd2.appendChild(newInput);
     
    	newTr.appendChild(newTd);
    	newTr.appendChild(newTd2);
     
    	div.appendChild(newTr);
     
    	return div;
    }

    Code JavaScript:
    function remove(from) {
    	if (from != null && from.childNodes) {
     
    		while (from.firstChild) {
    			from.removeChild(from.firstChild);
    		}
    	}
    }

    Code HTML4Strict:
    <form method="post" action="test.php">
    		<input type="hidden" id="total_match" name="total_match" value="0">
    		<div>
    			<input type="text" id="test" name="test" value="" onchange="updateMatch(this.value)">
    		</div>
    		<table id="match_table_1">
    		</table>
    	</form>

  5. #5
    SitePoint Addict miggl's Avatar
    Join Date
    Feb 2007
    Location
    Los Angeles, CA
    Posts
    286
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Try this:
    Code:
    function updateMatch(total) {
    	var totalMatch = document.getElementById("total_match");
    	var matchValue = 0;
    	var key = 1;
    
    	var div = document.getElementById("match_table_1");
    	var newTbody = document.createElement("tbody");	
    	
    	var match = new Array();
    		
    	if (parseInt(totalMatch.value) > 0) {
    		/*Fetch the current values, then clear the table*/
    		var matchPaid = document.getElementsByTagName("input");
    			
    //		for (var nr=0;nr < parseInt(totalMatch.value);nr++)
    		for (var nr=0; nr<matchPaid.length; nr++)
    		{
    			if (matchPaid[nr].name == "plan_bonus_amount[]")
    			{
    				match[match.length] = parseFloat(matchPaid[nr].value);
    			}
    		} 
    			
    		remove(div);
    	}
    		
    	for (var nr=0;nr < total;nr++) {			
    		if (typeof(match[nr]) != 'undefined') matchValue = match[nr];
    		else matchValue = 0;
    		
    		newTbody = createMatch(newTbody, key, nr, matchValue);
    	}
    		
    	div.appendChild(newTbody);
    
    	totalMatch.value = total;
    }
    Celebrate Liberty, Freedom, and Rights at The Constitutionalist.

  6. #6
    SitePoint Wizard TheRedDevil's Avatar
    Join Date
    Sep 2004
    Location
    Norway
    Posts
    1,190
    Mentioned
    3 Post(s)
    Tagged
    0 Thread(s)
    Thanks for your answer, much appreciated.

    After a little modification I got to work halfway, the problem is that it for some reason put 2d arrays into one, which contain the value of the last second array input. When I tried to loop over the second array, it gave me the same null error.


    Is it possible that IE just does not have javascript support to work with 2d form arrays? Though that sounds odd, considering how usual 2 and 3d arrays are in other languages.

  7. #7
    SitePoint Addict miggl's Avatar
    Join Date
    Feb 2007
    Location
    Los Angeles, CA
    Posts
    286
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by TheRedDevil View Post
    Thanks for your answer, much appreciated.

    After a little modification I got to work halfway, the problem is that it for some reason put 2d arrays into one, which contain the value of the last second array input. When I tried to loop over the second array, it gave me the same null error.


    Is it possible that IE just does not have javascript support to work with 2d form arrays? Though that sounds odd, considering how usual 2 and 3d arrays are in other languages.
    IE does have some very odd peculiarities regarding their official DOM support. So some functions won't behave as expected. Also, the programming that went into the DOM support was mediocre at best, whereas the standard compliant browsers are smarter and work as expected, for the most part.

    I know that doesn't answer your questions with a "yes/no" answer, however: you may want to check if the element you are working with is an array. For this you would best use recursion through a function call that gets all the elements you need.

    Sorry, I can't be more specific at this time, as I would otherwise have to write the code out myself (not at home at the moment).
    Celebrate Liberty, Freedom, and Rights at The Constitutionalist.

  8. #8
    SitePoint Wizard TheRedDevil's Avatar
    Join Date
    Sep 2004
    Location
    Norway
    Posts
    1,190
    Mentioned
    3 Post(s)
    Tagged
    0 Thread(s)
    Thanks again for taking the time to answer.

    As you mention, it seems to be a specific issue with the way IE handle the DOM support (at least IE 6).

    The code you provided works the same in FF, Opera and IE. All of the browsers convert the 2d array into a single array, containing either the first or the last value in the second array as the value (that were the different from FF/Opera and IE).

    I am not too familiar at javascript, so I am a little unsure how I should approach to check if it finds it as an array or not. When I do a typeof check, it just say its an object; though an empty one in IE.

    When going over the code in php it does convert the input fields correctly into 2d arrays where they should exists. So I believe the html is correct, and that it is a IE javascript issue (Especially since it works in FF and Opera).


    A possible solution would be to change the 2d arrays into a single array, and append the "first array" to the field name instead. Basically "fieldname_X[]" where the X would be the first array integer value. Would be a little more difficult to loop over the values, but nothing to worry about.

    Though its an interesting issue, if 2d form arrays are actually possible in IE or it they need to be shun like the plague. If anyone has additional information, please share what you know.

    Thanks

  9. #9
    SitePoint Addict miggl's Avatar
    Join Date
    Feb 2007
    Location
    Los Angeles, CA
    Posts
    286
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    When you use array of elements or other JavaScript objects (such as the results of getElementsByName()) I would in general aim to avoid 2-dimensional arrays.

    The underlying principle here is that you get all items (regardless of nesting level) that meet a certain criteria (maybe the name). You then want to treat this collection as a raw collection, and examine it as a collection, not as a DOM node list (which would include hierarchies). If you wanted to examine it as a hierarchy, you could examine the DOM node list directly, without creating references to "filtered" collections.

    That being said, I would avoid 2-dimensional arrays in your case, and treat it as a one-dimensional array of objects.
    Celebrate Liberty, Freedom, and Rights at The Constitutionalist.

  10. #10
    SitePoint Wizard TheRedDevil's Avatar
    Join Date
    Sep 2004
    Location
    Norway
    Posts
    1,190
    Mentioned
    3 Post(s)
    Tagged
    0 Thread(s)
    Thanks for the reply.

    After another round of debugging and some swearing, I created a "unique" id for each form field in the 2d arrays.

    IE would not work with single arrays either when using the getElementsByName function. It migth have worked with getElementsByTagName, though I decided not to go that route due to the amount of fields the form can contain, no need to make the script use more resources than necessary.


    If anyone else has the same problem, I solved it by changing this part of my code:
    Code JavaScript:
    if (parseInt(totalMatch.value) > 0) {
            /*Fetch the current values, then clear the table*/
            var matchPaid = document.getElementsByName("plan_bonus_amount["+key+"][]");
     
            for (var nr=0;nr < parseInt(totalMatch.value);nr++) {
                match[nr] = parseFloat(matchPaid[nr].value);
            } 
     
            remove(div);
        }

    Into:
    Code JavaScript:
    if (parseInt(totalMatch.value) > 0) {
    			/*Fetch the current values, then clear the table*/
    			for (var nr=0;nr < parseInt(totalMatch.value);nr++) {
    				var matchPaid = document.getElementById("plan_bonus_amount_"+key+"_"+nr);
     
    				match[nr] = parseFloat(matchPaid.value);
    			}

    I also added the same id layout when the field is dynamically created. The numbers beeing the placement the field has in the 2d array.


Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •