This can't be done in general, but can be done in the specific case mentioned in the question, namely to detect that the scrolling occurred because Dojo is trying to put focus on an invalid element in a form. To do that it's necessary to override the validate
method in dijit/form/Form
so that it can automatically override the focus
method in all widgets in the form:
validate: function(){
var self = this;
var children = this._getDescendantFormWidgets();
array.forEach(children, function(child){
if(typeof(child.focus) === "function" && !child._uuiIsModded){
child._uuiOldFocus = child.focus;
child.focus = self._onProgrammaticFocus;
child._uuiIsModded = true;
}
});
return this.inherited(arguments);
},
_onProgrammaticFocus: function(){
topic.publish("on-programmatic-focus", this);
this._uuiOldFocus.apply(this, arguments);
},
The new validate
method amends all widgets contained in a form. The amendment is to replace the standard focus
method with a custom method _onProgrammaticFocus
, which fires the event on-programmatic-focus
before calling the standard focus
method. That way the event is fired only when the focus is put on the widget programmatically in response to a validation error and not when the widget is selected by the user:
- when user puts focus on a widget by selecting the widget with a mouse or tapping on it the
focus
method IS NOT CALLED
- when the form widget contains invalid value, the standard behavior of the
validate
method is to amend the widget with CSS classes that show the validation error and put focus on the widget by calling the focus
method. In this case the focus should be already amended and fire the "on-programmatic-focus" event.
Please remember, that this is a hack that replaces the standard focus
method and may not work if there are problems in other parts of your code. Specifically, in some cases __uuiOldFocus
may become undefined if your widgets containing other widgets don't inherit dijit/_Container
. This is because this._getDescendantFormWidgets()
returns different children than method toObject
from dom/dom-form
. The method this._getDescendantFormWidgets()
used in form validation relies on the fact that all widgets containing other widgets should inherit the dijit/_Container
mixin (which initializes this.containerNode
with the current DOM node).