Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Javascript > How do I add to an onchange event?

Reply
Thread Tools

How do I add to an onchange event?

 
 
nimhyea@gmail.com
Guest
Posts: n/a
 
      01-14-2008
Hello I was wondering if it was possible to add to an already defined
onchange event without having to re-write it completely.

scenario:
<input type="hidden" name="blah" value="" onChange="alert('hello');">

<script ...>
// want to add "world" alert, but since I still want to see
"hello"...
document.getElementById("blah").onchange = function()
{alert("hello");alert("world");}
</script>

ideally I just want to concatenate like:
document.getElementById("blah").onchange += function()
{alert("world");}

and not worry about what was there, but then I get a javascript error.

Thanks for any help.
 
Reply With Quote
 
 
 
 
Doug Gunnoe
Guest
Posts: n/a
 
      01-14-2008
On Jan 14, 1:28*pm, nimh...@gmail.com wrote:
> Hello I was wondering if it was possible to add to an already defined
> onchange event without having to re-write it completely.
>
> scenario:
> <input type="hidden" name="blah" value="" onChange="alert('hello');">
>
> <script ...>
> * // want to add "world" alert, but since I still want to see
> "hello"...
> * document.getElementById("blah").onchange = function()
> {alert("hello");alert("world");}
> </script>
>
> ideally I just want to concatenate like:
> * document.getElementById("blah").onchange += function()
> {alert("world");}
>
> and not worry about what was there, but then I get a javascript error.
>
> Thanks for any help.


Interesting. So I tried it just to see what would happen.

First I tried something similar to what you tried.

<html>
<head>
<script>
function dodo(){
alert('world');
}
function doStuff(){
var btn = document.getElementById('btn1');
btn.onclick += "dodo();"
alert(btn.onclick);
}
</script>
</head>
<body>
<input id='btn1' type="button" onclick="alert('hello');" value="click
me"/>
<br>
<input type="button" onclick="doStuff()" value="click me 1st" />
</body>
</html>

And I get this when the doStuff function runs:

http://polisick.com/test1.png

And it is obvious that will not work, right?

So when I just did this,

<input id='btn1' type="button" onclick="alert('hello');dodo();"
value="click me"/>

Then 'dodo()' is inside the anonymous function like so.

http://polisick.com/test2.png

And I guess the one you did would just be showing something like:

function anonymous(){
alert('hello');
}function(){alert('world')}

So I guess you could do some string manipulation and get that
alert('world') inside the anonymous function. Otherwise, someone else
might have a better idea.
 
Reply With Quote
 
 
 
 
Thomas 'PointedEars' Lahn
Guest
Posts: n/a
 
      01-14-2008
wrote:
> Hello I was wondering if it was possible to add to an already defined
> onchange event without having to re-write it completely.
>
> scenario:
> <input type="hidden" name="blah" value="" onChange="alert('hello');">


Since this element cannot be edited by the user, and so the `change' event
will never occur for it, the `onChange' attribute (which should be
`onchange') does not make sense here.

That aside:

> <script ...>
> // want to add "world" alert, but since I still want to see
> "hello"...
> document.getElementById("blah").onchange = function()
> {alert("hello");alert("world");}
> </script>
>
> ideally I just want to concatenate like:
> document.getElementById("blah").onchange += function()
> {alert("world");}


Features of the W3C-DOM and DOM Level 0 should not be combined untested;
always avoid such reference worms. Besides, your element has a name, not an
ID. Only MSHTML is this buggy to not care about that difference.

> and not worry about what was there, but then I get a javascript error.


Of course, although "a javascript error" is hardly a viable error
description: http://www.jibbering.com/faq/faq_not...ml#ps1DontWork

First, probably you have been trying to access properties of a non-object
that document.getElementById() returns here.

Second, you have been trying to concatenate (Function) object references; in
the best case you have been trying to assign the equivalent of

document.getElementById("blah").onchange = NaN;

as the Function objects were converted to their Number representations in
the script engine's attempt to satisfy your nonsensical demand.

As for the latter, you were looking for something along the following instead:

var _global = this, f = obj.onchange;

obj.onchange = function(e)
{
if (!e)
{
e = (typeof _global.window != "undefined"
&& typeof window.event != "undefined"
&& window.event);
}

if (f)
{
f(e);
}

// arbitrary additional code
window.alert("world");
};

// break circular reference to avoid memory leaks in IE
obj = null;

I have implemented this approach in the current version of
_addEventListener() (or dhtml.addEventListener()) in
http://PointedEars.de/scripts/dhtml.js as an alternative to MSHTML's buggy
attachEvent() where EventTarget::addEventListener() from W3C DOM Level 2
Events is not available. Comments are welcome.


PointedEars
--
var bugRiddenCrashPronePieceOfJunk = (
navigator.userAgent.indexOf('MSIE 5') != -1
&& navigator.userAgent.indexOf('Mac') != -1
) // Plone, register_function.js:16
 
Reply With Quote
 
Doug Gunnoe
Guest
Posts: n/a
 
      01-14-2008
On Jan 14, 1:28*pm, nimh...@gmail.com wrote:
> Hello I was wondering if it was possible to add to an already defined
> onchange event without having to re-write it completely.
>
> scenario:
> <input type="hidden" name="blah" value="" onChange="alert('hello');">
>
> <script ...>
> * // want to add "world" alert, but since I still want to see
> "hello"...
> * document.getElementById("blah").onchange = function()
> {alert("hello");alert("world");}
> </script>
>
> ideally I just want to concatenate like:
> * document.getElementById("blah").onchange += function()
> {alert("world");}
>
> and not worry about what was there, but then I get a javascript error.
>
> Thanks for any help.


I messed around with this some more.
The following worked on IE 6. I did not try it on anything else.

<html>
<head>
<script>
function dodo(){
alert('world');
}
function doStuff(){
var btn = document.getElementById('btn1');
var str = btn.onclick;
str = str + '';
str = str.substring(str.indexOf('{') + 1, str.indexOf('}'));
btn.onclick = new Function(str + "dodo();");
}
</script>
</head>
<body>
<input type="button" id="btn1" value="click me"
onclick="alert('hello');" />
<input type="button" value="click me 1st" onclick="doStuff()" />
</body>
</html>

 
Reply With Quote
 
SAM
Guest
Posts: n/a
 
      01-15-2008
a écrit :
> Hello I was wondering if it was possible to add to an already defined
> onchange event without having to re-write it completely.
>
> scenario:
> <input type="hidden" name="blah" value="" onChange="alert('hello');">


Here you'll need id="blah"
if you use getElementById

> <script ...>
> // want to add "world" alert, but since I still want to see
> "hello"...
> document.getElementById("blah").onchange = function()
> {alert("hello");alert("world");}
> </script>
>
> ideally I just want to concatenate like:
> document.getElementById("blah").onchange += function()
> {alert("world");}


If the problem was to get alert('Hello World)

document.getElementById("blah").onchange = function() {
alert('Hello World');}

If you want to do what you tell, use the addEvent function
(IE + others browsers) :

function addEvent( obj, type, fn ) {
if ( obj.attachEvent ) {
obj['e'+type+fn] = fn;
obj[type+fn] = function(){obj['e'+type+fn]( window.event );}
obj.attachEvent( 'on'+type, obj[type+fn] );
} else
obj.addEventListener( type, fn, false );
}

addEvent(document.getElementById("blah"), 'change',
function(){alert("world");});


nota: that doesn't work with IE Mac nor NC4

Not sure that onchange works with an hidden field... ?
--
sm
 
Reply With Quote
 
AKS
Guest
Posts: n/a
 
      01-15-2008
On Jan 15, 1:27 am, Thomas 'PointedEars' Lahn <PointedE...@web.de>
wrote:

> I have implemented this approach in the current version of
> _addEventListener() (or dhtml.addEventListener()) inhttp://PointedEars.de/scripts/dhtml.jsas an alternative to MSHTML's buggy
> attachEvent() where EventTarget::addEventListener() from W3C DOM Level 2
> Events is not available. Comments are welcome.



result = (o[sHandler] == fListener);

-result- will always be false, but logically it must be true.

 
Reply With Quote
 
Thomas 'PointedEars' Lahn
Guest
Posts: n/a
 
      01-15-2008
AKS wrote:
> On Jan 15, 1:27 am, Thomas 'PointedEars' Lahn <PointedE...@web.de>
> wrote:
>> I have implemented this approach in the current version of
>> _addEventListener() (or dhtml.addEventListener()) inhttp://PointedEars.de/scripts/dhtml.jsas an alternative to MSHTML's buggy
>> attachEvent() where EventTarget::addEventListener() from W3C DOM Level 2
>> Events is not available. Comments are welcome.

>
> result = (o[sHandler] == fListener);
>
> -result- will always be false, but logically it must be true.


Thanks. You are correct; that was a relic from the previous version. Fixed
with

var oldListener = o["on" + sEvent];
var newListener = function(e)
{
if (!e)
{
e = (typeof _global.window != "undefined"
&& typeof window.event != "undefined"
&& window.event);
}

if (oldListener)
{
oldListener(e);
}

fListener(e);
};

o[sHandler] = newListener;

result = (o[sHandler] == newListener);


PointedEars
--
var bugRiddenCrashPronePieceOfJunk = (
navigator.userAgent.indexOf('MSIE 5') != -1
&& navigator.userAgent.indexOf('Mac') != -1
) // Plone, register_function.js:16
 
Reply With Quote
 
Thomas 'PointedEars' Lahn
Guest
Posts: n/a
 
      01-15-2008
Randy Webb wrote:
> Thomas 'PointedEars' Lahn said the following on 1/14/2008 3:27 PM:
>> wrote:
>>> Hello I was wondering if it was possible to add to an already defined
>>> onchange event without having to re-write it completely.
>>>
>>> scenario:
>>> <input type="hidden" name="blah" value="" onChange="alert('hello');">

>> Since this element cannot be edited by the user, and so the `change' event
>> will never occur for it, the `onChange' attribute (which should be
>> `onchange') does not make sense here.

>
> Nonsense. It can be ONCHANGE, onChange, onchange, ONChange, or any other
> capitalization you prefer. HTML is not case-sensitive.


That is oversimplified. HTML *attribute names* are case-insensitive.[1]
There are the following -- I think valid -- reasons for my recommendation:

1. Consistent markup.
2. Lowercase text compresses better.
3. Reusing the code will be easier.

YMMV.


PointedEars
___________
[1] http://www.w3.org/TR/html401/types.html#h-6.1
--
var bugRiddenCrashPronePieceOfJunk = (
navigator.userAgent.indexOf('MSIE 5') != -1
&& navigator.userAgent.indexOf('Mac') != -1
) // Plone, register_function.js:16
 
Reply With Quote
 
David Mark
Guest
Posts: n/a
 
      01-15-2008
On Jan 15, 9:16*am, Thomas 'PointedEars' Lahn <PointedE...@web.de>
wrote:
> AKS wrote:
> > On Jan 15, 1:27 am, Thomas 'PointedEars' Lahn <PointedE...@web.de>
> > wrote:
> >> I have implemented this approach in the current version of
> >> _addEventListener() (or dhtml.addEventListener()) inhttp://PointedEars.de/scripts/dhtml.jsasan alternative to MSHTML's buggy
> >> attachEvent() where EventTarget::addEventListener() from W3C DOM Level 2
> >> Events is not available. *Comments are welcome.

>
> > result = (o[sHandler] == fListener);

>
> > -result- will always be false, but logically it must be true.

>
> Thanks. *You are correct; that was a relic from the previous version. *Fixed
> with
>
> * * * var oldListener = o["on" + sEvent];
> * * * var newListener = function(e)
> * * * {
> * * * * if (!e)
> * * * * {
> * * * * * e = (typeof _global.window != "undefined"
> * * * * * * * *&& typeof window.event != "undefined"
> * * * * * * * *&& window.event);
> * * * * }
>


If either of the first two tests fail, e will go from undefined to
false. Also, you first check if window is a property of the Global
Object, then turn right around and refer to the same identifier
implicitly.

This would seem sufficient:

e = e || window.event;

Or if you want to be more explicit:

if (!e && _global.window) {
e = _global.window.event;
}

It is hard to imagine an implementation that would throw an exception
on [[Get]] for the window object. Methods of this (or any host
object) are another story (as we have been over recently.)

Or if you must:

if (!e && typeof _global.window == 'object' && _global.window) {
e = _global.window.event;
}

Or to be really paranoid about host object implementations:

if (!e && typeof _global.window != 'undefined') {
e = _global.window.event;
}

But show me one agent that returns anything other than "object" for
typeof window. If there is one that screwy, who is to say that it
wouldn't return a null value for window or throw a [[Get]] exception
on window.event? The fact that such an agent could exist in the
future is a good argument for encapsulating such tests in a central
function (as we have also been over recently.) Regardless, there is
no surefire way to know if a host object will throw an exception on
evaluation.

Either way, assuming no [[Get]] exceptions, e will be an event object
or undefined (but never false.) Personally, I would use the first
one, possibly checking for the existence of the window object prior to
creating the function (or assigning the global event property as
window and the Global Object share the same scope.) The second option
would be:

e = e || _global.event;

Unless you think that IE8 or newer will give window a different scope
than the Global object (obviously won't happen), then this is
sufficient. Here's hoping that IE8 does away with the ridiculous
global event object altogether.

This snippet appears to be part of a general solution, which should
take into account that elements passed may not reside in the same
frame. Also, expandos are always a bad idea. If you must use them,
you need to check the document.expando property first.

Looking at the file it came from, I see a few other problems.

if (typeof oScript.type != "undefined")
{
oScript.type = sType || "text/javascript";
}

if (typeof oScript.type != "undefined")
{
oScript.type = sType || "text/javascript";
}

That is clearly a copy and paste error.

if (isMethod(typeof aHeads[0].appendChild))

I assume this is a typo and isMethodType was meant.

// makes the method applicable to Document and Element objects
if (!o
&& typeof this.constructor != "undefined"
&& /Document|Element/.test(String(this.constructor)))
{
o = this;
}

You wouldn't augment host objects would you? Regardless, this is pure
evil.

Next line:

if (o && isMethod(typeof o.getElementsByTagName))

Same typo as before I assume.

if (typeof HTMLDocument != "undefined"
&& typeof HTMLDocument.prototype != "undefined")
{
HTMLDocument.prototype.getElementsByTabIndex =
getElementsByTabIndex;
}

if (typeof HTMLElement != "undefined"
&& typeof HTMLElement.prototype != "undefined")
{
HTMLElement.prototype.getElementsByTabIndex = getElementsByTabIndex;
}

OMG. No you didn't.

Your attribute alias map lists rowspan, but not colspan. Both get and
set attribute functions have problems. See the version proposed in
the CWR project. It needs to be revised as I recently fixed a couple
of problems, but it should indicate areas that you need to improve in
your code.

The get and set style property functions don't handle float properly.

The show function is roughly equivalent to Prototype's, which is to
say worthless.

The getParent function is ambiguous as parentNode and parentElement
are not equivalent.

The getAbsPos function is severely lacking. For one it completely
ignores borders.

This looks wrong:

if (typeof _global != "undefined")
{
var _global = this;
}

Perhaps you meant:

if (typeof _global == "undefined")

The test isn't needed anyway.

var dhtml = new DHTML();

Shouldn't this library be a singleton?

Overall, feature testing should be pulled out of the functions and the
repetitive comments should be trimmed. You should run it through
JSLint as minification is to be expected (nobody wants to download all
of those credits.)
 
Reply With Quote
 
Thomas 'PointedEars' Lahn
Guest
Posts: n/a
 
      01-17-2008
David Mark wrote:
> [...] Thomas 'PointedEars' Lahn [...] wrote:
> > AKS wrote:
> > > On Jan 15, 1:27 am, Thomas 'PointedEars' Lahn <PointedE...@web.de>
> > > wrote:
> > >> I have implemented this approach in the current version of
> > >> _addEventListener() (or dhtml.addEventListener()) inhttp://PointedEars.de/scripts/dhtml.jsasanalternative to MSHTML's buggy
> > >> attachEvent() where EventTarget::addEventListener() from W3C DOM Level 2
> > >> Events is not available. Comments are welcome.
> > >
> > > result = (o[sHandler] == fListener);

> >
> > > -result- will always be false, but logically it must be true.

> >
> > Thanks. You are correct; that was a relic from the previous version. Fixed
> > with
> >
> > var oldListener = o["on" + sEvent];
> > var newListener = function(e)
> > {
> > if (!e)
> > {
> > e = (typeof _global.window != "undefined"
> > && typeof window.event != "undefined"
> > && window.event);
> > }

>
> If either of the first two tests fail, e will go from undefined to
> false.


You are correct, but I don't think this will make a significant
difference. Both values evaluate to `false' in a boolean expression.

> Also, you first check if window is a property of the Global
> Object, then turn right around and refer to the same identifier
> implicitly.


True, the `_global.' is probably error-prone here. Fixed.

> This would seem sufficient:
>
> e = e || window.event;


It would not.

> Or if you want to be more explicit:
>
> if (!e && _global.window) {
> e = _global.window.event;
>
> }


That assumes that `window' would be a property of the Global Object
which, on second thought, does not need to be the case. I am unsure
as to whether to rely on the former or on the scope chain; I'll stick
with the latter for the time being.

> [...]
> But show me one agent that returns anything other than "object" for
> typeof window. If there is one that screwy, who is to say that it
> wouldn't return a null value for window


Good point, thanks. An additional type-converting test was necessary.

> or throw a [[Get]] exception on window.event?


There is no such thing as a [[Get]] exception. What are you aiming
at?

> [...]
> This snippet appears to be part of a general solution, which should
> take into account that elements passed may not reside in the same
> frame.


It is up to the caller to take that into account. If you have a
suggestion to make, then make it:

Talk is cheap. Show me the code. -- Linus Torvalds

> Also, expandos are always a bad idea.


I don't see where a host object would be augmented with a property
here.

> If you must use them, you need to check the document.expando property first.


That would be relevant *for MSHTML only* iff a host object would be
*augmented* here.

> Looking at the file it came from, I see a few other problems.
>
> if (typeof oScript.type != "undefined")
> {
> oScript.type = sType || "text/javascript";
> }
>
> if (typeof oScript.type != "undefined")
> {
> oScript.type = sType || "text/javascript";
> }
>
> That is clearly a copy and paste error.


Maybe not, however it is fixed now.

> if (isMethod(typeof aHeads[0].appendChild))
>
> I assume this is a typo and isMethodType was meant.


As no previous version of the method() in the repository handles the
result of the typeof operation, it would have to be. The library uses
the new isMethod() method now.

> // makes the method applicable to Document and Element objects
> if (!o
> && typeof this.constructor != "undefined"
> && /Document|Element/.test(String(this.constructor)))
> {
> o = this;
> }
>
> You wouldn't augment host objects would you?


I would augment a prototype object of a host object after careful
feature tests. Why not? The fact that there is a prototype object
conveys the implementor's intention that it be used accordingly, so it
is not reasonable to assume that this would not work.

> Regardless, this is pure evil.


The explicit conversion to string was not necessary as
RegExp.prototype.test() already does that; fixed. I can't find
anything evil about this. Care to elaborate?

> Next line:
>
> if (o &&isMethod(typeof o.getElementsByTagName))
>
> Same typo as before I assume.


Fixed.

> if (typeof HTMLDocument != "undefined"
> && typeof HTMLDocument.prototype != "undefined")
> {
> HTMLDocument.prototype.getElementsByTabIndex =
> getElementsByTabIndex;
>
> }
>
> if (typeof HTMLElement != "undefined"
> && typeof HTMLElement.prototype != "undefined")
> {
> HTMLElement.prototype.getElementsByTabIndex = getElementsByTabIndex;
>
> }
>
> OMG. No you didn't.


Again, why not?

> Your attribute alias map lists rowspan, but not colspan.


Fixed.

> Both get and set attribute functions have problems. See the version proposed in
> the CWR project.


Maybe later.

> It needs to be revised as I recently fixed a couple of problems,
> but it should indicate areas that you need to improve in
> your code.


So it's only more cheap talk?

> The get and set style property functions don't handle float properly.


They do now.

> The show function is roughly equivalent to Prototype's, which is to
> say worthless.


There is no "show function". If you mean display() or visibility(),
you are mistaken.

> The getParent function is ambiguous as parentNode and parentElement
> are not equivalent.


When would they not be equivalent?

> The getAbsPos function is severely lacking. For one it completely
> ignores borders.


I'll look into that later.

> This looks wrong:
>
> if (typeof _global != "undefined")
> {
> var _global = this;
>
> }
>
> Perhaps you meant:
>
> if (typeof _global == "undefined")


Yes, I did; fixed.

> The test isn't needed anyway.


Yes, it was.

> var dhtml = new DHTML();
>
> Shouldn't this library be a singleton?


No, it should not. A singleton is a concept coming from class-based
inheritance to start with.

> Overall, feature testing should be pulled out of the functions and the
> repetitive comments should be trimmed.


There was and is going to be a version that has all JSdoc[tm] comments
removed, and there is going to be a documentation written in a markup
language generated from them.

> You should run it through JSLint as minification is to be expected (nobody wants to download all
> of those credits.)


I have stated what I think about minifiers already. As for the
credits, people will have to download the minimum of them (after the
JSdoc[tm] is removed) because otherwise I could not distribute the
library under the GNU GPL 2.0+.


PointedEars
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Re: How include a large array? Edward A. Falk C Programming 1 04-04-2013 08:07 PM
How to add onchange event to dropdown using xslt rekha XML 0 11-25-2008 10:03 AM
Checkboxlist add onchange event Jason Hartsoe ASP .Net 1 08-01-2008 03:58 PM
calling clientside js with onchange event Zeebra3 ASP .Net 5 07-14-2007 11:12 PM
POSTING A FORM USING onchange Brendan Vogt ASP .Net 2 08-28-2003 02:09 PM



Advertisments
 



1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57