Solved

Problem writing Javascript to the DOM in IE only

Posted on 2009-04-08
9
703 Views
Last Modified: 2013-12-08
I've got a bit of a confusing one here regarding writing to the DOM on the fly. I've included a stripped down version of my page in the code section below to highlight the problem that can be reproduced locally.

If you run the page in Firefox and the IE7 it should be pretty obvious what the problem is, but I'll explain: I start my page with 2 select fields in static HTML - the options/values of the second are written dynamically depending on what is selected in the first select field, so they work as a pair. The first is a category, the second essentially is a product. This bit is working fine, when i change category the options change in the product drop down.

I now have a button to add further pairs of these select fields to create further category/product inputs, and when this button is clicked there's a fair amount of script which creates notes and inserts them into the DOM in the appropriate place, giving new names to the fields based on a random number. This bit actually works fine too, and even a button to remove the parent paragraph tag which the new select pairs are in works fine in both browsers.

What Im having trouble with is setting the attribute of 'onChange' in the first select to call the javascript function. The function requires two parameters - the selectedIndex and the name of the field to update, and this is done in line 73 - the variable "passFunctionInSetAttr" is set and ontains the complete function call. This is then added to the node 3 lines later (after being alerted to the screen so I can see what is going on and that it is fine - it is).

And in firefox it works perfectly - I get an alert to say that its reached the updateproducts  function as expected and the newly created select list updates with the products list, but in IE (Im in version 7) - despite that I'm echoing the string back in the alert to see it's working - and it seems to be - it fails silently without an error message or anything and it doesnt reach the function to update the products - I can tell as the alert doesnt come up. I've been pulling this apart today in Visual Web Developer 2008 to try and get some debugging messages and theres no error message or anything, yet it doesn't work and fails in total silence.

I've added a 'Print Dom' button to this too, so I can print out the structure of the document that's been written on the fly and take a look - and it does look a little odd - the paragraph id isn't quoted for example (how can I change this I wonder..) but it seems to look vaguely ok.

Weirdly though, if i then paste the dom that is dumped out into the text area into its own document, and run it locally in a browser (just need to add the Doctype and HTML tags around the core code), it then gets as far as the function in IE and flashes up the alert which it didn't before. It still fails to update the second select..  but this is supposed to be exactly the same script, just one is written on the fly and the other has been run from a static HTML document - and its behaving differently.

Not sure if I've done something stupid here or hit a Javascript bug, but many thanks in advance for any help anyone can give me on this!

Matt


<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Select DOM Test</title>
<script type="text/javascript">
    function node_delete(whichPara) {
        if (confirm("Are you sure you want to delete this product?")) {
            document.getElementById('allparas').removeChild(document.getElementById(whichPara));
       }
    }
 
    function printDom() {
        allHTML = document.getElementsByTagName("html")[0].innerHTML;
        document.forms['update_table'].elements['dom'].value = allHTML;
 
    }
    var products_matrix = new Array();
    products_matrix[0] = "";
    products_matrix[1] = new Array("550|X1|product 1|10");
    products_matrix[2] = new Array("551|Y1|Product in section 2|10", "552|Y2|Another Product in Section 2|10");
    products_matrix[3] = new Array("640|B-682|Product in 3|1", "641|B-682-int|Another in 3|1", "642|CD-682|Product|1", "643|CD-6821|Another Product|1", "644|CD-C|And Another Product|1");
    products_matrix[4] = new Array("611|E-API682sd|Item in section 4|15", "612|B-AP|Another item in section 4|15", "613|S2wed|item name here|20", "614|B-Chem|Another items|15", "615|B-Chem|and another|15", "616|B-C|Aargh|15", "624|B-Oi|Final test product|15");
 
    var categories_names_array = new Array("Section 1", "Section 2", "Section 3", "Section 4");
    var categories_ids_array = new Array("6", "7", "12", "9");
 
    function updateproducts(selectedcategory, fieldtoupdate) {
        alert("reached update products function");
        
        var categorieslist = document.update_table.category1
        var productslist = eval("document.forms['update_table'].elements['" + fieldtoupdate + "']")
 
        productslist.options.length = 0
        if (selectedcategory > 0) {
            for (i = 0; i < products_matrix[selectedcategory].length; i++)
                productslist.options[productslist.options.length] = new Option(products_matrix[selectedcategory][i].split("|")[1] + "  -  " + products_matrix[selectedcategory][i].split("|")[2], products_matrix[selectedcategory][i].split("|")[0]);
        }
    }
 
    //-->
</script>
</head>
<body>
 
<form name="update_table" method="post" action="" enctype="multipart/form-data" style="padding:0px; margin:0px">
<p style="font-size:12px">Select Category:<br />
<select name="category1" onChange="updateproducts(this.selectedIndex,'product1')" />
<option value="">Select a category:</option>
<script language="Javascript">
    for (p=0;p<categories_names_array.length;p++){
	document.write("<option value=\"" + categories_ids_array[p] + "\">" + categories_names_array[p] + "</option>\n");
    }
</script></select>
</p>
 
<p style="font-size:12px">Product Name: <select name="product1" style="font-size:13px">
<option value="" style="font-family:tahoma,arial,verdana,helvetica"> Please select a category first </option>
</select>
</p>
 
<div id="allparas">
<span class="order_button" style="margin-top:30px"><a style="font-weight:bold; clear:both; padding-top:10px; margin-top:10px;" href="#" onclick="
if( !document.createElement || !document.childNodes ) {
	window.alert('Your browser is not DOM compliant');
} else {
	// set up paragraph and select
	randomNumber = Math.floor(Math.random()*9999999999999999) 
	var theNewParagraph = document.createElement('p');
	var lineBreak = document.createElement('br');
	var divName = 'div_' + randomNumber;
	var theTopCategorySelect = document.createElement('select');
	var theSelect = document.createElement('select');
	newSelectName= 'select_' + document.getElementsByTagName('p').length;
	newCatSelectName= 'select_category_' + randomNumber
    myRandomNumber = Math.floor(Math.random()*9999999999999999);
	newSelectName = newSelectName + myRandomNumber;
    theSelect.setAttribute('name',newSelectName);
    theSelect.setAttribute('style','font-size:13px;');
	theTopCategorySelect.setAttribute('name',newCatSelectName);
	theTopCategorySelect.setAttribute('style','font-size:13px');
    
	passFunctionInSetAttr='updateproducts(this.selectedIndex,\'' + newSelectName + '\')';
	alert(passFunctionInSetAttr);
	
	theTopCategorySelect.setAttribute('onChange',passFunctionInSetAttr);
 
	// set up options for select
	firstOption = document.createElement('option');
	firstOption.setAttribute('value','');
	firstOption.setAttribute('style','font-weight:bold; font-size:12px');
	firstText = document.createTextNode(' - ');
	theSelect.appendChild(firstOption);
	firstOption.appendChild(firstText);
	arrayOptions=Array();
	arrayText=Array();
   
	// set up options for category select
	catFirstOption = document.createElement('option');
	catFirstOption,setAttribute('value','');
	catFirstOption.setAttribute('style','font-weight:bold; font-size:12px');
	catFirstText = document.createTextNode('Select A Category:');
	theTopCategorySelect.appendChild(catFirstOption);
	catFirstOption.appendChild(catFirstText);
	arrayOptions=Array();
	arrayText=Array();
    for (p=0;p<categories_ids_array.length;p++){
		arrayOptions[p] = document.createElement('option');
		arrayOptions[p].setAttribute('value',categories_ids_array[p]);
		arrayOptions[p].setAttribute('style','font-size:13px; ');
		arrayText[p] = document.createTextNode(categories_names_array[p]);
		theTopCategorySelect.appendChild(arrayOptions[p]);
		arrayOptions[p].appendChild(arrayText[p]);
	}
 
	var theDeleteImage = document.createElement('img');
	
	//set up theNewParagraph
	newParaName= 'para_' + document.getElementsByTagName('p').length;
	newParaName += randomNumber; 
	theNewParagraph.setAttribute('id',newParaName);
	theNewParagraph.setAttribute('style','padding-top:10px; font-size:12px; clear:both;');
 
    // delete image 
	theDeleteImage.setAttribute('src','http://www.dmlmarketing.net/demo/cancel.png');
	deleteImageName = 'delete_' + document.getElementsByTagName('p').length;
	deleteImageName += randomNumber; 
	theDeleteImage.setAttribute('id',deleteImageName);
	theDeleteImage.setAttribute('hspace','20');
	theDeleteImage.setAttribute('vspace','3');
 
    // div
	theDiv = document.createElement('div');
	theDiv.setAttribute('id',divName); 
	theDiv.setAttribute('style','display:inline; float:left;'); 
 
 	//prepare the text nodes
	var theText1 = document.createTextNode('Product Name:');
    theCategoryText = document.createTextNode('Select Category:');
       
    
	//put together the whole paragraph
	theNewParagraph.appendChild(theCategoryText);
	theNewParagraph.appendChild(lineBreak);
	theNewParagraph.appendChild(theTopCategorySelect);
	theNewParagraph.appendChild(lineBreak);
	theNewParagraph.appendChild(theText1);
	theNewParagraph.appendChild(theSelect);
	theNewParagraph.appendChild(theDiv);
	theDiv.appendChild(theDeleteImage);
	
	//insert it into the document somewhere
	this.parentNode.parentNode.insertBefore(theNewParagraph,this.parentNode);
	//make the paragraph delete itself when the delete image is clicked
	document.getElementById(deleteImageName).onclick = function () { node_delete(this.parentNode.parentNode.id); };
}
return false;">Add New</a></span>
<hr />
<span style="disaply:block; clear:both;"><textarea name="dom" rows=10 cols=70></textarea><br /><a href="Javascript:printDom()">Print Dom</a></span>
</form>
</body>
</html>

Open in new window

0
Comment
Question by:MatthewP
  • 4
  • 3
9 Comments
 
LVL 41

Expert Comment

by:HonorGod
ID: 24099909
I'm pretty sure that the problem is with this line of code:

document.getElementById(deleteImageName).onclick = function () { node_delete(this.parentNode.parentNode.id);

I've had problems before trying to change the onclick in IE.
What I had to end up doing was checking for an attachEvent function associated with the object (element), and using it, instead of the
assignment like you have, or setAttribute.

Something like:
var ele = document.getElementById( 'deleteImageName' )
if ( ele.attachEvent ) {
  ele.attachEvent( 'onfocus', function() { doSomething(this.event.srcElement); } )
} else {
  ele.setAttribute( 'onclick', 'doSomething(this);' );
}

Open in new window

0
 
LVL 41

Expert Comment

by:HonorGod
ID: 24099916
sorry, the attachEvent should have been
ele.attachEvent( 'onclick', function() { doSomething(this.event.srcElement); } )

Open in new window

0
 
LVL 6

Author Comment

by:MatthewP
ID: 24100111
Hi,

Thanks for taking a look. did you try running the code locally? The delete is working perfectly for me in both browsers, its the onChange when written to the DOM that is failing.

Thanks,
Matt
0
Master Your Team's Linux and Cloud Stack!

The average business loses $13.5M per year to ineffective training (per 1,000 employees). Keep ahead of the competition and combine in-person quality with online cost and flexibility by training with Linux Academy.

 
LVL 41

Expert Comment

by:HonorGod
ID: 24100212
Haven't had a chance yet... Trying to do way too many things at once. :-)
0
 
LVL 6

Author Comment

by:MatthewP
ID: 24100282
Tell me about it :) I've been on this 2 days and not got anywhere, I need to forget about it for a bit. If you're up for taking a look though the script i sent should demonstrate it pretty succinctly. I've either done something very stupid.. or its an IE bug.. i *think*.

Cheers,
matt

0
 
LVL 6

Author Comment

by:MatthewP
ID: 24926770
Bit of a curious one this, I got it fixed but not by what I was trying to do but by adding another line similar to:

document.getElementById(deleteImageName).onclick = function () { node_delete(this.parentNode.parentNode.id); };

it all worked correctly - it seems that the event wouldnt attach directly to the element but would if I attached it later. Not figured out why but there you go.
0
 
LVL 41

Expert Comment

by:HonorGod
ID: 24927095
Wow, somehow, I lost track of this, and never returned.

Please forgive me.

I'm glad that you were able to get the issue resolved though.
0
 

Accepted Solution

by:
ee_auto earned 0 total points
ID: 25621634
Question PAQ'd, 500 points refunded, and stored in the solution database.
0

Featured Post

Master Your Team's Linux and Cloud Stack!

The average business loses $13.5M per year to ineffective training (per 1,000 employees). Keep ahead of the competition and combine in-person quality with online cost and flexibility by training with Linux Academy.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Title # Comments Views Activity
How to use embargo Date/time in php 29 39
Best Way to remove the port from a URL? 15 38
Jquery keyup 4 20
How to reload page and grab querystring 2 11
I had to do a bit of research to find the answer to this question so I thought I'd share my results.  Due to our outdated mainframe systems, we need to downgrade IE9 to IE8 in order to stay compatible.  We also needed to downgrade Java.  In order to…
Today, still in the boom of Apple, PC's and products, nearly 50% of the computer users use Windows as graphical operating systems. If you are among those users who love windows, but are grappling to keep the system's hard drive optimized, then you s…
Google currently has a new report that is in beta and coming soon to Webmaster Tool accounts. This Micro Tutorial will highlight new features for Google Webmaster Tools.
Shows how to create a shortcut to site-search Experts Exchange using Google in the Chrome browser. This eliminates the need to type out site:experts-exchange.com whenever you want to search the site. Launch the Search Engine Menu: In chrome, via you…

803 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question