You'd have to use something like
document.getElementById(whatever).addEventListener('change', callfunc,
false), I believe.
Patrick
Clever. This has the disadvantage that it only calls the actual
function in the onchange handler but fails to trigger any other event
that could be bound to the same event via addEventListener (probably not
relevant in this particular case).
In general it is possible to synthesize events [1] so that the result is
the same as if they had been triggered by an user's action.
A quick solution would look approximately as follows:
// We are assuming <SELECT ID='foo'><OPTION ...></SELECT>
var SELECT = document.getElementById('foo');
// This just sets the right option but does not trigger onchange
SELECT.childNodes[3].selected = true;
// This does triggers 'onchange';
// the previous lines are still necessary
var evt = document.createEvent("HTMLEvents");
evt.initEvent("change", true, true);
SELECT.dispatchEvent(evt);
[1] http://developer.mozilla.org/en/docs/DOM:document.createEvent
[1] http://wiki.greasespot.net/Code_snippets
En/na RodMcguire ha escrit:
This is working for me in the test page you indicated:
// 1 - Select radio button 'Change status to'
var cs = document.getElementById('knob-changestatus');
cs.checked = true;
// 2 - Select option 'NEEDINFO'
var sf = document.forms.namedItem( 'changeform');
var ns = sf.elements.namedItem('newstatus');
var ni = ns.options[1];
// NEEDINFO is the second option, i.e. options[1]
ni.selected = true;
// Trigger 'onchange';
var evt = document.createEvent("HTMLEvents");
evt.initEvent("change", true, true);
// set 'Reporter' after change status; this is necessary because
// the 'change' event occurs asynchronously
ni.addEventListener('change',setReporter,true);
ni.dispatchEvent(evt);
// 3 - Select from 'Reporter'
function setReporter(){
var ac = document.getElementById('requestee_actor-16');
ac.options[2].selected = true;
/* trigger onchange to ensure we're not missing
somenthing important, we never know... */
var evt = document.createEvent("HTMLEvents");
evt.initEvent("change", true, true);
ac.dispatchEvent(evt);
}
Of course you have to provide some error-handling in the code above in
order for it to be robust.
> Do you have any suggestion how to find out who is to blame for this?
We should carefully read the code used by the page;
better than that is to reproduce the actions a human user would take, which
is what I did above.
> Is there some way how to list all event handlers currently registered
> in the page?
If by that you mean something like 'foo.getEventListeners()', then the
answer is 'no'. I do not know whether it would be possible to attach
a listener which would capture the instant at which other event would be
triggered, an in that case if we could even know the name of the
listener or a reference to it. This seems like an interesting exercise ;)
I developed my script on the page you indicated in your original post:
http://mcepl.fedorapeople.org/tmp/show_bug.html
There NEEDINFO was option[1].
>
>> // 3 - Select from 'Reporter'
>> function setReporter(){
>> var ac = document.getElementById('requestee_actor-16');
>>[...]
>> }
>
> Actually, this doesn't work, because we have to get needinfo.flag_id
> from the global scope (take a look at the original HTML, whole INPUT
> element is generated by the Javascript with the changing name/id).
> However, whatever I tried I cannot get to the global needinfo (even
> unsafeWindow.needinfo doesn't work -- I don't care about unsafeWindow
> in this case, because I pretty much have to trust bugzilla of my
> employer ;-)). Any thoughts?
I see. Anyway replacing the line above by the following
var ac = document.getElementById('requestee_actor-' +
unsafeWindow.needinfo.flag_id );
works just fine. Why are you saying you cannot get
unsafeWindow.needinfo to work?
> The last version of the script is on http://mcepl.fedorapeople.org/scripts/bugzillaCopyOwnerToCC.user.js
I cannot completely test the script on the sample page because I get a
404 upon submit (button "NEEDINFO reporter"). However, if you slightly
modify the addNewButton function to inhibit the submit:
function addNewButton(oldButton,newId,newLabel,handlerFunc) {
var newButton = oldButton.cloneNode(true);
newButton.setAttribute('type','button'); // ---> added line
newButton.id=newId
...
}
you will find that it sets the status correctly, as well as the 'from'
field. This leads me to think that the problem is probably the
submission taking place before our synthesized events get a chance to be
triggered. If this is is so, we could attempt to capture the submit
event, trigger our events, and then release the submit and let it go.
Alternatively you can try delaying the submit:
1) Inhibit the submit by setting the button type to 'button' as above
2) At the end of function needinfoHandler call the form's submit method
with a delay of 300 milliseconds:
setTimeout("document.forms.namedItem('changeform').submit()",300);
Not the fantastic solution, but it may help you to find the culprit.
Yes, this is correct. Finally, at least something in this mess seems to
work as I would expect it!
> This leads me to think that the problem is probably the
> submission taking place before our synthesized events get a chance to be
> triggered. If this is is so, we could attempt to capture the submit
> event, trigger our events, and then release the submit and let it go.
Do you mean adding
document.forms[0].addEventListener("submit",FakeSubmit,true)
and then doing something like this:
function FakeSubmit(evt) {
needinfoHandler();
var evtSubmit = document.createEvent("HTMLEvents");
evtSubmit.initEvent("submit", true, true);
ac.dispatchEvent(evtSubmit);
evt.stopPropagation();
evt.preventDefault();
}
Is that what you meant?
Thanks for all the help,
Matěj
--
http://www.ceplovi.cz/matej/blog/, Jabber: ceplma<at>jabber.cz
GPG Finger: 89EF 4BC6 288A BF43 1BAB 25C3 E09F EF25 D964 84AC
Whenever Christ our life is revealed, then also you will be
revealed with Him in glory.
-- Colossians 3:4 (Green's Literal Translation)
Or in other words, is there any way how to wait until the event finishes
to happen? Some kind of callbacks or something?
Matěj
--
http://www.ceplovi.cz/matej/blog/, Jabber: ceplma<at>jabber.cz
GPG Finger: 89EF 4BC6 288A BF43 1BAB 25C3 E09F EF25 D964 84AC
There's nothing wrong with you that reincarnation won't cure.
-- Jack F. Leonard