问题
I have a Dojo SubmitButton with jsId="saveParamButtonWidget". I overrided its onClick method by putting:
saveParamButtonWidget.onClick = editParam
I defined the editParam() function like this:
function editParam(eventObj) {
dojo.stopEvent(eventObj);
// ...
}
dojo.stopEvent() is supposed to stop event bubbling and default processing. However, the browser will submit the form anyway. I also tried with the following:
function editParam(eventObj) {
eventObj.stopPropagation();
eventObj.preventDefault();
// ...
}
Same thing. The only way I've managed to prevent form submission is by returning "false" from the event handler:
function editParam(eventObj) {
// ...
return false;
}
Can someone tell me why the first two ways did not work? Thanks.
回答1:
Okay, after doing some digging through the source, I believe I can answer your question definitively.
The reason dojo.stopEvent() doesn't work, but return false does, is entirely due to how dijit.form.Button is coded. If you're interested, it's time for a little field trip. Keep your hard hats on.
When a dijit.form.Button is clicked...
- The button's
_onButtonClickmethod is invoked. (This is hooked up in the template, to the specialondijitclickevent which captures not only mouse click but also certain keypresses, for a11y purposes.) - The
_onButtonClickmethod first invokes the_onClickmethod, which, presuming the button is not disabled (which it's not in this case), invokes and returns the result of theonClickmethod. This is of particular interest since it's the method you're overriding! - Coming back to
_onButtonClick, if_onClickreturned preciselyfalse(e.g. if youronClickhandler returnedfalse),_onButtonClickimmediately bails out. This is why returning false makes your code work as desired. But what happens if it doesn't bail out there? Let's follow the trail further... - Next,
_onButtonClickchecks whether this button not a descendant of an actual HTML form, but is a descendant of a widget with an_onSubmitmethod (duck-typing). I'm assuming that in your case it is inside a real form (dijit.form.Formcounts), so we'll skip over this. (I am under the impression that this code path wouldn't actually end up submitting, whereas yours apparently does.) - One final condition is checked: if the button has a
valueNodedefined (it does), theclickmethod of this node is invoked. Unfortunately, this produces an entirely new event object on an invisibleinput type="submit"node under your form, and thus anything you tried to tell the original event is rendered immaterial, and the form goes on to submit! This is whydojo.stopEventdid not work - this code indijit.form.Buttonpays it absolutely no heed.
I cooked this up as a somewhat-limited proof of concept (be sure to open firebug/etc. to get the logs): http://jsfiddle.net/Bf5H8/
Perhaps this is something that should be logged as a bug, but I suppose the initial thought may have been that supporting the well-known return false mechanism would be enough.
All this being said, it's quite possible that overriding onSubmit of the form is more in-line with your interests than overriding the button's onClick anyway (as S.Jones suggested), but at least this should solve the mystery.
回答2:
Interesting question. +1
I believe you have to use dojo.connect to connect your function to a DOM event to get access to those methods with an event object.
See: The Event Object (DojoTollkit.org Reference Guide)
The Event Object
When you connect a function to a DOM event with dojo.connect, Dojo passes your function a normalized event object. This means that, regardless of the client's browser, you can count on a set of standard attributes about the event and a set of methods to manipulate the event.
Assume that your function has been called by dojo.connect and takes an argument named event, like:
dojo.connect(dojo.byId("node"), "onclick", function(event){ // the var 'event' is available, and is the normalized object });...
Dojo normalizes the following methods with an event object:
- event.preventDefault — prevent an event's default behavior (e.g., a link from loading a new page)
- event.stopPropagation — prevent an event from triggering a parent node's event
Additionally, dojo.stopEvent(event) will prevent both default behavior any any propagation (bubbling) of an event.
That said, placing a function like the one below in your form to perform some logic before submitting it, is a fairly clean, easily understood & maintainable approach.
<script type="dojo/method" event="onSubmit">
if (!this.validate()) { // or whatever else you'd like to evaluate
// insert calls here...
return false;
}
return true;
<script>
Cheers.
回答3:
I had the same issue for using dojo.stopEvent
This issue is solved the form submission issue like this - here it is a simple form used to connect through dojo:
this.formId = dojo.byId("formId");
dojo.connect(this.formId, 'onsubmit', function(evt) {
var val_main = validate_this_form(0);
if(val_main == false)
dojo.stopEvent(evt);
});
来源:https://stackoverflow.com/questions/3844995/preventing-form-submission-with-dojo