Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Chriss Miller on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

DOM Inconsistencies btw. IE and Firefox 1

Status
Not open for further replies.

cLFlaVA

Programmer
Jun 14, 2004
6,450
US
Hi all,

I've been writing this script today just based on questions I've seen here over the past few days. It basically allows you to specify the number of fields to create, using a select box, then either creates or removes fields depending on the number selected.

the red line works perfectly in FF, but for some reason returns false in IE. any ideas why this is happening?

thanks!

Code:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
	"[URL unfurl="true"]http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">[/URL]

<html>
<head>
<title>Untitled</title>
<style type="text/css">
label { display: block; }
</style>
<script type="text/javascript"><!--

function changeFields( objParentTargetId, intNumFields, strLabelStart ) {
    var objParent = document.getElementById( objParentTargetId );
    var aryElems = objParent.getElementsByTagName( "input" );
    
    if ( aryElems.length > intNumFields ) {
        
        for ( var intI = 0; intI < aryElems.length; intI++ ) {
            if ( intI+1 > intNumFields ) {
                var objRemove = aryElems[intI];
                alert("removing " + aryElems[intI].name);
                objParent.removeChild(objRemove.parentNode);
                intI--;
            }
        }
    }
    
    for ( var intI = 1; intI <= intNumFields; intI++ ) {
        alert(aryElems[strLabelStart + intI]?(strLabelStart + intI + " exists!"):(strLabelStart + intI + " does not exist!"));
        [red]if ( !aryElems[strLabelStart + intI] ) {[/red]
            var objLabel = document.createElement( "label" );
            objLabel.htmlFor = strLabelStart + intI;
            objLabel.innerHTML = strLabelStart + " " + intI + ":";
            
            var objTextBox = document.createElement( "input" );
            objTextBox.type = "text";
            objTextBox.name = strLabelStart + intI;
            
            objParent.appendChild( objLabel );
            objLabel.appendChild( objTextBox );
        }
    }
}

//--></script>
</head>

<body>

<form name="f" action="blah">
    <fieldset>
        <select name="numTextFields" onchange="changeFields('fsTarg', this.value, 'File');">
            <option value="0"></option>
            <option value="1">1</option>
            <option value="2">2</option>
            <option value="3">3</option>
            <option value="4">4</option>
            <option value="5">5</option>
        </select>
    </fieldset>
    <fieldset id="fsTarg">
    </fieldset>
</form>

</body>
</html>



*cLFlaVA
----------------------------
[tt]somebody set up us the bomb![bomb][/tt]

[URL unfurl="true"]http://www.coryarthus.com/[/url]
 
Cory, it works for me in IE 6.
The line evaluates true showing that aryElems[strLabelStart + intI] does not already exist and it goes and creates it.

At my age I still learn something new every day, but I forget two others.
 
Sorry... I should have mentioned the test case:

select 4, then select 2.

it is supposed to remove fields 3 and 4. instead, it removes 3 and 4, then writes another 1 and 2!

thanks for taking a look.



*cLFlaVA
----------------------------
[tt]somebody set up us the bomb![bomb][/tt]

[URL unfurl="true"]http://www.coryarthus.com/[/url]
 
IE has problems referencing dynamically created elements by their name which might be what is causing the problem you are having.

When IE adds the elements to the page the name value is set but cannot be directly addressed the way you are attempting.
If instead you loop through the elements array and check the name property you can detect it.

Try a function like this:
Code:
function checkElement(objParentTargetId, fldName) {
  var objParent = document.getElementById( objParentTargetId );
  var aryElems = objParent.getElementsByTagName( "input" );
  for (var e = 0; e < aryElems.length; e++) {
    if (aryElems[e].name == fldName)
      return true;
  }
  return false;
}

Add in this new variable declaration and modify your if statement like this:
Code:
        var fldName = strLabelStart + intI;
        if ( !checkElement(objParentTargetId, fldName) ) {

The new function loops through the input fields and checks the name property of each rather than trying to directly compare the name of the element inside the array which is where IE hangs up.


At my age I still learn something new every day, but I forget two others.
 
hi theniteowl...

do you just know that from prior experience, or do you have a link about this IE issue? i believe you, i'm just curious and want to read up on it more.

i don't know why i bother, though, because nothing surprises me anymore with IE.



*cLFlaVA
----------------------------
[tt]somebody set up us the bomb![bomb][/tt]

[URL unfurl="true"]http://www.coryarthus.com/[/url]
 
I found it mentioned on a site a long time ago when I was working on adding/removing form elements with DOM methods.
The code was set to detect document.all and alter it's approach accordingly.

I do not remember where I originally found it but searching on the text of a comment in the code found a number of sites, here is a link to one:

I have found that the direct approach fails even in IE 6 but that looping through the elements and testing the name property individually does work.


At my age I still learn something new every day, but I forget two others.
 
thanks buddy.

i modified your function a little, here's the complete working code:

Code:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
	"[URL unfurl="true"]http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">[/URL]

<html>
<head>
<title>Untitled</title>
<style type="text/css">
label { display: block; }
</style>
<script type="text/javascript"><!--

function checkElement(objParent, aryElems, fldName) {
  for (var e = 0; e < aryElems.length; e++) {
    if (aryElems[e].name == fldName)
      return true;
  }
  return false;
}

function changeFields( objParentTargetId, intNumFields, strLabelStart ) {
    var objParent = document.getElementById( objParentTargetId );
    var aryElems = objParent.getElementsByTagName( "input" );
    var strFieldName = "";
    
    if ( aryElems.length > intNumFields ) {
        
        for ( var intI = 0; intI < aryElems.length; intI++ ) {
            if ( intI+1 > intNumFields ) {
                var objRemove = aryElems[intI];
                objParent.removeChild(objRemove.parentNode);
                intI--;
            }
        }
    }
    
    for ( var intI = 1; intI <= intNumFields; intI++ ) {
        strFieldName = strLabelStart + intI;
        if ( !checkElement( objParent, aryElems, strFieldName ) ) {
            var objLabel = document.createElement( "label" );
            objLabel.htmlFor = strFieldName;
            objLabel.innerHTML = strLabelStart + " " + intI + ":";
            
            var objTextBox = document.createElement( "input" );
            objTextBox.type = "text";
            objTextBox.name = strFieldName;
            
            objParent.appendChild( objLabel );
            objLabel.appendChild( objTextBox );
        }
    }
}

//--></script>
</head>

<body>

<form name="f" action="blah">
    <fieldset>
        <select name="numTextFields" onchange="changeFields('fsTarg', this.value, 'File');">
            <option value="0"></option>
            <option value="1">1</option>
            <option value="2">2</option>
            <option value="3">3</option>
            <option value="4">4</option>
            <option value="5">5</option>
        </select>
    </fieldset>
    <fieldset id="fsTarg">
    </fieldset>
</form>

</body>
</html>



*cLFlaVA
----------------------------
[tt]somebody set up us the bomb![bomb][/tt]

[URL unfurl="true"]http://www.coryarthus.com/[/url]
 
I began writing it that way myself but was also converting the function from different purposes at the same time I was adapting it for your code but I kept getting distracted by work-related emergencies so I just threw together the quickest working version. I knew you could simplify it with your current objects. :)

Aint IE a pain though?

At my age I still learn something new every day, but I forget two others.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top