sync
[bootswatch] / Eshopper / js / price-range.js
1 /* =========================================================\r
2  * bootstrap-slider.js v2.0.0\r
3  * http://www.eyecon.ro/bootstrap-slider\r
4  * =========================================================\r
5  * Copyright 2012 Stefan Petre\r
6  *\r
7  * Licensed under the Apache License, Version 2.0 (the "License");\r
8  * you may not use this file except in compliance with the License.\r
9  * You may obtain a copy of the License at\r
10  *\r
11  * http://www.apache.org/licenses/LICENSE-2.0\r
12  *\r
13  * Unless required by applicable law or agreed to in writing, software\r
14  * distributed under the License is distributed on an "AS IS" BASIS,\r
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
16  * See the License for the specific language governing permissions and\r
17  * limitations under the License.\r
18  * ========================================================= */\r
19  \r
20 !function( $ ) {\r
21 \r
22         var Slider = function(element, options) {\r
23                 this.element = $(element);\r
24                 this.picker = $('<div class="slider">'+\r
25                                                         '<div class="slider-track">'+\r
26                                                                 '<div class="slider-selection"></div>'+\r
27                                                                 '<div class="slider-handle"></div>'+\r
28                                                                 '<div class="slider-handle"></div>'+\r
29                                                         '</div>'+\r
30                                                         '<div class="tooltip"><div class="tooltip-arrow"></div><div class="tooltip-inner"></div></div>'+\r
31                                                 '</div>')\r
32                                                         .insertBefore(this.element)\r
33                                                         .append(this.element);\r
34                 this.id = this.element.data('slider-id')||options.id;\r
35                 if (this.id) {\r
36                         this.picker[0].id = this.id;\r
37                 }\r
38 \r
39                 if (typeof Modernizr !== 'undefined' && Modernizr.touch) {\r
40                         this.touchCapable = true;\r
41                 }\r
42 \r
43                 var tooltip = this.element.data('slider-tooltip')||options.tooltip;\r
44 \r
45                 this.tooltip = this.picker.find('.tooltip');\r
46                 this.tooltipInner = this.tooltip.find('div.tooltip-inner');\r
47 \r
48                 this.orientation = this.element.data('slider-orientation')||options.orientation;\r
49                 switch(this.orientation) {\r
50                         case 'vertical':\r
51                                 this.picker.addClass('slider-vertical');\r
52                                 this.stylePos = 'top';\r
53                                 this.mousePos = 'pageY';\r
54                                 this.sizePos = 'offsetHeight';\r
55                                 this.tooltip.addClass('right')[0].style.left = '100%';\r
56                                 break;\r
57                         default:\r
58                                 this.picker\r
59                                         .addClass('slider-horizontal')\r
60                                         .css('width', this.element.outerWidth());\r
61                                 this.orientation = 'horizontal';\r
62                                 this.stylePos = 'left';\r
63                                 this.mousePos = 'pageX';\r
64                                 this.sizePos = 'offsetWidth';\r
65                                 this.tooltip.addClass('top')[0].style.top = -this.tooltip.outerHeight() - 14 + 'px';\r
66                                 break;\r
67                 }\r
68 \r
69                 this.min = this.element.data('slider-min')||options.min;\r
70                 this.max = this.element.data('slider-max')||options.max;\r
71                 this.step = this.element.data('slider-step')||options.step;\r
72                 this.value = this.element.data('slider-value')||options.value;\r
73                 if (this.value[1]) {\r
74                         this.range = true;\r
75                 }\r
76 \r
77                 this.selection = this.element.data('slider-selection')||options.selection;\r
78                 this.selectionEl = this.picker.find('.slider-selection');\r
79                 if (this.selection === 'none') {\r
80                         this.selectionEl.addClass('hide');\r
81                 }\r
82                 this.selectionElStyle = this.selectionEl[0].style;\r
83 \r
84 \r
85                 this.handle1 = this.picker.find('.slider-handle:first');\r
86                 this.handle1Stype = this.handle1[0].style;\r
87                 this.handle2 = this.picker.find('.slider-handle:last');\r
88                 this.handle2Stype = this.handle2[0].style;\r
89 \r
90                 var handle = this.element.data('slider-handle')||options.handle;\r
91                 switch(handle) {\r
92                         case 'round':\r
93                                 this.handle1.addClass('round left-round');\r
94                                 this.handle2.addClass('round');\r
95                                 break\r
96                         case 'triangle':\r
97                                 this.handle1.addClass('triangle');\r
98                                 this.handle2.addClass('triangle');\r
99                                 break\r
100                 }\r
101 \r
102                 if (this.range) {\r
103                         this.value[0] = Math.max(this.min, Math.min(this.max, this.value[0]));\r
104                         this.value[1] = Math.max(this.min, Math.min(this.max, this.value[1]));\r
105                 } else {\r
106                         this.value = [ Math.max(this.min, Math.min(this.max, this.value))];\r
107                         this.handle2.addClass('hide');\r
108                         if (this.selection == 'after') {\r
109                                 this.value[1] = this.max;\r
110                         } else {\r
111                                 this.value[1] = this.min;\r
112                         }\r
113                 }\r
114                 this.diff = this.max - this.min;\r
115                 this.percentage = [\r
116                         (this.value[0]-this.min)*100/this.diff,\r
117                         (this.value[1]-this.min)*100/this.diff,\r
118                         this.step*100/this.diff\r
119                 ];\r
120 \r
121                 this.offset = this.picker.offset();\r
122                 this.size = this.picker[0][this.sizePos];\r
123 \r
124                 this.formater = options.formater;\r
125 \r
126                 this.layout();\r
127 \r
128                 if (this.touchCapable) {\r
129                         // Touch: Bind touch events:\r
130                         this.picker.on({\r
131                                 touchstart: $.proxy(this.mousedown, this)\r
132                         });\r
133                 } else {\r
134                         this.picker.on({\r
135                                 mousedown: $.proxy(this.mousedown, this)\r
136                         });\r
137                 }\r
138 \r
139                 if (tooltip === 'show') {\r
140                         this.picker.on({\r
141                                 mouseenter: $.proxy(this.showTooltip, this),\r
142                                 mouseleave: $.proxy(this.hideTooltip, this)\r
143                         });\r
144                 } else {\r
145                         this.tooltip.addClass('hide');\r
146                 }\r
147         };\r
148 \r
149         Slider.prototype = {\r
150                 constructor: Slider,\r
151 \r
152                 over: false,\r
153                 inDrag: false,\r
154                 \r
155                 showTooltip: function(){\r
156                         this.tooltip.addClass('in');\r
157                         //var left = Math.round(this.percent*this.width);\r
158                         //this.tooltip.css('left', left - this.tooltip.outerWidth()/2);\r
159                         this.over = true;\r
160                 },\r
161                 \r
162                 hideTooltip: function(){\r
163                         if (this.inDrag === false) {\r
164                                 this.tooltip.removeClass('in');\r
165                         }\r
166                         this.over = false;\r
167                 },\r
168 \r
169                 layout: function(){\r
170                         this.handle1Stype[this.stylePos] = this.percentage[0]+'%';\r
171                         this.handle2Stype[this.stylePos] = this.percentage[1]+'%';\r
172                         if (this.orientation == 'vertical') {\r
173                                 this.selectionElStyle.top = Math.min(this.percentage[0], this.percentage[1]) +'%';\r
174                                 this.selectionElStyle.height = Math.abs(this.percentage[0] - this.percentage[1]) +'%';\r
175                         } else {\r
176                                 this.selectionElStyle.left = Math.min(this.percentage[0], this.percentage[1]) +'%';\r
177                                 this.selectionElStyle.width = Math.abs(this.percentage[0] - this.percentage[1]) +'%';\r
178                         }\r
179                         if (this.range) {\r
180                                 this.tooltipInner.text(\r
181                                         this.formater(this.value[0]) + \r
182                                         ' : ' + \r
183                                         this.formater(this.value[1])\r
184                                 );\r
185                                 this.tooltip[0].style[this.stylePos] = this.size * (this.percentage[0] + (this.percentage[1] - this.percentage[0])/2)/100 - (this.orientation === 'vertical' ? this.tooltip.outerHeight()/2 : this.tooltip.outerWidth()/2) +'px';\r
186                         } else {\r
187                                 this.tooltipInner.text(\r
188                                         this.formater(this.value[0])\r
189                                 );\r
190                                 this.tooltip[0].style[this.stylePos] = this.size * this.percentage[0]/100 - (this.orientation === 'vertical' ? this.tooltip.outerHeight()/2 : this.tooltip.outerWidth()/2) +'px';\r
191                         }\r
192                 },\r
193 \r
194                 mousedown: function(ev) {\r
195 \r
196                         // Touch: Get the original event:\r
197                         if (this.touchCapable && ev.type === 'touchstart') {\r
198                                 ev = ev.originalEvent;\r
199                         }\r
200 \r
201                         this.offset = this.picker.offset();\r
202                         this.size = this.picker[0][this.sizePos];\r
203 \r
204                         var percentage = this.getPercentage(ev);\r
205 \r
206                         if (this.range) {\r
207                                 var diff1 = Math.abs(this.percentage[0] - percentage);\r
208                                 var diff2 = Math.abs(this.percentage[1] - percentage);\r
209                                 this.dragged = (diff1 < diff2) ? 0 : 1;\r
210                         } else {\r
211                                 this.dragged = 0;\r
212                         }\r
213 \r
214                         this.percentage[this.dragged] = percentage;\r
215                         this.layout();\r
216 \r
217                         if (this.touchCapable) {\r
218                                 // Touch: Bind touch events:\r
219                                 $(document).on({\r
220                                         touchmove: $.proxy(this.mousemove, this),\r
221                                         touchend: $.proxy(this.mouseup, this)\r
222                                 });\r
223                         } else {\r
224                                 $(document).on({\r
225                                         mousemove: $.proxy(this.mousemove, this),\r
226                                         mouseup: $.proxy(this.mouseup, this)\r
227                                 });\r
228                         }\r
229 \r
230                         this.inDrag = true;\r
231                         var val = this.calculateValue();\r
232                         this.element.trigger({\r
233                                         type: 'slideStart',\r
234                                         value: val\r
235                                 }).trigger({\r
236                                         type: 'slide',\r
237                                         value: val\r
238                                 });\r
239                         return false;\r
240                 },\r
241 \r
242                 mousemove: function(ev) {\r
243                         \r
244                         // Touch: Get the original event:\r
245                         if (this.touchCapable && ev.type === 'touchmove') {\r
246                                 ev = ev.originalEvent;\r
247                         }\r
248 \r
249                         var percentage = this.getPercentage(ev);\r
250                         if (this.range) {\r
251                                 if (this.dragged === 0 && this.percentage[1] < percentage) {\r
252                                         this.percentage[0] = this.percentage[1];\r
253                                         this.dragged = 1;\r
254                                 } else if (this.dragged === 1 && this.percentage[0] > percentage) {\r
255                                         this.percentage[1] = this.percentage[0];\r
256                                         this.dragged = 0;\r
257                                 }\r
258                         }\r
259                         this.percentage[this.dragged] = percentage;\r
260                         this.layout();\r
261                         var val = this.calculateValue();\r
262                         this.element\r
263                                 .trigger({\r
264                                         type: 'slide',\r
265                                         value: val\r
266                                 })\r
267                                 .data('value', val)\r
268                                 .prop('value', val);\r
269                         return false;\r
270                 },\r
271 \r
272                 mouseup: function(ev) {\r
273                         if (this.touchCapable) {\r
274                                 // Touch: Bind touch events:\r
275                                 $(document).off({\r
276                                         touchmove: this.mousemove,\r
277                                         touchend: this.mouseup\r
278                                 });\r
279                         } else {\r
280                                 $(document).off({\r
281                                         mousemove: this.mousemove,\r
282                                         mouseup: this.mouseup\r
283                                 });\r
284                         }\r
285 \r
286                         this.inDrag = false;\r
287                         if (this.over == false) {\r
288                                 this.hideTooltip();\r
289                         }\r
290                         this.element;\r
291                         var val = this.calculateValue();\r
292                         this.element\r
293                                 .trigger({\r
294                                         type: 'slideStop',\r
295                                         value: val\r
296                                 })\r
297                                 .data('value', val)\r
298                                 .prop('value', val);\r
299                         return false;\r
300                 },\r
301 \r
302                 calculateValue: function() {\r
303                         var val;\r
304                         if (this.range) {\r
305                                 val = [\r
306                                         (this.min + Math.round((this.diff * this.percentage[0]/100)/this.step)*this.step),\r
307                                         (this.min + Math.round((this.diff * this.percentage[1]/100)/this.step)*this.step)\r
308                                 ];\r
309                                 this.value = val;\r
310                         } else {\r
311                                 val = (this.min + Math.round((this.diff * this.percentage[0]/100)/this.step)*this.step);\r
312                                 this.value = [val, this.value[1]];\r
313                         }\r
314                         return val;\r
315                 },\r
316 \r
317                 getPercentage: function(ev) {\r
318                         if (this.touchCapable) {\r
319                                 ev = ev.touches[0];\r
320                         }\r
321                         var percentage = (ev[this.mousePos] - this.offset[this.stylePos])*100/this.size;\r
322                         percentage = Math.round(percentage/this.percentage[2])*this.percentage[2];\r
323                         return Math.max(0, Math.min(100, percentage));\r
324                 },\r
325 \r
326                 getValue: function() {\r
327                         if (this.range) {\r
328                                 return this.value;\r
329                         }\r
330                         return this.value[0];\r
331                 },\r
332 \r
333                 setValue: function(val) {\r
334                         this.value = val;\r
335 \r
336                         if (this.range) {\r
337                                 this.value[0] = Math.max(this.min, Math.min(this.max, this.value[0]));\r
338                                 this.value[1] = Math.max(this.min, Math.min(this.max, this.value[1]));\r
339                         } else {\r
340                                 this.value = [ Math.max(this.min, Math.min(this.max, this.value))];\r
341                                 this.handle2.addClass('hide');\r
342                                 if (this.selection == 'after') {\r
343                                         this.value[1] = this.max;\r
344                                 } else {\r
345                                         this.value[1] = this.min;\r
346                                 }\r
347                         }\r
348                         this.diff = this.max - this.min;\r
349                         this.percentage = [\r
350                                 (this.value[0]-this.min)*100/this.diff,\r
351                                 (this.value[1]-this.min)*100/this.diff,\r
352                                 this.step*100/this.diff\r
353                         ];\r
354                         this.layout();\r
355                 }\r
356         };\r
357 \r
358         $.fn.slider = function ( option, val ) {\r
359                 return this.each(function () {\r
360                         var $this = $(this),\r
361                                 data = $this.data('slider'),\r
362                                 options = typeof option === 'object' && option;\r
363                         if (!data)  {\r
364                                 $this.data('slider', (data = new Slider(this, $.extend({}, $.fn.slider.defaults,options))));\r
365                         }\r
366                         if (typeof option == 'string') {\r
367                                 data[option](val);\r
368                         }\r
369                 })\r
370         };\r
371 \r
372         $.fn.slider.defaults = {\r
373                 min: 0,\r
374                 max: 10,\r
375                 step: 1,\r
376                 orientation: 'horizontal',\r
377                 value: 5,\r
378                 selection: 'before',\r
379                 tooltip: 'show',\r
380                 handle: 'round',\r
381                 formater: function(value) {\r
382                         return value;\r
383                 }\r
384         };\r
385 \r
386         $.fn.slider.Constructor = Slider;\r
387 \r
388 }( window.jQuery );