diff --git a/.DS_Store b/.DS_Store new file mode 100644 index 0000000..ba3b77f Binary files /dev/null and b/.DS_Store differ diff --git a/css/simple-slider.css b/css/simple-slider.css index 7d6cded..484d462 100644 --- a/css/simple-slider.css +++ b/css/simple-slider.css @@ -41,4 +41,46 @@ border: 1px solid #aaa; height: 4px; -} \ No newline at end of file +} + +.slider .tooltip { + background-color: #72A307; + border-radius: 3px; + color: #fff; + left: 100%; + margin-left: 15px; + padding: 1px 4px; + position: absolute; +} + +.slider > .tooltip::before { + background-color: #72A307; + content: ''; + display: block; + height: 7px; + left: -3px; + position: absolute; + top: 5px; + width: 7px; + -webkit-transform: rotate(45deg); + -moz-transform: rotate(45deg); + -o-transform: rotate(45deg); + -ms-transform: rotate(45deg); + transform: rotate(45deg); +} + +/** + * These are styles for when we're on a touch-capable device where we'd prefer + * a larger dragger + */ +html.touch .slider > .dragger { + -webkit-border-radius: 10px; + -moz-border-radius: 10px; + border-radius: 20px; + height: 32px; + width: 32px; +} + +html.touch .slider > .tooltip { + top: 8px; +} diff --git a/js/simple-slider.coffee b/js/simple-slider.coffee index e2fed31..d353a98 100644 --- a/js/simple-slider.coffee +++ b/js/simple-slider.coffee @@ -8,6 +8,12 @@ (($, window) -> + # Adds a class 'touch' to the HTML tag if this is a touch-capable device, + # this allows our CSS to respond accordingly and, in this case, make the + # size of the dragger 2X the size. + if 'ontouchstart' in window + $('html').addClass 'touch' + # # Main slider class # @@ -38,6 +44,10 @@ userSelect: "none" boxSizing: "border-box" .insertBefore @input + if @settings.tooltip + @tooltip = $("
").addClass("tooltip") + @slider.append( @.tooltip) + @displayValue(Number(@input.val())) @slider.attr("id", @input.attr("id") + "-slider") if @input.attr("id") # Create the track @@ -65,7 +75,7 @@ @slider.css minHeight: @dragger.outerHeight() marginLeft: @dragger.outerWidth()/2 - marginRight: @dragger.outerWidth()/2 + marginRight: @dragger.outerWidth()/2 + (56 if @settings.tooltip) @track.css marginTop: @track.outerHeight()/-2 @@ -74,54 +84,78 @@ marginTop: @dragger.outerWidth()/-2 marginLeft: @dragger.outerWidth()/-2 - # Hook up drag/drop mouse events - @track - .mousedown (e) => - return unless e.which == 1 - @domDrag(e.pageX, e.pageY, true) - @dragging = true - false + # Hook up drag/drop mouse events AND touch events. Note, we use 'on' + # rather than 'bind', so this requires a more recent version of + # jQuery/Zepto. + + @track.on 'touchstart mousedown', (evt) => + + # If this mouse down isn’t the left mouse button, ignore it. Also, If + # this is a mousedown event, we must preventDefault to prevent + # interacting accidentally with page content. We MUST allow the + # default action, however for touch-based input, otherwise, it will + # interfere with other gestures (page-scroll, pinch-to-zoom, etc.) + + if evt.type == "mousedown" + unless evt.which is 1 + return + evt.preventDefault() + + @domDrag(evt, true) + @dragging = true + + + @dragger.on 'touchstart mousedown', (evt) => - @dragger - .mousedown (e) => - return unless e.which == 1 + # See note above re: preventDefault() and left mouse button + if evt.type is "mousedown" + unless evt.which is 1 + return + evt.preventDefault() - # We've started moving - @dragging = true - @dragger.addClass "dragging" + # We've started moving + @dragging = true + @dragger.addClass "dragging" + # Update the slider position + @domDrag(evt, true) + + false + + + $("body").on 'touchmove mousemove', (evt) => + + # See note above re: preventDefault() + if evt.type is "mousemove" + evt.preventDefault(); + + if @dragging # Update the slider position - @domDrag(e.pageX, e.pageY) + @domDrag(evt) - false + # Always show a pointer when dragging + $("body").css cursor: "pointer" - $("body") - .mousemove (e) => - if @dragging - # Update the slider position - @domDrag(e.pageX, e.pageY) - # Always show a pointer when dragging - $("body").css cursor: "pointer" + $("body").on 'touchend mouseup', () => + if @dragging + # Finished dragging + @dragging = false + @dragger.removeClass "dragging" - .mouseup (e) => - if @dragging - # Finished dragging - @dragging = false - @dragger.removeClass "dragging" + # Revert the cursor + $("body").css cursor: "auto" - # Revert the cursor - $("body").css cursor: "auto" # Set slider initial position @pagePos = 0 - + # Fill in initial slider value if @input.val() == "" @value = @getRange().min - @input.val(@value) + @displayValue(@value) else @value = @nearestValidValue(@input.val()) @@ -129,12 +163,23 @@ # We are ready to go ratio = @valueToRatio(@value) - @input.trigger "slider:ready", + @input.trigger "slider:ready", value: @value ratio: ratio position: ratio * @slider.outerWidth() el: @slider + # Displays the value appropriately for the step value, if any, given. + displayValue: (value) -> + # If there is no step value, then we leave the value untouched. + # This will allow a default slider from 0->1 to work as it did previously. + if @settings.step && !isNaN(@settings.step) + precision = Math.max(0, Math.ceil(Math.log(1/@settings.step)/Math.log(10))); + value = value.toFixed(precision) + if (this.tooltip) + @tooltip.text(value) + @input.val(value) + # Set the ratio (value between 0 and 1) of the slider. # Exposed via el.slider("setRatio", ratio) setRatio: (ratio) -> @@ -167,7 +212,20 @@ @valueChanged(value, ratio, "setValue") # Respond to a dom drag event - domDrag: (pageX, pageY, animate=false) -> + domDrag: (evt, animate=false) -> + # jQuery users + if evt.originalEvent && evt.originalEvent.touches + {pageX, pageY} = evt.originalEvent.touches[0] + + # For Zepto users + else if evt.touches + {pageX, pageY} = evt.touches[0] + + # Not really sure when this would ever be used, but it probably should + # be here. + else + {pageX, pageY} = evt + # Normalize position within allowed range pagePos = pageX - @slider.offset().left pagePos = Math.min(@slider.outerWidth(), pagePos) @@ -189,7 +247,7 @@ @setSliderPositionFromValue(value, animate) else @setSliderPosition(pagePos, animate) - + # Set the slider position given a slider canvas position setSliderPosition: (position, animate=false) -> if animate and @settings.animate @@ -201,7 +259,7 @@ setSliderPositionFromValue: (value, animate=false) -> # Get the slide ratio from the value ratio = @valueToRatio(value) - + # Set the slider position @setSliderPosition(ratio * @slider.outerWidth(), animate) @@ -231,7 +289,7 @@ $.each @settings.allowedValues, -> if closest == null || Math.abs(this - rawValue) < Math.abs(closest - rawValue) closest = this - + return closest else if @settings.step maxSteps = (range.max - range.min) / @settings.step @@ -244,7 +302,7 @@ # Convert a value to a ratio valueToRatio: (value) -> - if @settings.equalSteps + if @settings.equalSteps # Get slider ratio for equal-step for allowedVal, idx in @settings.allowedValues if !closest? || Math.abs(allowedVal - value) < Math.abs(closest - value) @@ -255,7 +313,7 @@ (closestIdx+0.5)/@settings.allowedValues.length else (closestIdx)/(@settings.allowedValues.length - 1) - + else # Get slider ratio for continuous values range = @getRange() @@ -283,15 +341,16 @@ @value = value # Construct event data and fire event - eventData = + eventData = value: value ratio: ratio position: ratio * @slider.outerWidth() trigger: trigger el: @slider + @displayValue(value); + @input - .val(value) .trigger($.Event("change", eventData)) .trigger("slider:changed", eventData) @@ -306,7 +365,7 @@ $(this).each -> if settingsOrMethod and settingsOrMethod in publicMethods obj = $(this).data("slider-object") - + obj[settingsOrMethod].apply(obj, params) else settings = settingsOrMethod @@ -328,6 +387,7 @@ settings.allowedValues = (parseFloat(x) for x in allowedValues.split(",")) if allowedValues settings.range = $el.data("slider-range").split(",") if $el.data("slider-range") settings.step = $el.data("slider-step") if $el.data("slider-step") + settings.tooltip = $el.data("slider-tooltip") if $el.data("slider-tooltip") settings.snap = $el.data("slider-snap") settings.equalSteps = $el.data("slider-equal-steps") settings.theme = $el.data("slider-theme") if $el.data("slider-theme") diff --git a/js/simple-slider.js b/js/simple-slider.js index f114f90..8efe3e5 100644 --- a/js/simple-slider.js +++ b/js/simple-slider.js @@ -1,3 +1,5 @@ +// Generated by CoffeeScript 1.6.1 + /* jQuery Simple Slider @@ -6,320 +8,364 @@ Licensed under the MIT license (http://mit-license.org/) */ -var __slice = [].slice, - __indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; }; -(function($, window) { - var SimpleSlider; - SimpleSlider = (function() { +(function() { + var __indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; }, + __slice = [].slice; - function SimpleSlider(input, options) { - var ratio, - _this = this; - this.input = input; - this.defaultOptions = { - animate: true, - snapMid: false, - classPrefix: null, - classSuffix: null, - theme: null - }; - this.settings = $.extend({}, this.defaultOptions, options); - if (this.settings.theme) { - this.settings.classSuffix = "-" + this.settings.theme; - } - this.input.hide(); - this.slider = $("
").addClass("slider" + (this.settings.classSuffix || "")).css({ - position: "relative", - userSelect: "none", - boxSizing: "border-box" - }).insertBefore(this.input); - if (this.input.attr("id")) { - this.slider.attr("id", this.input.attr("id") + "-slider"); - } - this.track = $("
").addClass("track").css({ - position: "absolute", - top: "50%", - width: "100%", - userSelect: "none", - cursor: "pointer" - }).appendTo(this.slider); - this.dragger = $("
").addClass("dragger").css({ - position: "absolute", - top: "50%", - userSelect: "none", - cursor: "pointer" - }).appendTo(this.slider); - this.slider.css({ - minHeight: this.dragger.outerHeight(), - marginLeft: this.dragger.outerWidth() / 2, - marginRight: this.dragger.outerWidth() / 2 - }); - this.track.css({ - marginTop: this.track.outerHeight() / -2 - }); - this.dragger.css({ - marginTop: this.dragger.outerWidth() / -2, - marginLeft: this.dragger.outerWidth() / -2 - }); - this.track.mousedown(function(e) { - if (e.which !== 1) { - return; + (function($, window) { + var SimpleSlider; + if (__indexOf.call(window, 'ontouchstart') >= 0) { + $('html').addClass('touch'); + } + SimpleSlider = (function() { + + function SimpleSlider(input, options) { + var ratio, + _this = this; + this.input = input; + this.defaultOptions = { + animate: true, + snapMid: false, + classPrefix: null, + classSuffix: null, + theme: null + }; + this.settings = $.extend({}, this.defaultOptions, options); + if (this.settings.theme) { + this.settings.classSuffix = "-" + this.settings.theme; } - _this.domDrag(e.pageX, e.pageY, true); - _this.dragging = true; - return false; - }); - this.dragger.mousedown(function(e) { - if (e.which !== 1) { - return; + this.input.hide(); + this.slider = $("
").addClass("slider" + (this.settings.classSuffix || "")).css({ + position: "relative", + userSelect: "none", + boxSizing: "border-box" + }).insertBefore(this.input); + if (this.settings.tooltip) { + this.tooltip = $("
").addClass("tooltip"); + this.slider.append(this.tooltip); + this.displayValue(Number(this.input.val())); } - _this.dragging = true; - _this.dragger.addClass("dragging"); - _this.domDrag(e.pageX, e.pageY); - return false; - }); - $("body").mousemove(function(e) { - if (_this.dragging) { - _this.domDrag(e.pageX, e.pageY); - return $("body").css({ - cursor: "pointer" - }); + if (this.input.attr("id")) { + this.slider.attr("id", this.input.attr("id") + "-slider"); } - }).mouseup(function(e) { - if (_this.dragging) { - _this.dragging = false; - _this.dragger.removeClass("dragging"); - return $("body").css({ - cursor: "auto" - }); + this.track = $("
").addClass("track").css({ + position: "absolute", + top: "50%", + width: "100%", + userSelect: "none", + cursor: "pointer" + }).appendTo(this.slider); + this.dragger = $("
").addClass("dragger").css({ + position: "absolute", + top: "50%", + userSelect: "none", + cursor: "pointer" + }).appendTo(this.slider); + this.slider.css({ + minHeight: this.dragger.outerHeight(), + marginLeft: this.dragger.outerWidth() / 2, + marginRight: this.dragger.outerWidth() / 2 + (this.settings.tooltip ? 56 : void 0) + }); + this.track.css({ + marginTop: this.track.outerHeight() / -2 + }); + this.dragger.css({ + marginTop: this.dragger.outerWidth() / -2, + marginLeft: this.dragger.outerWidth() / -2 + }); + this.track.on('touchstart mousedown', function(evt) { + if (evt.type === "mousedown") { + if (evt.which !== 1) { + return; + } + evt.preventDefault(); + } + _this.domDrag(evt, true); + return _this.dragging = true; + }); + this.dragger.on('touchstart mousedown', function(evt) { + if (evt.type === "mousedown") { + if (evt.which !== 1) { + return; + } + evt.preventDefault(); + } + _this.dragging = true; + _this.dragger.addClass("dragging"); + _this.domDrag(evt, true); + return false; + }); + $("body").on('touchmove mousemove', function(evt) { + if (evt.type === "mousemove") { + evt.preventDefault(); + } + if (_this.dragging) { + _this.domDrag(evt); + return $("body").css({ + cursor: "pointer" + }); + } + }); + $("body").on('touchend mouseup', function() { + if (_this.dragging) { + _this.dragging = false; + _this.dragger.removeClass("dragging"); + return $("body").css({ + cursor: "auto" + }); + } + }); + this.pagePos = 0; + if (this.input.val() === "") { + this.value = this.getRange().min; + this.displayValue(this.value); + } else { + this.value = this.nearestValidValue(this.input.val()); } - }); - this.pagePos = 0; - if (this.input.val() === "") { - this.value = this.getRange().min; - this.input.val(this.value); - } else { - this.value = this.nearestValidValue(this.input.val()); + this.setSliderPositionFromValue(this.value); + ratio = this.valueToRatio(this.value); + this.input.trigger("slider:ready", { + value: this.value, + ratio: ratio, + position: ratio * this.slider.outerWidth(), + el: this.slider + }); } - this.setSliderPositionFromValue(this.value); - ratio = this.valueToRatio(this.value); - this.input.trigger("slider:ready", { - value: this.value, - ratio: ratio, - position: ratio * this.slider.outerWidth(), - el: this.slider - }); - } - SimpleSlider.prototype.setRatio = function(ratio) { - var value; - ratio = Math.min(1, ratio); - ratio = Math.max(0, ratio); - value = this.ratioToValue(ratio); - this.setSliderPositionFromValue(value); - return this.valueChanged(value, ratio, "setRatio"); - }; - - SimpleSlider.prototype.setValue = function(value) { - var ratio; - value = this.nearestValidValue(value); - ratio = this.valueToRatio(value); - this.setSliderPositionFromValue(value); - return this.valueChanged(value, ratio, "setValue"); - }; + SimpleSlider.prototype.displayValue = function(value) { + var precision; + if (this.settings.step && !isNaN(this.settings.step)) { + precision = Math.max(0, Math.ceil(Math.log(1 / this.settings.step) / Math.log(10))); + value = value.toFixed(precision); + } + if (this.tooltip) { + this.tooltip.text(value); + } + return this.input.val(value); + }; - SimpleSlider.prototype.domDrag = function(pageX, pageY, animate) { - var pagePos, ratio, value; - if (animate == null) { - animate = false; - } - pagePos = pageX - this.slider.offset().left; - pagePos = Math.min(this.slider.outerWidth(), pagePos); - pagePos = Math.max(0, pagePos); - if (this.pagePos !== pagePos) { - this.pagePos = pagePos; - ratio = pagePos / this.slider.outerWidth(); + SimpleSlider.prototype.setRatio = function(ratio) { + var value; + ratio = Math.min(1, ratio); + ratio = Math.max(0, ratio); value = this.ratioToValue(ratio); - this.valueChanged(value, ratio, "domDrag"); - if (this.settings.snap) { - return this.setSliderPositionFromValue(value, animate); + this.setSliderPositionFromValue(value); + return this.valueChanged(value, ratio, "setRatio"); + }; + + SimpleSlider.prototype.setValue = function(value) { + var ratio; + value = this.nearestValidValue(value); + ratio = this.valueToRatio(value); + this.setSliderPositionFromValue(value); + return this.valueChanged(value, ratio, "setValue"); + }; + + SimpleSlider.prototype.domDrag = function(evt, animate) { + var pagePos, pageX, pageY, ratio, value, _ref, _ref1; + if (animate == null) { + animate = false; + } + if (evt.originalEvent && evt.originalEvent.touches) { + _ref = evt.originalEvent.touches[0], pageX = _ref.pageX, pageY = _ref.pageY; + } else if (evt.touches) { + _ref1 = evt.touches[0], pageX = _ref1.pageX, pageY = _ref1.pageY; } else { - return this.setSliderPosition(pagePos, animate); + pageX = evt.pageX, pageY = evt.pageY; } - } - }; + pagePos = pageX - this.slider.offset().left; + pagePos = Math.min(this.slider.outerWidth(), pagePos); + pagePos = Math.max(0, pagePos); + if (this.pagePos !== pagePos) { + this.pagePos = pagePos; + ratio = pagePos / this.slider.outerWidth(); + value = this.ratioToValue(ratio); + this.valueChanged(value, ratio, "domDrag"); + if (this.settings.snap) { + return this.setSliderPositionFromValue(value, animate); + } else { + return this.setSliderPosition(pagePos, animate); + } + } + }; - SimpleSlider.prototype.setSliderPosition = function(position, animate) { - if (animate == null) { - animate = false; - } - if (animate && this.settings.animate) { - return this.dragger.animate({ - left: position - }, 200); - } else { - return this.dragger.css({ - left: position - }); - } - }; + SimpleSlider.prototype.setSliderPosition = function(position, animate) { + if (animate == null) { + animate = false; + } + if (animate && this.settings.animate) { + return this.dragger.animate({ + left: position + }, 200); + } else { + return this.dragger.css({ + left: position + }); + } + }; - SimpleSlider.prototype.setSliderPositionFromValue = function(value, animate) { - var ratio; - if (animate == null) { - animate = false; - } - ratio = this.valueToRatio(value); - return this.setSliderPosition(ratio * this.slider.outerWidth(), animate); - }; + SimpleSlider.prototype.setSliderPositionFromValue = function(value, animate) { + var ratio; + if (animate == null) { + animate = false; + } + ratio = this.valueToRatio(value); + return this.setSliderPosition(ratio * this.slider.outerWidth(), animate); + }; - SimpleSlider.prototype.getRange = function() { - if (this.settings.allowedValues) { - return { - min: Math.min.apply(Math, this.settings.allowedValues), - max: Math.max.apply(Math, this.settings.allowedValues) - }; - } else if (this.settings.range) { - return { - min: parseFloat(this.settings.range[0]), - max: parseFloat(this.settings.range[1]) - }; - } else { - return { - min: 0, - max: 1 - }; - } - }; + SimpleSlider.prototype.getRange = function() { + if (this.settings.allowedValues) { + return { + min: Math.min.apply(Math, this.settings.allowedValues), + max: Math.max.apply(Math, this.settings.allowedValues) + }; + } else if (this.settings.range) { + return { + min: parseFloat(this.settings.range[0]), + max: parseFloat(this.settings.range[1]) + }; + } else { + return { + min: 0, + max: 1 + }; + } + }; - SimpleSlider.prototype.nearestValidValue = function(rawValue) { - var closest, maxSteps, range, steps; - range = this.getRange(); - rawValue = Math.min(range.max, rawValue); - rawValue = Math.max(range.min, rawValue); - if (this.settings.allowedValues) { - closest = null; - $.each(this.settings.allowedValues, function() { - if (closest === null || Math.abs(this - rawValue) < Math.abs(closest - rawValue)) { - return closest = this; + SimpleSlider.prototype.nearestValidValue = function(rawValue) { + var closest, maxSteps, range, steps; + range = this.getRange(); + rawValue = Math.min(range.max, rawValue); + rawValue = Math.max(range.min, rawValue); + if (this.settings.allowedValues) { + closest = null; + $.each(this.settings.allowedValues, function() { + if (closest === null || Math.abs(this - rawValue) < Math.abs(closest - rawValue)) { + return closest = this; + } + }); + return closest; + } else if (this.settings.step) { + maxSteps = (range.max - range.min) / this.settings.step; + steps = Math.floor((rawValue - range.min) / this.settings.step); + if ((rawValue - range.min) % this.settings.step > this.settings.step / 2 && steps < maxSteps) { + steps += 1; } - }); - return closest; - } else if (this.settings.step) { - maxSteps = (range.max - range.min) / this.settings.step; - steps = Math.floor((rawValue - range.min) / this.settings.step); - if ((rawValue - range.min) % this.settings.step > this.settings.step / 2 && steps < maxSteps) { - steps += 1; + return steps * this.settings.step + range.min; + } else { + return rawValue; } - return steps * this.settings.step + range.min; - } else { - return rawValue; - } - }; + }; - SimpleSlider.prototype.valueToRatio = function(value) { - var allowedVal, closest, closestIdx, idx, range, _i, _len, _ref; - if (this.settings.equalSteps) { - _ref = this.settings.allowedValues; - for (idx = _i = 0, _len = _ref.length; _i < _len; idx = ++_i) { - allowedVal = _ref[idx]; - if (!(typeof closest !== "undefined" && closest !== null) || Math.abs(allowedVal - value) < Math.abs(closest - value)) { - closest = allowedVal; - closestIdx = idx; + SimpleSlider.prototype.valueToRatio = function(value) { + var allowedVal, closest, closestIdx, idx, range, _i, _len, _ref; + if (this.settings.equalSteps) { + _ref = this.settings.allowedValues; + for (idx = _i = 0, _len = _ref.length; _i < _len; idx = ++_i) { + allowedVal = _ref[idx]; + if ((typeof closest === "undefined" || closest === null) || Math.abs(allowedVal - value) < Math.abs(closest - value)) { + closest = allowedVal; + closestIdx = idx; + } + } + if (this.settings.snapMid) { + return (closestIdx + 0.5) / this.settings.allowedValues.length; + } else { + return closestIdx / (this.settings.allowedValues.length - 1); } - } - if (this.settings.snapMid) { - return (closestIdx + 0.5) / this.settings.allowedValues.length; } else { - return closestIdx / (this.settings.allowedValues.length - 1); + range = this.getRange(); + return (value - range.min) / (range.max - range.min); } - } else { - range = this.getRange(); - return (value - range.min) / (range.max - range.min); - } - }; + }; - SimpleSlider.prototype.ratioToValue = function(ratio) { - var idx, range, rawValue, step, steps; - if (this.settings.equalSteps) { - steps = this.settings.allowedValues.length; - step = Math.round(ratio * steps - 0.5); - idx = Math.min(step, this.settings.allowedValues.length - 1); - return this.settings.allowedValues[idx]; - } else { - range = this.getRange(); - rawValue = ratio * (range.max - range.min) + range.min; - return this.nearestValidValue(rawValue); - } - }; + SimpleSlider.prototype.ratioToValue = function(ratio) { + var idx, range, rawValue, step, steps; + if (this.settings.equalSteps) { + steps = this.settings.allowedValues.length; + step = Math.round(ratio * steps - 0.5); + idx = Math.min(step, this.settings.allowedValues.length - 1); + return this.settings.allowedValues[idx]; + } else { + range = this.getRange(); + rawValue = ratio * (range.max - range.min) + range.min; + return this.nearestValidValue(rawValue); + } + }; - SimpleSlider.prototype.valueChanged = function(value, ratio, trigger) { - var eventData; - if (value.toString() === this.value.toString()) { - return; - } - this.value = value; - eventData = { - value: value, - ratio: ratio, - position: ratio * this.slider.outerWidth(), - trigger: trigger, - el: this.slider + SimpleSlider.prototype.valueChanged = function(value, ratio, trigger) { + var eventData; + if (value.toString() === this.value.toString()) { + return; + } + this.value = value; + eventData = { + value: value, + ratio: ratio, + position: ratio * this.slider.outerWidth(), + trigger: trigger, + el: this.slider + }; + this.displayValue(value); + return this.input.trigger($.Event("change", eventData)).trigger("slider:changed", eventData); }; - return this.input.val(value).trigger($.Event("change", eventData)).trigger("slider:changed", eventData); - }; - return SimpleSlider; + return SimpleSlider; - })(); - $.extend($.fn, { - simpleSlider: function() { - var params, publicMethods, settingsOrMethod; - settingsOrMethod = arguments[0], params = 2 <= arguments.length ? __slice.call(arguments, 1) : []; - publicMethods = ["setRatio", "setValue"]; - return $(this).each(function() { - var obj, settings; - if (settingsOrMethod && __indexOf.call(publicMethods, settingsOrMethod) >= 0) { - obj = $(this).data("slider-object"); - return obj[settingsOrMethod].apply(obj, params); - } else { - settings = settingsOrMethod; - return $(this).data("slider-object", new SimpleSlider($(this), settings)); - } - }); - } - }); - return $(function() { - return $("[data-slider]").each(function() { - var $el, allowedValues, settings, x; - $el = $(this); - settings = {}; - allowedValues = $el.data("slider-values"); - if (allowedValues) { - settings.allowedValues = (function() { - var _i, _len, _ref, _results; - _ref = allowedValues.split(","); - _results = []; - for (_i = 0, _len = _ref.length; _i < _len; _i++) { - x = _ref[_i]; - _results.push(parseFloat(x)); + })(); + $.extend($.fn, { + simpleSlider: function() { + var params, publicMethods, settingsOrMethod; + settingsOrMethod = arguments[0], params = 2 <= arguments.length ? __slice.call(arguments, 1) : []; + publicMethods = ["setRatio", "setValue"]; + return $(this).each(function() { + var obj, settings; + if (settingsOrMethod && __indexOf.call(publicMethods, settingsOrMethod) >= 0) { + obj = $(this).data("slider-object"); + return obj[settingsOrMethod].apply(obj, params); + } else { + settings = settingsOrMethod; + return $(this).data("slider-object", new SimpleSlider($(this), settings)); } - return _results; - })(); - } - if ($el.data("slider-range")) { - settings.range = $el.data("slider-range").split(","); - } - if ($el.data("slider-step")) { - settings.step = $el.data("slider-step"); - } - settings.snap = $el.data("slider-snap"); - settings.equalSteps = $el.data("slider-equal-steps"); - if ($el.data("slider-theme")) { - settings.theme = $el.data("slider-theme"); + }); } - return $el.simpleSlider(settings); }); - }); -})(this.jQuery || this.Zepto, this); + return $(function() { + return $("[data-slider]").each(function() { + var $el, allowedValues, settings, x; + $el = $(this); + settings = {}; + allowedValues = $el.data("slider-values"); + if (allowedValues) { + settings.allowedValues = (function() { + var _i, _len, _ref, _results; + _ref = allowedValues.split(","); + _results = []; + for (_i = 0, _len = _ref.length; _i < _len; _i++) { + x = _ref[_i]; + _results.push(parseFloat(x)); + } + return _results; + })(); + } + if ($el.data("slider-range")) { + settings.range = $el.data("slider-range").split(","); + } + if ($el.data("slider-step")) { + settings.step = $el.data("slider-step"); + } + if ($el.data("slider-tooltip")) { + settings.tooltip = $el.data("slider-tooltip"); + } + settings.snap = $el.data("slider-snap"); + settings.equalSteps = $el.data("slider-equal-steps"); + if ($el.data("slider-theme")) { + settings.theme = $el.data("slider-theme"); + } + return $el.simpleSlider(settings); + }); + }); + })(this.jQuery || this.Zepto, this); + +}).call(this); diff --git a/js/simple-slider.min.js b/js/simple-slider.min.js index 349b791..09bc93b 100644 --- a/js/simple-slider.min.js +++ b/js/simple-slider.min.js @@ -1,11 +1,8 @@ +// Generated by CoffeeScript 1.6.1 /* - * jQuery Simple Slider: Unobtrusive Numerical Slider - * Version 1.0.0 - * - * Copyright (c) 2013 James Smith (http://loopj.com) - * - * Licensed under the MIT license (http://mit-license.org/) - * - */ + jQuery Simple Slider -var __slice=[].slice,__indexOf=[].indexOf||function(e){for(var t=0,n=this.length;t").addClass("slider"+(this.settings.classSuffix||"")).css({position:"relative",userSelect:"none",boxSizing:"border-box"}).insertBefore(this.input),this.input.attr("id")&&this.slider.attr("id",this.input.attr("id")+"-slider"),this.track=e("
").addClass("track").css({position:"absolute",top:"50%",width:"100%",userSelect:"none",cursor:"pointer"}).appendTo(this.slider),this.dragger=e("
").addClass("dragger").css({position:"absolute",top:"50%",userSelect:"none",cursor:"pointer"}).appendTo(this.slider),this.slider.css({minHeight:this.dragger.outerHeight(),marginLeft:this.dragger.outerWidth()/2,marginRight:this.dragger.outerWidth()/2}),this.track.css({marginTop:this.track.outerHeight()/-2}),this.dragger.css({marginTop:this.dragger.outerWidth()/-2,marginLeft:this.dragger.outerWidth()/-2}),this.track.mousedown(function(e){if(e.which!==1)return;return i.domDrag(e.pageX,e.pageY,!0),i.dragging=!0,!1}),this.dragger.mousedown(function(e){if(e.which!==1)return;return i.dragging=!0,i.dragger.addClass("dragging"),i.domDrag(e.pageX,e.pageY),!1}),e("body").mousemove(function(t){if(i.dragging)return i.domDrag(t.pageX,t.pageY),e("body").css({cursor:"pointer"})}).mouseup(function(t){if(i.dragging)return i.dragging=!1,i.dragger.removeClass("dragging"),e("body").css({cursor:"auto"})}),this.pagePos=0,this.input.val()===""?(this.value=this.getRange().min,this.input.val(this.value)):this.value=this.nearestValidValue(this.input.val()),this.setSliderPositionFromValue(this.value),r=this.valueToRatio(this.value),this.input.trigger("slider:ready",{value:this.value,ratio:r,position:r*this.slider.outerWidth(),el:this.slider})}return t.prototype.setRatio=function(e){var t;return e=Math.min(1,e),e=Math.max(0,e),t=this.ratioToValue(e),this.setSliderPositionFromValue(t),this.valueChanged(t,e,"setRatio")},t.prototype.setValue=function(e){var t;return e=this.nearestValidValue(e),t=this.valueToRatio(e),this.setSliderPositionFromValue(e),this.valueChanged(e,t,"setValue")},t.prototype.domDrag=function(e,t,n){var r,i,s;n==null&&(n=!1),r=e-this.slider.offset().left,r=Math.min(this.slider.outerWidth(),r),r=Math.max(0,r);if(this.pagePos!==r)return this.pagePos=r,i=r/this.slider.outerWidth(),s=this.ratioToValue(i),this.valueChanged(s,i,"domDrag"),this.settings.snap?this.setSliderPositionFromValue(s,n):this.setSliderPosition(r,n)},t.prototype.setSliderPosition=function(e,t){return t==null&&(t=!1),t&&this.settings.animate?this.dragger.animate({left:e},200):this.dragger.css({left:e})},t.prototype.setSliderPositionFromValue=function(e,t){var n;return t==null&&(t=!1),n=this.valueToRatio(e),this.setSliderPosition(n*this.slider.outerWidth(),t)},t.prototype.getRange=function(){return this.settings.allowedValues?{min:Math.min.apply(Math,this.settings.allowedValues),max:Math.max.apply(Math,this.settings.allowedValues)}:this.settings.range?{min:parseFloat(this.settings.range[0]),max:parseFloat(this.settings.range[1])}:{min:0,max:1}},t.prototype.nearestValidValue=function(t){var n,r,i,s;return i=this.getRange(),t=Math.min(i.max,t),t=Math.max(i.min,t),this.settings.allowedValues?(n=null,e.each(this.settings.allowedValues,function(){if(n===null||Math.abs(this-t)this.settings.step/2&&s=0?(s=e(this).data("slider-object"),s[i].apply(s,t)):(o=i,e(this).data("slider-object",new n(e(this),o)))})}}),e(function(){return e("[data-slider]").each(function(){var t,n,r,i;return t=e(this),r={},n=t.data("slider-values"),n&&(r.allowedValues=function(){var e,t,r,s;r=n.split(","),s=[];for(e=0,t=r.length;e").addClass("slider"+(this.settings.classSuffix||"")).css({position:"relative",userSelect:"none",boxSizing:"border-box"}).insertBefore(this.input);this.input.attr("id")&&this.slider.attr("id",this.input.attr("id")+"-slider");this.track=n("
").addClass("track").css({position:"absolute",top:"50%",width:"100%",userSelect:"none",cursor:"pointer"}).appendTo(this.slider);this.dragger=n("
").addClass("dragger").css({position:"absolute",top:"50%",userSelect:"none",cursor:"pointer"}).appendTo(this.slider);this.slider.css({minHeight:this.dragger.outerHeight(),marginLeft:this.dragger.outerWidth()/2,marginRight:this.dragger.outerWidth()/2});this.track.css({marginTop:this.track.outerHeight()/-2});this.dragger.css({marginTop:this.dragger.outerWidth()/-2,marginLeft:this.dragger.outerWidth()/-2});this.track.mousedown(function(e){if(e.which!==1)return;i.domDrag(e.pageX,e.pageY,!0);i.dragging=!0;return!1});this.dragger.mousedown(function(e){if(e.which!==1)return;i.dragging=!0;i.dragger.addClass("dragging");i.domDrag(e.pageX,e.pageY);return!1});n("body").mousemove(function(e){if(i.dragging){i.domDrag(e.pageX,e.pageY);return n("body").css({cursor:"pointer"})}}).mouseup(function(e){if(i.dragging){i.dragging=!1;i.dragger.removeClass("dragging");return n("body").css({cursor:"auto"})}});this.pagePos=0;if(this.input.val()===""){this.value=this.getRange().min;this.input.val(this.value)}else this.value=this.nearestValidValue(this.input.val());this.setSliderPositionFromValue(this.value);r=this.valueToRatio(this.value);this.input.trigger("slider:ready",{value:this.value,ratio:r,position:r*this.slider.outerWidth(),el:this.slider})}e.prototype.setRatio=function(e){var t;e=Math.min(1,e);e=Math.max(0,e);t=this.ratioToValue(e);this.setSliderPositionFromValue(t);return this.valueChanged(t,e,"setRatio")};e.prototype.setValue=function(e){var t;e=this.nearestValidValue(e);t=this.valueToRatio(e);this.setSliderPositionFromValue(e);return this.valueChanged(e,t,"setValue")};e.prototype.domDrag=function(e,t,n){var r,i,s;n==null&&(n=!1);r=e-this.slider.offset().left;r=Math.min(this.slider.outerWidth(),r);r=Math.max(0,r);if(this.pagePos!==r){this.pagePos=r;i=r/this.slider.outerWidth();s=this.ratioToValue(i);this.valueChanged(s,i,"domDrag");return this.settings.snap?this.setSliderPositionFromValue(s,n):this.setSliderPosition(r,n)}};e.prototype.setSliderPosition=function(e,t){t==null&&(t=!1);return t&&this.settings.animate?this.dragger.animate({left:e},200):this.dragger.css({left:e})};e.prototype.setSliderPositionFromValue=function(e,t){var n;t==null&&(t=!1);n=this.valueToRatio(e);return this.setSliderPosition(n*this.slider.outerWidth(),t)};e.prototype.getRange=function(){return this.settings.allowedValues?{min:Math.min.apply(Math,this.settings.allowedValues),max:Math.max.apply(Math,this.settings.allowedValues)}:this.settings.range?{min:parseFloat(this.settings.range[0]),max:parseFloat(this.settings.range[1])}:{min:0,max:1}};e.prototype.nearestValidValue=function(e){var t,r,i,s;i=this.getRange();e=Math.min(i.max,e);e=Math.max(i.min,e);if(this.settings.allowedValues){t=null;n.each(this.settings.allowedValues,function(){if(t===null||Math.abs(this-e)this.settings.step/2&&s=0){e=n(this).data("slider-object");return e[o].apply(e,r)}u=o;return n(this).data("slider-object",new i(n(this),u))})}});return n(function(){return n("[data-slider]").each(function(){var e,t,r,i;e=n(this);r={};t=e.data("slider-values");t&&(r.allowedValues=function(){var e,n,r,s;r=t.split(",");s=[];for(e=0,n=r.length;e