- uploading 1.1 in tags
[mootools.git] / Plugins / Slider.js
blobf55a646ca77d2b5527b9aef58f308da6ed6789ce
1 /*
2 Script: Slider.js
3         Contains <Slider>
5 License:
6         MIT-style license.
7 */
9 /*
10 Class: Slider
11         Creates a slider with two elements: a knob and a container. Returns the values.
12         
13 Note:
14         The Slider requires an XHTML doctype.
16 Arguments:
17         element - the knob container
18         knob - the handle
19         options - see Options below
21 Options:
22         onChange - a function to fire when the value changes.
23         onComplete - a function to fire when you're done dragging.
24         onTick - optionally, you can alter the onTick behavior, for example displaying an effect of the knob moving to the desired position.
25                 Passes as parameter the new position.
26         steps - the number of steps for your slider.
27         mode - either 'horizontal' or 'vertical'. defaults to horizontal.
28         offset - relative offset for knob position. default to 0.
31 var Slider = new Class({
33         options: {
34                 onChange: Class.empty,
35                 onComplete: Class.empty,
36                 onTick: function(pos){
37                         this.knob.setStyle(this.p, pos);
38                 },
39                 mode: 'horizontal',
40                 steps: 100,
41                 offset: 0
42         },
44         initialize: function(el, knob, options){
45                 this.element = $(el);
46                 this.knob = $(knob);
47                 this.setOptions(options);
48                 this.previousChange = -1;
49                 this.previousEnd = -1;
50                 this.step = -1;
51                 this.element.addEvent('mousedown', this.clickedElement.bindWithEvent(this));
52                 var mod, offset;
53                 switch(this.options.mode){
54                         case 'horizontal':
55                                 this.z = 'x';
56                                 this.p = 'left';
57                                 mod = {'x': 'left', 'y': false};
58                                 offset = 'offsetWidth';
59                                 break;
60                         case 'vertical':
61                                 this.z = 'y';
62                                 this.p = 'top';
63                                 mod = {'x': false, 'y': 'top'};
64                                 offset = 'offsetHeight';
65                 }
66                 this.max = this.element[offset] - this.knob[offset] + (this.options.offset * 2);
67                 this.half = this.knob[offset]/2;
68                 this.getPos = this.element['get' + this.p.capitalize()].bind(this.element);
69                 this.knob.setStyle('position', 'relative').setStyle(this.p, - this.options.offset);
70                 var lim = {};
71                 lim[this.z] = [- this.options.offset, this.max - this.options.offset];
72                 this.drag = new Drag.Base(this.knob, {
73                         limit: lim,
74                         modifiers: mod,
75                         snap: 0,
76                         onStart: function(){
77                                 this.draggedKnob();
78                         }.bind(this),
79                         onDrag: function(){
80                                 this.draggedKnob();
81                         }.bind(this),
82                         onComplete: function(){
83                                 this.draggedKnob();
84                                 this.end();
85                         }.bind(this)
86                 });
87                 if (this.options.initialize) this.options.initialize.call(this);
88         },
90         /*
91         Property: set
92                 The slider will get the step you pass.
94         Arguments:
95                 step - one integer
96         */
98         set: function(step){
99                 this.step = step.limit(0, this.options.steps);
100                 this.checkStep();
101                 this.end();
102                 this.fireEvent('onTick', this.toPosition(this.step));
103                 return this;
104         },
106         clickedElement: function(event){
107                 var position = event.page[this.z] - this.getPos() - this.half;
108                 position = position.limit(-this.options.offset, this.max -this.options.offset);
109                 this.step = this.toStep(position);
110                 this.checkStep();
111                 this.end();
112                 this.fireEvent('onTick', position);
113         },
115         draggedKnob: function(){
116                 this.step = this.toStep(this.drag.value.now[this.z]);
117                 this.checkStep();
118         },
120         checkStep: function(){
121                 if (this.previousChange != this.step){
122                         this.previousChange = this.step;
123                         this.fireEvent('onChange', this.step);
124                 }
125         },
127         end: function(){
128                 if (this.previousEnd !== this.step){
129                         this.previousEnd = this.step;
130                         this.fireEvent('onComplete', this.step + '');
131                 }
132         },
134         toStep: function(position){
135                 return Math.round((position + this.options.offset) / this.max * this.options.steps);
136         },
138         toPosition: function(step){
139                 return this.max * step / this.options.steps;
140         }
144 Slider.implement(new Events);
145 Slider.implement(new Options);