]> git.proxmox.com Git - extjs.git/blob - extjs/modern/modern/src/field/Slider.js
add extjs 6.0.1 sources
[extjs.git] / extjs / modern / modern / src / field / Slider.js
1 /**
2 * The slider is a way to allow the user to select a value from a given numerical range. You might use it for choosing
3 * a percentage, combine two of them to get min and max values, or use three of them to specify the hex values for a
4 * color. Each slider contains a single 'thumb' that can be dragged along the slider's length to change the value.
5 * Sliders are equally useful inside {@link Ext.form.Panel forms} and standalone. Here's how to quickly create a
6 * slider in form, in this case enabling a user to choose a percentage:
7 *
8 * @example
9 * Ext.create('Ext.form.Panel', {
10 * fullscreen: true,
11 * items: [
12 * {
13 * xtype: 'sliderfield',
14 * label: 'Percentage',
15 * value: 50,
16 * minValue: 0,
17 * maxValue: 100
18 * }
19 * ]
20 * });
21 *
22 * In this case we set a starting value of 50%, and defined the min and max values to be 0 and 100 respectively, giving
23 * us a percentage slider. Because this is such a common use case, the defaults for {@link #minValue} and
24 * {@link #maxValue} are already set to 0 and 100 so in the example above they could be removed.
25 *
26 * It's often useful to render sliders outside the context of a form panel too. In this example we create a slider that
27 * allows a user to choose the waist measurement of a pair of jeans. Let's say the online store we're making this for
28 * sells jeans with waist sizes from 24 inches to 60 inches in 2 inch increments - here's how we might achieve that:
29 *
30 * @example
31 * Ext.create('Ext.form.Panel', {
32 * fullscreen: true,
33 * items: [
34 * {
35 * xtype: 'sliderfield',
36 * label: 'Waist Measurement',
37 * minValue: 24,
38 * maxValue: 60,
39 * increment: 2,
40 * value: 32
41 * }
42 * ]
43 * });
44 *
45 * Now that we've got our slider, we can ask it what value it currently has and listen to events that it fires. For
46 * example, if we wanted our app to show different images for different sizes, we can listen to the {@link #change}
47 * event to be informed whenever the slider is moved:
48 *
49 * slider.on('change', function(field, newValue) {
50 * if (newValue[0] > 40) {
51 * imgComponent.setSrc('large.png');
52 * } else {
53 * imgComponent.setSrc('small.png');
54 * }
55 * }, this);
56 *
57 * Here we listened to the {@link #change} event on the slider and updated the background image of an
58 * {@link Ext.Img image component} based on what size the user selected. Of course, you can use any logic inside your
59 * event listener.
60 */
61 Ext.define('Ext.field.Slider', {
62 extend : 'Ext.field.Field',
63 xtype : 'sliderfield',
64 requires: ['Ext.slider.Slider'],
65 alternateClassName: 'Ext.form.Slider',
66
67 /**
68 * @event change
69 * Fires when the value changes.
70 * @param {Ext.field.Slider} me
71 * @param {Number[]} newValue The new value.
72 * @param {Number[]} oldValue The old value.
73 */
74
75 /**
76 * @event dragchange
77 * Fires when a thumb value changes via drag.
78 * @param {Ext.field.Slider} me
79 * @param {Ext.slider.Slider} sl Slider Component.
80 * @param {Ext.slider.Thumb} thumb
81 * @param {Number[]} newValue The new value of this thumb.
82 * @param {Number[]} oldValue The old value of this thumb.
83 */
84
85 /**
86 * @event dragstart
87 * Fires when the slider thumb starts a drag operation.
88 * @param {Ext.field.Slider} this
89 * @param {Ext.slider.Slider} sl Slider Component.
90 * @param {Ext.slider.Thumb} thumb The thumb being dragged.
91 * @param {Array} value The start value.
92 * @param {Ext.event.Event} e
93 */
94
95 /**
96 * @event drag
97 * Fires when the slider thumb starts a drag operation.
98 * @param {Ext.field.Slider} this
99 * @param {Ext.slider.Slider} sl Slider Component.
100 * @param {Ext.slider.Thumb} thumb The thumb being dragged.
101 * @param {Ext.event.Event} e
102 */
103
104 /**
105 * @event dragend
106 * Fires when the slider thumb ends a drag operation.
107 * @param {Ext.field.Slider} this
108 * @param {Ext.slider.Slider} sl Slider Component.
109 * @param {Ext.slider.Thumb} thumb The thumb being dragged.
110 * @param {Array} value The end value.
111 * @param {Ext.event.Event} e
112 */
113
114 config: {
115 /**
116 * @cfg
117 * @inheritdoc
118 */
119 cls: Ext.baseCSSPrefix + 'slider-field',
120
121 /**
122 * @cfg {Boolean} liveUpdate
123 * `true` to fire change events while the slider is dragging. `false` will
124 * only fire a change once the drag is complete.
125 */
126 liveUpdate: false,
127
128 /**
129 * @cfg
130 * @inheritdoc
131 */
132 tabIndex: -1,
133
134 /**
135 * Will make this field read only, meaning it cannot be changed with used interaction.
136 * @cfg {Boolean} readOnly
137 * @accessor
138 */
139 readOnly: false,
140
141 /**
142 * @inheritdoc Ext.slider.Slider#value
143 * @cfg {Number/Number[]} value
144 * @accessor
145 */
146 value: 0
147 },
148
149 proxyConfig: {
150
151 /**
152 * @inheritdoc Ext.slider.Slider#increment
153 * @cfg {Number} increment
154 * @accessor
155 */
156 increment : 1,
157
158 /**
159 * @inheritdoc Ext.slider.Slider#minValue
160 * @cfg {Number} minValue
161 * @accessor
162 */
163 minValue: 0,
164
165 /**
166 * @inheritdoc Ext.slider.Slider#maxValue
167 * @cfg {Number} maxValue
168 * @accessor
169 */
170 maxValue: 100
171 },
172
173 defaultBindProperty: 'values',
174 twoWayBindable: {
175 values: 1,
176 value: 1
177 },
178
179 /**
180 * @inheritdoc Ext.slider.Slider#values
181 * @cfg {Number/Number[]} values
182 */
183
184 constructor: function(config) {
185 config = config || {};
186
187 if (config.hasOwnProperty('values')) {
188 config.value = config.values;
189 }
190
191 this.callParent([config]);
192 this.updateMultipleState();
193 },
194
195 /**
196 * @private
197 */
198 initialize: function() {
199 this.callParent();
200
201 this.getComponent().on({
202 scope: this,
203
204 change: 'onSliderChange',
205 dragstart: 'onSliderDragStart',
206 drag: 'onSliderDrag',
207 dragend: 'onSliderDragEnd'
208 });
209 },
210
211 /**
212 * @private
213 */
214 applyComponent: function(config) {
215 return Ext.factory(config, Ext.slider.Slider);
216 },
217
218 /**
219 * @private
220 */
221 updateComponent: function(component, oldComponent) {
222 this.callParent([component, oldComponent]);
223
224 component.setMinValue(this.getMinValue());
225 component.setMaxValue(this.getMaxValue());
226 },
227
228 applyValue: function(value) {
229 var ret = value;
230 // If we are currently dragging, don't allow the binding
231 // to push a value over the top of what the user is doing.
232 if (this.dragging && this.isSyncing('value')) {
233 ret = undefined;
234 }
235 return ret;
236 },
237
238 updateValue: function(value, oldValue) {
239 var me = this;
240
241 if (!me.dragging) {
242 me.setComponentValue(value);
243 }
244 if (me.initialized) {
245 me.fireEvent('change', me, value, oldValue);
246 }
247 },
248
249 setComponentValue: function(value) {
250 this.getComponent().setValue(value);
251 },
252
253 onSliderChange: function(slider, thumb, newValue, oldValue) {
254 this.setValue(slider.getValue());
255 this.fireEvent('dragchange', this, slider, thumb, newValue, oldValue);
256 },
257
258 onSliderDragStart: function(slider, thumb, startValue, e) {
259 this.dragging = true;
260 this.fireEvent('dragstart', this, slider, thumb, startValue, e);
261 },
262
263 onSliderDrag: function(slider, thumb, value, e) {
264 var me = this;
265 if (me.getLiveUpdate()) {
266 me.setValue(slider.getValue());
267 }
268 me.fireEvent('drag', me, slider, thumb, value, e);
269 },
270
271 onSliderDragEnd: function(slider, thumb, startValue, e) {
272 this.dragging = false;
273 this.fireEvent('dragend', this, slider, thumb, startValue, e);
274 },
275
276 /**
277 * Convenience method. Calls {@link #setValue}.
278 * @param {Object} value
279 */
280 setValues: function(value) {
281 this.setValue(value);
282 this.updateMultipleState();
283 },
284
285 /**
286 * Convenience method. Calls {@link #getValue}
287 * @return {Object}
288 */
289 getValues: function() {
290 return this.getValue();
291 },
292
293 reset: function() {
294 var config = this.config,
295 initialValue = (this.config.hasOwnProperty('values')) ? config.values : config.value;
296
297 this.setValue(initialValue);
298 },
299
300 updateDisabled: function(disabled) {
301 this.callParent(arguments);
302
303 this.getComponent().setDisabled(disabled);
304 },
305
306 updateReadOnly: function(newValue) {
307 this.getComponent().setReadOnly(newValue);
308 },
309
310 isDirty : function () {
311 if (this.getDisabled()) {
312 return false;
313 }
314
315 return this.getValue() !== this.originalValue;
316 },
317
318 updateMultipleState: function() {
319 var value = this.getValue();
320 if (value && value.length > 1) {
321 this.addCls(Ext.baseCSSPrefix + 'slider-multiple');
322 }
323 }
324 });