By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
424,962 Members | 1,998 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 424,962 IT Pros & Developers. It's quick & easy.

Problem with events on dynamically created input fields in internet explorer

P: n/a
Hi,

I'm having a problem with the dynamically created inputfields in
Internet Explorer.
The situation is the following:
- I have a dynamically created table with a textbox in each Cell.
- It is possible to Add and Delete rows
- Some cells have special attributes (readonly and events)

Here's a snippet of the code:
function addRowToTable(p_vestigingnummer,
p_straat_vest,
p_huisnr_vest,
p_bus_vest,
p_postcode_vest,
p_gemeente_vest,
p_plaats_syscode_vest,
p_vanaf_vest
) {
var tbl = document.getElementById("tablename");
var lastRow = tbl.rows.length;
lastRow--;
v_row++
v_rowid = "row" + v_row;
// if theres no header row in the table, then iteration =
lastRow + 1
var iteration = lastRow;
var row = tbl.insertRow(lastRow);
row.setAttribute("id",v_rowid);

/*.....more cells added here......*/
var CellPostcode = row.insertCell(4);
CellPostcode.setAttribute("nowrap","");
var CellPostcodeTekst = document.createElement("input");
var Anchornode = document.createElement("a");
Anchornode.setAttribute("href","javascript:call_zo ekgemeente_byID(\''p_plaats_sys_vest"
+ v_rowid + "\'',\''p_postcode_vest" + v_rowid +
"\'',\''p_gemeente_vest" + v_rowid + "\'')");
var Imagenode = document.createElement("img");
Imagenode.setAttribute("src","/images/list.gif");
Imagenode.setAttribute("border","0");
CellPostcodeTekst.setAttribute("type","text");
CellPostcodeTekst.setAttribute("name","p_postcode_ vest_tmp");
CellPostcodeTekst.setAttribute("id","p_postcode_ve st" +
v_rowid);
CellPostcodeTekst.setAttribute("size","3");
CellPostcodeTekst.setAttribute("value",p_postcode_ vest);
//troubles CellPostcodeTekst.setAttribute("onblur","call_zoek gemeente_byID(\''p_plaats_sys_vest"
+ v_rowid + "\'',\''p_postcode_vest" + v_rowid +
"\'',\''p_gemeente_vest" + v_rowid + "\'')");
CellPostcode.appendChild(CellPostcodeTekst);
Anchornode.appendChild(Imagenode);
CellPostcode.appendChild(Anchornode);

//Cell gemeente
var Cellgemeente = row.insertCell(5);
var CellgemeenteTekst = document.createElement("input");
CellgemeenteTekst.setAttribute("type","text");
CellgemeenteTekst.setAttribute("name","p_gemeente_ vest_tmp");
CellgemeenteTekst.setAttribute("id","p_gemeente_ve st" +
v_rowid);
CellgemeenteTekst.setAttribute("size","20");
CellgemeenteTekst.setAttribute("value",p_gemeente_ vest);
CellgemeenteTekst.setAttribute("READONLY","true"); //troubles
var Cellplaatshidden = document.createElement("hidden");
Cellplaatshidden.setAttribute("type","hidden");
Cellplaatshidden.setAttribute("name","p_plaats_sys _vest_tmp");
Cellplaatshidden.setAttribute("value",p_plaats_sys code_vest);
Cellplaatshidden.setAttribute("id","p_plaats_sys_v est" +
v_rowid);

Cellgemeente.appendChild(CellgemeenteTekst);
Cellgemeente.appendChild(Cellplaatshidden);
}

Now The problem(s) is this:
If you change the textbox "p_postcode" (which is postal code in
english - or something like that) it must invoke a function which
looks up the correct city.
This works fine in Firefox but it doesn't do a damn thing in Internet
Explorer 6. I've allready changed the onchange event to onblur but
that doesn't help.
Second problem is the readonly attribute which doesn't seem to work in
IE.

Now my question is offcourse: Why doesn't it work in Internet
Explorer? Am I dealing with a MS bug here or is there some other
explanation?
Strange thing is that a lot of other attributes work perfectly (but i
don't need those, haha, programming is fun) like disabled, style,
etc....
I's nearly impossible to change the whole code (time is running out)
so I'll have to find a fix here!

anyone have a clue?

Greetz,
Thomas
Jul 23 '05 #1
Share this Question
Share on Google+
6 Replies


P: n/a
Thomas wrote:
Hi,

I'm having a problem with the dynamically created inputfields in
Internet Explorer.
The situation is the following:
- I have a dynamically created table with a textbox in each Cell.
- It is possible to Add and Delete rows
- Some cells have special attributes (readonly and events)
[snip] CellPostcodeTekst.setAttribute("onblur","call_zoek gemeente_byID(\''p_plaats_sys_vest" [snip] CellgemeenteTekst.setAttribute("READONLY","true"); [snip]
Now The problem(s) is this:
If you change the textbox "p_postcode" (which is postal code in
english - or something like that) it must invoke a function which
looks up the correct city.
This works fine in Firefox but it doesn't do a damn thing in Internet
Explorer 6. I've allready changed the onchange event to onblur but
that doesn't help.
The problem is that event handler attributes are functions, not strings.
Mozilla browsers parse the string and create a function object, just like
they do when they parse the HTML. IE, on the other hand, expects you to
set the attribute to a Function object; it doesn't parse the string.

Which is correct? Neither, really. According to the W3C DOM specs, the
setAttribute method only accepts a string for the second argument, so
IE isn't compliant. On the other hand, event handlers are special cases
that are handled by a completely separate method using DOM-compliant
clients; they aren't really attributes (which can only be strings) at all.

"addEventListener"
http://www.w3.org/TR/DOM-Level-2-Eve...dEventListener

Unfortunately, IE doesn't follow the spec for adding event handlers to
elements (of course); it has its own proprietary method.

"attachEvent Method"
http://msdn.microsoft.com/workshop/a...ttachevent.asp

Unless you want to do client capability-sniffing, the cross-browser way
to add event handlers to elements is to avoid the setAttribute menthod
(which is the wrong approach anyway) and the W3C-DOM and MS-proprietary
methods and to use the DOM-0 format:

CellPostcodeTekst.onblur=function(){call_zoekgemee nte_byID(...)}
Second problem is the readonly attribute which doesn't seem to work in
IE.
IE wants the attribute to be spelled "readOnly" (with a capital O).
You should also be aware that although Mozilla accepts the value
"READONLY", Opera does not. It also expects the value "readOnly".
Now my question is offcourse: Why doesn't it work in Internet
Explorer? Am I dealing with a MS bug here or is there some other
explanation?
setAttribute isn't really meant to handle event handlers.
Strange thing is that a lot of other attributes work perfectly (but i
don't need those, haha, programming is fun) like disabled, style,
etc....
Other attributes are string values; setAttribute is meant to work with
them.
I's nearly impossible to change the whole code (time is running out)
so I'll have to find a fix here!

anyone have a clue?


Use the DOM-0 method to attach event handlers and use the value
"readOnly" to set the readonly attribute.

--
Steve

If a man points at the moon, an idiot will look at the finger.
-Sufi wisdom
Jul 23 '05 #2

P: n/a
Thomas wrote:
Hi,
Steve has already pointed you in the right direction, I'll just lob a
few extras in...

I'm having a problem with the dynamically created inputfields in
Internet Explorer.
The situation is the following:
- I have a dynamically created table with a textbox in each Cell.
- It is possible to Add and Delete rows
- Some cells have special attributes (readonly and events)

Here's a snippet of the code:
function addRowToTable(p_vestigingnummer,
p_straat_vest,
p_huisnr_vest,
p_bus_vest,
p_postcode_vest,
p_gemeente_vest,
p_plaats_syscode_vest,
p_vanaf_vest
) {
var tbl = document.getElementById("tablename");
var lastRow = tbl.rows.length;
lastRow--;
v_row++
v_rowid = "row" + v_row;
// if theres no header row in the table, then iteration =
lastRow + 1
var iteration = lastRow;
var row = tbl.insertRow(lastRow);
row.setAttribute("id",v_rowid);
All of your 'setAttribute' stuff can be done by accessing the
properties directly. You don't seem to be supporting older browsers,
so I can't see an issue with:

row.id = v_rowid;

And similarly for all the other attributes you set.

/*.....more cells added here......*/
var CellPostcode = row.insertCell(4);
CellPostcode.setAttribute("nowrap","");
var CellPostcodeTekst = document.createElement("input");
var Anchornode = document.createElement("a");
Anchornode.setAttribute("href","javascript:call_zo ekgemeente_byID(\''p_plaats_sys_vest"
+ v_rowid + "\'',\''p_postcode_vest" + v_rowid +
"\'',\''p_gemeente_vest" + v_rowid + "\'')");
var Imagenode = document.createElement("img");
Imagenode.setAttribute("src","/images/list.gif");
Imagenode.setAttribute("border","0");
CellPostcodeTekst.setAttribute("type","text");
CellPostcodeTekst.setAttribute("name","p_postcode_ vest_tmp");
CellPostcodeTekst.setAttribute("id","p_postcode_ve st" +
v_rowid);
Imagenode.src = "/images/list.gif";

// Set all border attributes in one go
Imagenode.style.border = '2px solid red';

// Or just the width:
Imagenode.style.borderWidth = '0px';

CellPostcodeTekst.type = "text";
CellPostcodeTekst.name = "p_postcode_vest_tmp";
CellPostcodeTekst.id = "p_postcode_vest" + v_rowid;
...
CellPostcodeTekst.setAttribute("size","3");
CellPostcodeTekst.setAttribute("value",p_postcode_ vest);
//troubles CellPostcodeTekst.setAttribute("onblur","call_zoek gemeente_byID(\''p_plaats_sys_vest"
+ v_rowid + "\'',\''p_postcode_vest" + v_rowid +
"\'',\''p_gemeente_vest" + v_rowid + "\'')");
Untested, but you can attach functions to intrinsic events thusly:

CellPostcodeTekst.onblur = function (){
call_zoekgemeente_byID('p_plaats_sys_vest' + v_rowid,
'p_postcode_vest' + v_rowid,
'p_gemeente_vest' + v_rowid )
};

This way you have access to the variables created in the rest of your
script.
CellPostcode.appendChild(CellPostcodeTekst);
Anchornode.appendChild(Imagenode);
CellPostcode.appendChild(Anchornode);

//Cell gemeente
var Cellgemeente = row.insertCell(5);
var CellgemeenteTekst = document.createElement("input");
CellgemeenteTekst.setAttribute("type","text");
CellgemeenteTekst.setAttribute("name","p_gemeente_ vest_tmp");
CellgemeenteTekst.setAttribute("id","p_gemeente_ve st" +
v_rowid);
CellgemeenteTekst.setAttribute("size","20");
CellgemeenteTekst.setAttribute("value",p_gemeente_ vest);
CellgemeenteTekst.setAttribute("READONLY","true"); //troubles
CellgemeenteTekst.readOnly = true;
var Cellplaatshidden = document.createElement("hidden");
Cellplaatshidden.setAttribute("type","hidden"); [...]
anyone have a clue?


Hope that helps.
--
Rob
Jul 23 '05 #3

P: n/a
Thomas wrote:
I'm having a problem with the dynamically created inputfields in
Internet Explorer.


Just thought I'd add another setAttribute gotcha. If you want to use it
to set the class of an element, Mozilla expects the attribute to be
called "class" and IE expects it to be called "className"; Opera accepts
either value.

--
Steve

Every gun that is made, every warship launched, every rocket fired
signifies, in the final sense, a theft from those who hunger and are not
fed, those who are cold and are not clothed. -Dwight D. Eisenhower
Jul 23 '05 #4

P: n/a
>
Untested, but you can attach functions to intrinsic events thusly:

CellPostcodeTekst.onblur = function (){
call_zoekgemeente_byID('p_plaats_sys_vest' + v_rowid,
'p_postcode_vest' + v_rowid,
'p_gemeente_vest' + v_rowid )
};

This way you have access to the variables created in the rest of your
script.


Hope that helps.


This sure helps me a lot! Thank you for your time and answers. But I
have a new problem now: The variable v_rowid always has the newest
value it was assigned, so the last row is always chosen. :s
Can I add parameters to the function so it always works?
Jul 23 '05 #5

P: n/a
Thomas wrote:
Untested, but you can attach functions to intrinsic events thusly:

CellPostcodeTekst.onblur = function (){
call_zoekgemeente_byID('p_plaats_sys_vest' + v_rowid,
'p_postcode_vest' + v_rowid,
'p_gemeente_vest' + v_rowid )
};

This way you have access to the variables created in the rest of your
script.
Hope that helps.

This sure helps me a lot! Thank you for your time and answers. But I
have a new problem now: The variable v_rowid always has the newest
value it was assigned, so the last row is always chosen. :s
Can I add parameters to the function so it always works?


Ah, I suspect this is an issue with closure - because the onblur
function still references the variable v_rowid, it stays in existence
even though it was created in the script. When the onblur runs, it
references the existing value, not what it was when the onblur was
created.

If I knew enough about these things I'd probably rabbit on about
scope chains and how to break them, but I don't. I can think of a
few kludgey was to get around it, but I'm sure there's an elegant
solution (and an explanation that will help both our understanding
of the issue) is RC lurking?

Following is a bit of play code as an example of the specific issue.
It adds 5 rows to a table, generating a row id as it goes. The row
id becomes static, but a reference to the same variable from the
onclick function stays dynamic.

Adding multiple sets of rows creates multiple instances of the
persistent variable 'i' - indicating that the lack of closure is also
eating memory - or am I totally off the track?
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<title> Dynamic ID </title>
<meta http-equiv="Content-Type"
content="text/html; charset=ISO-8859-1">

<script type="text/javascript">
function addRows(t){
var cell, i, row, rowId;
for ( i=0; i<5; i++ ){
row = t.insertRow(t.rows.length-1);
row.id = 'row-' + i;
row.onclick = function () {
alert('row-' + i + '\n' + this.id);
};
cell = document.createElement('td');
cell.appendChild(document.createTextNode(i))
row.appendChild(cell);
}
}
</script>
</head>
<body>

<table border="1">
<tbody id="tbodyA">
<tr>
<td onclick="addRows(document.getElementById('tbodyA') );">
Click me to add rows
</td>
</tr>
</tbody>
</table>
</body>
</html>
--
Rob
Jul 23 '05 #6

P: n/a
Thomas wrote:
Untested, but you can attach functions to intrinsic events thusly:

CellPostcodeTekst.onblur = function (){
call_zoekgemeente_byID('p_plaats_sys_vest' + v_rowid,
'p_postcode_vest' + v_rowid,
'p_gemeente_vest' + v_rowid )
};

This way you have access to the variables created in the rest of your
script.
Hope that helps.

This sure helps me a lot! Thank you for your time and answers. But I
have a new problem now: The variable v_rowid always has the newest
value it was assigned, so the last row is always chosen. :s
Can I add parameters to the function so it always works?


I was hoping someone could explain things better, ah well.

Anyhow, the way to break the scope chain is to have the onclick added
by an external function, not an internal one. My post above provides
code to demonstrate the issue, below is a modified version that fixes
it (tested: Firefox, IE).

The trick is to pass values to another function and add the onclick
from there. My guess is that this breaks the chain back to 'i' and
so its literal value is used for the onclick, not the variable
reference.

At the bottom I have added what I think will work for your case.

/******** Demo fix *****************/

<script type="text/javascript">
function addRows(t){
var cell, row, rowId,
i = t.rows.length,
j = i + 5;
for ( ; i<j; i++ ){
row = t.insertRow(i);
row.id = 'row-' + i;
addClick(row,i);
cell = document.createElement('td');
cell.appendChild(document.createTextNode(i))
row.appendChild(cell);
}
}

function addClick(x,y){
x.onclick = function() {
alert('this.id: ' + this.id + '\nstatic value: row-' + y)};
}
</script>

/******** Your fix *****************/

function .... {
...

addOnBlur(CellPostcodeTekst,
'p_plaats_sys_vest' + v_rowid,
'p_postcode_vest' + v_rowid,
'p_gemeente_vest' + v_rowid );

...
}

// Outside the above function
function addOnBlur(PostcodeTekst, plaats_sys, postcode, gemeente){
PostcodeTekst.onblur = function (){
call_zoekgemeente_byID( plaats_sys, postcode, gemeente )
};
}

Hope that does the trick (untested of course!).
--
Rob
Jul 23 '05 #7

This discussion thread is closed

Replies have been disabled for this discussion.