6 Feb 2012 7:04 PM #1
Sliders (Single & Multi) fire [before]change[complete] events in setValue
Ext version tested:
- Ext 4.1.0b2
Browser versions tested against:
- Firefox 10
DOCTYPE tested against:
- html (HTML5)
- The code for handling setValue for a slider triggers change events that are supposed to be associated with user-driven changes rather than programmatic changes.
- For a slider, the "dragend" event is practically the same as what "change" seems intended to be.
- For code which handles the "change" event for a variety of fields, this requires a special-case to ignore "change" on the slider and listen to "dragend" instead (and to use getValue() instead of having the new value passed as the second argument).
Steps to reproduce the problem:
- Just call setValue() on a slider.
The result that was expected:
- No events should be fired.
The result that occurs instead:
- Various before/after change events are fired.
- To fix this in a backward-compatible way, it might be necessary to create a new, abstract/base slider class which does not have this problem. Multi could inherit from it and implement the existing setValue() behavior, while new "BetterMulti" and "BetterSingle" classes provide change events that are more compliant with the behavior of other fields.
6 Feb 2012 7:17 PM #2
- Join Date
- Apr 2007
- Sydney, Australia
- Vote Rating
It's intended to work that way, from the docs:
Fires before the slider value is changed. By returning false from an event handler, you can cancel the event and prevent the slider from changing.Evan Trimboli
Twitter - @evantrimboli
Don't be afraid of the source code!
7 Feb 2012 8:01 AM #3
Documentation/Design is broken
Yes, it is behaving "as documented", but the documentation has been written to describe a "broken" design/implementation that violates the contract of the Ext.form.field.Base class that the slider inherits.
The Base documentation for the change event says:
Fires when a user-initiated change is detected in the value of the field.
Fires when the slider value is changed.
In general, I would think that if code wants to prevent other code from changing the value of a slider (or any other field), it should be using a validation-related function to do that, as other fields do. Maybe it would make sense to have a "validate" event; but it should be separate from "change" -- that is, there is a big difference between "Is this data ok?" and "The user changed this". Specifically, I am not trying to cancel the change & reject the data; but I do want to avoid taking actions that should only happen when a human being fiddles with the UI. (Ext JS itself does this by directly setting internal data fields; but since those aren't documented for application use, that's not a reasonable option.)
Other fields will fire change through the Ext.form.field.Field mixin, which uses this.suspendCheckChange to control firing the change event. This makes it easy to make programatic changes to values without firing off a lot of incorrect event handlers, which is obviously useful -- particularly when loading up a page of data values. The setRawValue call isn't exactly the same thing; as this isn't about bypassing validation -- it's about avoiding the events that run "when the user does something" when the user isn't actually doing anything.
One could say that the "bug" here is simply that sliders don't act like other fields & should also use the Field mixin, or else re-implement its behaviors. But in general there need to be ways to set values of fields without triggering code that should run when a user changes the values of fields.