473,698 Members | 2,158 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Problems with dynamically adding events to new DOM objects

I am trying to add an event listener to the keyup event for some text
inputs that I am creating dynamically. I have no problems getting it
to work in Firefox, but IE just ignores them. I have created a few
functions to aid in making this process work semi-cross-browser. (I
develop in FF, but everyone who uses it will be using IE6.)

function attachEvent(_ob j, _evt, _fnc) {
_evt = _evt.toLowerCas e();

if (_obj.attachEve nt) {
_obj.attachEven t('on' + _evt, _fnc);
} else {
eval('_obj.on' + _evt + ' = ' + _fnc);
}
}

function generateFunctio n(_name, _params) {
var func;
if (navigator.user Agent.toLowerCa se().indexOf('g ecko') != -1) {
func = eval('function( ){' + _name + '(' + _params + ');}');
} else {
func = function(){eval (_name + '(' + _params + ')');};
}
return func;
}

function attachValidator (_obj, _validatorName) {
if (navigator.user Agent.toLowerCa se().indexOf('g ecko') != -1) {
attachEvent(_ob j, 'keyup', generateFunctio n(_validatorNam e, 'this'));
} else {
var eventAttr = document.create Attribute('onke yup');
eventAttr.value = _validatorName + '(this);';
_obj.setAttribu teNode(eventAtt r);
}
}

function createTextField (_base, _id, _value, _validatorName, _class) {
var input = document.create Element('input' );
var inputID = document.create Attribute('id') ;
inputID.value = _base + _id;
var inputType = document.create Attribute('type ');
inputType.value = 'text';
var inputValue = document.create Attribute('valu e');
inputValue.valu e = _value;

input.setAttrib uteNode(inputID );
input.setAttrib uteNode(inputTy pe);
input.setAttrib uteNode(inputVa lue);

if (_validatorName ) {
attachValidator (input, _validatorName) ;
//attachEvent(inp ut, 'keyup', generateFunctio n(_validatorNam e,
'this'));
}

if (_class) {
var inputClass = document.create Attribute('clas s');
inputClass.valu e = _class;

input.setAttrib uteNode(inputCl ass);
}

return input;
}

Sorry about the browser sniffing using the userAgent string, but since
I am the only non-IE6 user in the building, it shouldn't really matter
in the long run.

Thanks in advance,

Chris

Jun 23 '06 #1
5 2246
"Chris Lieb" <ch********@gma il.com> writes:
I am trying to add an event listener to the keyup event for some text
inputs that I am creating dynamically. I have no problems getting it
to work in Firefox, but IE just ignores them.
Let's quote out of context:
function attachValidator (_obj, _validatorName) {
if (navigator.user Agent.toLowerCa se().indexOf('g ecko') != -1) {
attachEvent(_ob j, 'keyup', generateFunctio n(_validatorNam e, 'this'));
} else {
var eventAttr = document.create Attribute('onke yup');
eventAttr.value = _validatorName + '(this);';
_obj.setAttribu teNode(eventAtt r);
}
}
So, Gecko based browsers take the first branch and IE will take the
second. If they act differently, this is as good a place to look as
any.

Indeed it seems the second branch doesn't work in IE.

Since the attachEvent function is also written to work in more
than one setting, it looks like an error that you only call it
for Gecko browsers.
When working with HTML it's better to use the HTML DOM properties
(e.g., obj.href) instead of Core DOM attribute methodes (e.g.,
obj.setAttribut e). IE, for one, often doesn't react to changes
to Core DOM attributes.
I have created a few functions to aid in making this process work
semi-cross-browser. (I develop in FF, but everyone who uses it will
be using IE6.)
Some suggestions (mostly about how to avoid "eval", which only
complicates your life):
function attachEvent(_ob j, _evt, _fnc) {
Try:
function attachEvent(_ob j, _evt, _fnc) {
_evt = _evt.toLowerCas e();
if (_obj.addEventH andler) {
_obj.addEventHa ndler(_evt, _fnc, false);
} else if (_obj.attachEve nt) {
_obj.attachEven t("on" + _evt, fnc);
} else {
_obj["on" + _evt] = fnc;
}
}
function generateFunctio n(_name, _params) {
I guess this function's job is to create a function that calls another
with specified arguments. It's safer to pass the actual function than
just its name:

function bindParameter(_ func, _params) {
_func.apply(thi s,_params)
}
var func;
if (navigator.user Agent.toLowerCa se().indexOf('g ecko') != -1) {
func = eval('function( ){' + _name + '(' + _params + ');}');
} else {
func = function(){eval (_name + '(' + _params + ')');};
}
Why this difference? I can't see any feature that IE and Gecko would
do differently in either branch.
return func;
}
function attachValidator (_obj, _validatorName) {
function attachValidator (_obj, _validatorFunc) {
attachEvent(_ob j, "keyup", bindParams(_val idatorFunc, _obj));
}

function createTextField (_base, _id, _value, _validatorName, _class) {


Here also pass a validator function, not its name.

I.e., something like:
createTextField (..,..,.., function(_obj){ return _obj.value!=""; }, ...);
(or use a function defined somewhere else).

/L
--
Lasse Reichstein Nielsen - lr*@hotpop.com
DHTML Death Colors: <URL:http://www.infimum.dk/HTML/rasterTriangleD OM.html>
'Faith without judgement merely degrades the spirit divine.'
Jun 23 '06 #2

Lasse Reichstein Nielsen wrote:
"Chris Lieb" <ch********@gma il.com> writes:
I am trying to add an event listener to the keyup event for some text
inputs that I am creating dynamically. I have no problems getting it
to work in Firefox, but IE just ignores them.
Let's quote out of context:
function attachValidator (_obj, _validatorName) {
if (navigator.user Agent.toLowerCa se().indexOf('g ecko') != -1) {
attachEvent(_ob j, 'keyup', generateFunctio n(_validatorNam e, 'this'));
} else {
var eventAttr = document.create Attribute('onke yup');
eventAttr.value = _validatorName + '(this);';
_obj.setAttribu teNode(eventAtt r);
}
}


So, Gecko based browsers take the first branch and IE will take the
second. If they act differently, this is as good a place to look as
any.

Indeed it seems the second branch doesn't work in IE.

Since the attachEvent function is also written to work in more
than one setting, it looks like an error that you only call it
for Gecko browsers.


The code that is in there for IE does not use the attachEvent method
because I had apready determined that the attachEvent function was not
achieving what I wanted.
When working with HTML it's better to use the HTML DOM properties
(e.g., obj.href) instead of Core DOM attribute methodes (e.g.,
obj.setAttribut e). IE, for one, often doesn't react to changes
to Core DOM attributes.
I have created a few functions to aid in making this process work
semi-cross-browser. (I develop in FF, but everyone who uses it will
be using IE6.)
Some suggestions (mostly about how to avoid "eval", which only
complicates your life):
function attachEvent(_ob j, _evt, _fnc) {


Try:
function attachEvent(_ob j, _evt, _fnc) {
_evt = _evt.toLowerCas e();
if (_obj.addEventH andler) {
_obj.addEventHa ndler(_evt, _fnc, false);
} else if (_obj.attachEve nt) {
_obj.attachEven t("on" + _evt, fnc);
} else {
_obj["on" + _evt] = fnc;
}
}
function generateFunctio n(_name, _params) {


I guess this function's job is to create a function that calls another
with specified arguments. It's safer to pass the actual function than
just its name:

function bindParameter(_ func, _params) {
_func.apply(thi s,_params)
}


I've never seen the apply function before. I looked it up in the
Mozilla Developer docs, but I don't understand how this works or how
the bindParameter function would be used comared to the previous
generateFunctio n function.
var func;
if (navigator.user Agent.toLowerCa se().indexOf('g ecko') != -1) {
func = eval('function( ){' + _name + '(' + _params + ');}');
} else {
func = function(){eval (_name + '(' + _params + ')');};
}


Why this difference? I can't see any feature that IE and Gecko would
do differently in either branch.
return func;
}
For some reason, IE choked on creating an anonymous function using eval
and FF evaluated the IE version correctly, meaning that an anonymous
function was created whose body was eval(_name + '(' + _params + ')');
This did not work in FF because the _name and _params variables had
gone out of scope by the time that the function was invoked.

function attachValidator (_obj, _validatorName) {


function attachValidator (_obj, _validatorFunc) {
attachEvent(_ob j, "keyup", bindParams(_val idatorFunc, _obj));
}

function createTextField (_base, _id, _value, _validatorName, _class) {


Here also pass a validator function, not its name.

I.e., something like:
createTextField (..,..,.., function(_obj){ return _obj.value!=""; }, ...);
(or use a function defined somewhere else).


I thought that events did not pass any parameters. If this is so,
where is this anonymous function (the one passed to createTextField in
the above example) getting the _obj parameter from?
/L
Thanks for the help, but I am slightly confused by some of the things
that you proposed, such as the bindParam function. Could you please
clarify them?

Chris
--
Lasse Reichstein Nielsen - lr*@hotpop.com
DHTML Death Colors: <URL:http://www.infimum.dk/HTML/rasterTriangleD OM.html>
'Faith without judgement merely degrades the spirit divine.'


Jun 23 '06 #3
Chris Lieb wrote:
I am trying to add an event listener to the keyup event for some text
inputs that I am creating dynamically. I have no problems getting it
to work in Firefox, but IE just ignores them. I have created a few
functions to aid in making this process work semi-cross-browser. (I
develop in FF, but everyone who uses it will be using IE6.)

[...]

Aren't you making this much more difficult than it should be? Why
can't you just use:

function createTextField (_base, _id, _value, _validatorName, _class)
{
var oInput = document.create Element('input' );
oInput.type = 'text';
oInput.id = _base + _id;
oInput.value = _value;

if ( _validatorName) {
oInput.onkeyup = _validatorName;
}

/* Assuming 'class' is in regard to style, not JScript 'class' */
if (_class && 'string' == typeof _class){
oInput.classNam e = _class;
}

return oInput;
}
Within whatever function is attached to the input, 'this' will refer to
the input that called the function, so if you had:

function showID(){ alert(this.id); }

Then do:

document.body.a ppendChild(
createTextField ( 'foo', 'bar', 'foey', showID, 'brightRed'));
Then you should see a new text input with a value of 'foey' and
displays 'foobar' onkeyup - works in IE, Firefox & Safari at least. If
you want to add multiple functions to a particular handler (which is
rare for onkeyup), use your forking addEventListene r/attachEvent for
the _validator.

Sample below:

<html><title>Pl ay</title>

<style type="text/css">
.brightRed {
border: 2px solid red;
background-color: #fdd;
}
</style>

<script type="text/javascript">

function createTextField (_base, _id, _value, _validatorName, _class)
{
var oInput = document.create Element('input' );
oInput.type = 'text';
oInput.id = _base + _id;
oInput.value = _value;

if ( _validatorName) {
oInput.onkeyup = _validatorName;
}

/* Assuming 'class' is in regard to style, not JScript 'class' */
if (_class && 'string' == typeof _class){
oInput.classNam e = _class;
}

return oInput;
}

function showID(){ alert(this.id); }

window.onload = function()
{
document.body.a ppendChild(
createTextField ( 'foo', 'bar', 'foey', showID, 'brightRed'));
};

</script>
</html>
--
Rob

Jun 24 '06 #4
"Chris Lieb" <ch********@gma il.com> writes:
Lasse Reichstein Nielsen wrote: The code that is in there for IE does not use the attachEvent method
because I had apready determined that the attachEvent function was not
achieving what I wanted.
Sine no other browser has an attachEvent function (well, maybe some
does by now, but it's a proprietary IE feature), you can safely remove
that code.

function bindParameter(_ func, _params) {
_func.apply(thi s,_params)
}


I've never seen the apply function before. I looked it up in the
Mozilla Developer docs, but I don't understand how this works or how
the bindParameter function would be used comared to the previous
generateFunctio n function.


Well, since I forgot something, it's not odd that you don't understand
what it does :)

The bind function should ofcourse return a function, so it should be:

function bindParameter(_ func, _params) {
return function() {
_func.apply(thi s,_params)
};
}

What it now does is to return a function that, when called, calls
the _func function with the parameters in the array _params.

The .apply method on function values calls the function as a method
of the object in the first argument and with the parameters in the
array in the second argument.

There is a similar method, "call", that expects the parameters
directly, not as an array.

So, if o is an object, then the following performs the same calls:

o.foo = myFunc;
o.foo(a,b,c)
and
myFunc.call(o,a ,b,c)
and
myFunc.apply(o,[a,b,c])
For some reason, IE choked on creating an anonymous function using eval
and FF evaluated the IE version correctly, meaning that an anonymous
function was created whose body was eval(_name + '(' + _params + ')');
This did not work in FF because the _name and _params variables had
gone out of scope by the time that the function was invoked.
The fragility of eval is one of the reasons it's not recommended.
You have to be very careful when you build source strings for eval,
and it's generally not worth it.
Javascript allows you to pass values around, even function values,
so it's unlikely that you ever need to pass around names of
functions or strings representing values.
Thanks for the help, but I am slightly confused by some of the things
that you proposed, such as the bindParam function. Could you please
clarify them?


Generally, don't use eval.
If you need to call an unknown function in some code, don't pass its
name and look it up, just pass the function directly.

If you want to add an event handler, the W3C DOM method is addEventHandler ,
IE's metod is attachEvent (which doesn't bind "this" to the attachee when
it executes the function), and the generic fallback is object.onevent
(i.e., object['on'+_evt]), which can only accept one handler per event
type).

Be carefull with using setAttribute on HTML elements, since some browsers,
most notably IE, will not make them take effect the same way assigning
to the W3C HTML DOM properties does (e.g., _obj.style.widt h='4px',
_link.href='foo .html').

/L
--
Lasse Reichstein Nielsen - lr*@hotpop.com
DHTML Death Colors: <URL:http://www.infimum.dk/HTML/rasterTriangleD OM.html>
'Faith without judgement merely degrades the spirit divine.'
Jun 24 '06 #5

Lasse Reichstein Nielsen wrote:
"Chris Lieb" <ch********@gma il.com> writes:
Lasse Reichstein Nielsen wrote:

The code that is in there for IE does not use the attachEvent method
because I had apready determined that the attachEvent function was not
achieving what I wanted.


Sine no other browser has an attachEvent function (well, maybe some
does by now, but it's a proprietary IE feature), you can safely remove
that code.

function bindParameter(_ func, _params) {
_func.apply(thi s,_params)
}


I've never seen the apply function before. I looked it up in the
Mozilla Developer docs, but I don't understand how this works or how
the bindParameter function would be used comared to the previous
generateFunctio n function.


Well, since I forgot something, it's not odd that you don't understand
what it does :)

The bind function should ofcourse return a function, so it should be:

function bindParameter(_ func, _params) {
return function() {
_func.apply(thi s,_params)
};
}

What it now does is to return a function that, when called, calls
the _func function with the parameters in the array _params.

The .apply method on function values calls the function as a method
of the object in the first argument and with the parameters in the
array in the second argument.

There is a similar method, "call", that expects the parameters
directly, not as an array.

So, if o is an object, then the following performs the same calls:

o.foo = myFunc;
o.foo(a,b,c)
and
myFunc.call(o,a ,b,c)
and
myFunc.apply(o,[a,b,c])
For some reason, IE choked on creating an anonymous function using eval
and FF evaluated the IE version correctly, meaning that an anonymous
function was created whose body was eval(_name + '(' + _params + ')');
This did not work in FF because the _name and _params variables had
gone out of scope by the time that the function was invoked.


The fragility of eval is one of the reasons it's not recommended.
You have to be very careful when you build source strings for eval,
and it's generally not worth it.
Javascript allows you to pass values around, even function values,
so it's unlikely that you ever need to pass around names of
functions or strings representing values.
Thanks for the help, but I am slightly confused by some of the things
that you proposed, such as the bindParam function. Could you please
clarify them?


Generally, don't use eval.
If you need to call an unknown function in some code, don't pass its
name and look it up, just pass the function directly.

If you want to add an event handler, the W3C DOM method is addEventHandler ,
IE's metod is attachEvent (which doesn't bind "this" to the attachee when
it executes the function), and the generic fallback is object.onevent
(i.e., object['on'+_evt]), which can only accept one handler per event
type).

Be carefull with using setAttribute on HTML elements, since some browsers,
most notably IE, will not make them take effect the same way assigning
to the W3C HTML DOM properties does (e.g., _obj.style.widt h='4px',
_link.href='foo .html').

/L
--
Lasse Reichstein Nielsen - lr*@hotpop.com
DHTML Death Colors: <URL:http://www.infimum.dk/HTML/rasterTriangleD OM.html>
'Faith without judgement merely degrades the spirit divine.'


Thanks. That bindParam function has everything working in both FF and
IE.

Chris

Jun 26 '06 #6

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

6
3323
by: Thomas | last post by:
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:
11
2289
by: Steven D'Aprano | last post by:
Suppose I create a class with some methods: py> class C: .... def spam(self, x): .... print "spam " * x .... def ham(self, x): .... print "ham * %s" % x .... py> C().spam(3) spam spam spam
8
4312
by: Donald Xie | last post by:
Hi, I noticed an interesting effect when working with controls that are dynamically loaded. For instance, on a web form with a PlaceHolder control named ImageHolder, I dynamically add an image button at runtime: //----- Code snippet protected System.Web.UI.WebControls.PlaceHolder ImageHolder; private void Page_Load(object sender, System.EventArgs e)
2
2226
by: JezB | last post by:
I'm adding WebControl objects to a Page dynamically on Page_Load, but I'm having trouble attaching events to these. For example, adding an image button :- ImageButton nb = new ImageButton(); nb.ImageUrl = "text.gif"; nb.ToolTip = "Edit Text"; nb.Click += new ImageClickEventHandler(b1_Click); myPlaceholder.Controls.Add(nb);
1
1407
by: bill | last post by:
I'm using VS2005. I am dynamically adding a Textbox control to a Placeholder control in the page_load event of the form, but the event handler isn't firing. What am I doing wrong? Thanks Bill
7
2528
by: Ron Goral | last post by:
Hello I am new to creating objects in javascript, so please no flames about my coding style. =) I am trying to create an object that will represent a "div" element as a menu. I have written several methods that are working fine. The problem is if I want to dynamically assign an event handler to the object, the event handler is not called. What am I doing wrong? Below is a sample HTML doc with everything in place. <!DOCTYPE HTML PUBLIC...
9
7925
by: Chris | last post by:
I am dynamically adding a user control to each row in a gridview. The reason I am doing it dynamically is the user control is different depending on certain data in the gridview. The gridview contains a placeholder and I add the control to it, the user control is a formview bound to an object datsource. This works great until I post back the page and the user control disappears. What am I doing wrong? Regards, Chris. Protected Sub...
3
1399
by: yovalk | last post by:
Hello, I have the following problem, I think it is rather simple, but hard to describe: I created a simple user control which contains a check box and an image - CheckBoxImage. Then I createa a control which contains and visually arranges CheckBoxImage controls in a table dynamically (it can contain diffrent numbers of ImageCheckBox)- CheckBoxImageContainer. The CheckBoxImage are added to the container dynamically. The problem is this:...
10
2710
by: Jess | last post by:
Hello, I have a program that stores dynamically created objects into a vector. #include<iostream> #include<vector> using namespace std;
0
8683
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main usage, and What is the difference between ONU and Router. Let’s take a closer look ! Part I. Meaning of...
0
9170
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. Here is my compilation command: g++-12 -std=c++20 -Wnarrowing bit_field.cpp Here is the code in...
0
7739
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then launch it, all on its own.... Now, this would greatly impact the work of software developers. The idea...
0
5862
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert into image. Globals.ThisAddIn.Application.ActiveDocument.Select();...
0
4371
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
0
4622
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
1
3052
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system
2
2336
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.
3
2007
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating effective websites that not only look great but also perform exceptionally well. In this comprehensive...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.