HTML element, custom client event
I have a composite control that emits HTML that looks like this:
<span id="myControl">
<select id="myControl_select">
<option value=""></option>
<option value="1">Item 1</option>
<option value="2">Item 2</option>
</select>
</span>
I would like the parent control to fire an event when the onchange event contained in the combobox fires. Since this is a composite control, I have to allow the consumer of that control to assign an event handler (I was hoping via an html attribute called onvaluechanged or whatever)
Edited to include bobince clause. The only problem is that the argument parameter is not passed. It is currently "undefined".
<script>
window.onload = function() {
var objSelect = document.getElementById('myControl_select')
if (objSelect.attachEvent)
objSelect.attachEvent("onchange", myControl_ddlOnChange);
else if (objSelect.addEventListener)
objSelect.addEventListener("onchange", myControl_ddlOnChange, false);
}
function myControl_ddlOnChange()
{
//fire span on value changed event
var target= document.getElementById('mycontrol');
var handler= target.getAttribute('onvaluechanged');
var args = { text : 'Hi!', index : 0 }
if (handler)
new Function(handler).call(target, args);
}
function myControl_ValueChanged()
{
alert(arguments[0]);
}
</script>
<span id="myControl" onvaluechanged="myControl_ValueChanged();">
<select id="myControl_select">
<option value=""></option>
<option value="1">Item 1</option>
<option value="2">Item 2</option>
</select>
</span>
source to share
Don't use attachEvent, it's IE only. You can hack solutions that use either attachEvent for IE or addEventListener in other browsers, or use a framework that already does this for you, but a simple event handler is sufficient for your purposes:
document.getElementById('myControl_select').onchange= myControl_ddlOnChange;
Don't start adding your own HTML onsomething attributes. Aside from being invalid, the browser won't do this magic to turn the HTML onclick attribute into a JavaScript onclick property. You have to do it manually by firing like:
var target= document.getElementById('myControl');
var handler= target.getAttribute('onvaluechanged');
if (handler)
new Function(handler).call(target);
It is generally best for the caller to write an "onclick" with the JavaScript function itself. HTML event handler attributes are pretty much sucking and should generally be avoided.
ETA for comments:
The reason no arguments are passed is because your event handler is:
onvaluechanged="myControl_ValueChanged();"
does not pass any arguments. You could say:
onvaluechanged="myControl_ValueChanged(arguments[0]);"
or, to pass any number of arguments:
onvaluechanged="myControl_ValueChanged.apply(this, arguments);"
But it actually gets away from how event handlers work normally, since they don't have arguments (*). It's much easier to just stick with JavaScript and say:
var control= document.getElementById('myControl');
// to register
//
control.onvaluechanged= myControl_ddlOnChange;
// to call
//
control.onvaluechanged(/* any arguments; 'this' inside ddlOnChange is the control */);
not this curious function.
Other minor nits: addEventListener accepts 'change', not 'onchange'; capital C in getElementById ('myControl').
(*: other than the event argument, in non-IE)
source to share