/*! * jQuery Cookie Plugin v1.4.1 * https://github.com/carhartl/jquery-cookie * * Copyright 2006, 2014 Klaus Hartl * Released under the MIT license */ (function (factory) { if (typeof define === 'function' && define.amd) { // AMD (Register as an anonymous module) define(['jquery'], factory); } else if (typeof exports === 'object') { // Node/CommonJS module.exports = factory(require('jquery')); } else { // Browser globals factory(jQuery); } }(function ($) { var pluses = /\+/g; function encode(s) { return config.raw ? s : encodeURIComponent(s); } function decode(s) { return config.raw ? s : decodeURIComponent(s); } function stringifyCookieValue(value) { return encode(config.json ? JSON.stringify(value) : String(value)); } function parseCookieValue(s) { if (s.indexOf('"') === 0) { // This is a quoted cookie as according to RFC2068, unescape... s = s.slice(1, -1).replace(/\\"/g, '"').replace(/\\\\/g, '\\'); } try { // Replace server-side written pluses with spaces. // If we can't decode the cookie, ignore it, it's unusable. // If we can't parse the cookie, ignore it, it's unusable. s = decodeURIComponent(s.replace(pluses, ' ')); return config.json ? JSON.parse(s) : s; } catch(e) {} } function read(s, converter) { var value = config.raw ? s : parseCookieValue(s); return $.isFunction(converter) ? converter(value) : value; } var config = $.cookie = function (key, value, options) { // Write if (arguments.length > 1 && !$.isFunction(value)) { options = $.extend({}, config.defaults, options); if (typeof options.expires === 'number') { var days = options.expires, t = options.expires = new Date(); t.setMilliseconds(t.getMilliseconds() + days * 864e+5); } return (document.cookie = [ encode(key), '=', stringifyCookieValue(value), options.expires ? '; expires=' + options.expires.toUTCString() : '', // use expires attribute, max-age is not supported by IE options.path ? '; path=' + options.path : '', options.domain ? '; domain=' + options.domain : '', options.secure ? '; secure' : '' ].join('')); } // Read var result = key ? undefined : {}, // To prevent the for loop in the first place assign an empty array // in case there are no cookies at all. Also prevents odd result when // calling $.cookie(). cookies = document.cookie ? document.cookie.split('; ') : [], i = 0, l = cookies.length; for (; i < l; i++) { var parts = cookies[i].split('='), name = decode(parts.shift()), cookie = parts.join('='); if (key === name) { // If second argument (value) is a function it's a converter... result = read(cookie, value); break; } // Prevent storing a cookie that we couldn't decode. if (!key && (cookie = read(cookie)) !== undefined) { result[name] = cookie; } } return result; }; config.defaults = {}; $.removeCookie = function (key, options) { // Must not alter options, thus extending a fresh object... $.cookie(key, '', $.extend({}, options, { expires: -1 })); return !$.cookie(key); }; })); /* * jQuery.range - A tiny, easily styleable range selector * Tom Moor, http://tommoor.com * Copyright (c) 2011 Tom Moor * MIT Licensed * @version 1.0 */ /* * minor bug fixes (c) 2012 Martin Raspe (hertzhaft@biblhertz.it) */ (function($){ var TinyRange = function(){ // locals var options; var $input; var $rail; var $handle; var $handle2; var $selection; var $dragging; var $original; var jump; var size; var defaults = { orientation: 'horizontal', // todo range: false, values: false, snap: false, change: null, blur: null }; var jumpHandle = function(ev) { ev.pageX = ev.pageX - $input.offset().left; // get closest handle var x1 = $handle.position().left; var dist = ev.pageX - x1; if($handle2){ var x2 = $handle2.position().left; var dist2 = ev.pageX - x2; } // move towards click if(!$handle2 || Math.abs(dist) < Math.abs(dist2) ){ if(dist > 0) moveHandle($handle, valueToPx(jump)+x1); if(dist < 0) moveHandle($handle, -valueToPx(jump)+x1); } else { if(dist2 > 0) moveHandle($handle2, valueToPx(jump)+x2); if(dist2 < 0) moveHandle($handle2, -valueToPx(jump)+x2); } } var moveHandle = function($h, p, update){ var boundR = $input.width()-size; var boundL = 0; if(options.range){ if($h[0] === $handle[0]){ boundR = $handle2.position().left; } else { boundL = $handle.position().left; } } if(p >= boundR){ p = boundR; } else if(p <= boundL){ p = boundL; } // leads to erratic behaviour with "step" attribute // if(options.snap && p !== boundR){ // var snapPx = valueToPx(options.snap); // p = Math.round(p/snapPx) * snapPx; // } $h.css({'left': p, 'position': 'absolute'}); if(options.range) updateSelection(); if(update !== false) updateValues(); } var dragStart = function(ev){ ev.stopPropagation(); ev.preventDefault(); $dragging = $(this); }; var drag = function(ev){ if($dragging){ ev.preventDefault(); var pos = ev.pageX - $input.offset().left; moveHandle($dragging, pos); } }; var updateSelection = function(){ var p = $handle.position().left; var w = $handle2.position().left-p; $selection.css({ 'left': p, 'width': w, 'position': 'absolute' }); }; var dragEnd = function(ev){ if($dragging){ $dragging = null; if (options.blur == null) { // send original blur event $original.blur(); } else { options.blur(options.values); } } }; var updateValues = function(){ var prev; if(options.range){ prev = options.values.slice(); // clone options.values[0] = bound(pxToValue($handle.position().left)); options.values[1] = bound(pxToValue($handle2.position().left)); // set value on original element $original.val(options.values[0] +','+options.values[1]); } else { prev = options.values; options.values = bound(pxToValue($handle.position().left)); // set value on original element $original.val(options.values); } if(options.values !== prev) { if (options.change == null) { // trigger original change event $original.change(); } else { options.change(options.values); } } }; var updateHandles = function(){ if (options.values != null) { if (options.range){ moveHandle($handle2, valueToPx(options.values[1]), false); moveHandle($handle, valueToPx(options.values[0]), false); } else { moveHandle($handle, valueToPx(options.values), false); } } updateValues(); }; var pxToValue = function (px) { var w = $input.width() - size; var valspan = options.max - options.min; var v = px * valspan / w + options.min; if (options.snap) { var tmp = v < 0 ? Math.floor(v / options.snap) * options.snap : Math.round(v / options.snap) * options.snap; // hack to cut off floating point imprecision var result = parseFloat(tmp.toFixed(4)); return result; } return Math.round(v); }; var valueToPx = function (val) { var w = $input.width() - size; var valspan = options.max - options.min; var valpos = val - options.min; var v = valpos * w / valspan; return v; }; var bound = function(input){ return Math.max(Math.min(input, options.max), options.min); }; var methods = { init : function (o) { // element already replaced if($(this).data('TinyRange')) return this; // options defaults.min = parseFloat($(this).attr('min')); defaults.max = parseFloat($(this).attr('max')); defaults.snap = parseFloat($(this).attr('step')); // options passed into plugin override input attributes options = $.extend(defaults, o); if(options.values){ // } else if(options.range){ options.values = [0, options.max]; } else { options.values = parseFloat($(this).attr('value')); } // how far do handles jump on click, default to step value jump = options.snap ? options.snap : options.max/10; // create dom elements $input = $('
', {'class': 'range-input'}).mousedown(jumpHandle); $rail = $('', {'class': 'range-rail'}).appendTo($input); if(options.range) $selection = $('', {'class': 'range-selection'}).appendTo($input); $handle = $('', {'class': 'range-handle'}).appendTo($input).mousedown(dragStart); if(options.range) $handle2 = $handle.clone(true).appendTo($input); // replace dom element $(this).after($input); $(this).hide(); $original = $(this); // attach events $(document).bind('mouseup', dragEnd); $(document).bind('mousemove', drag); // position handles size = $handle.width(); updateHandles(); return this; }, set: function(input){ if(typeof input === 'string'){ options.values = bound(input); } else if(typeof input === 'object' && input.length === 2){ options.values[0] = bound(input[0]); options.values[1] = bound(input[1]); } updateHandles(); }, destroy : function(){ $input.remove(); $(this).show().data('TinyRange', false); $(document).unbind('mouseup', dragEnd); $(document).unbind('mousemove', drag); return this; } }; return methods; }; $.fn.range = function(method) { // so that arguments are accessible within each closure var args = arguments; return this.each(function(){ var state = $(this).data('TinyRange'); // Method calling logic if (state && state[method] ) { state[ method ].apply( this, Array.prototype.slice.call( args, 1 )); } else if ( typeof method === 'object' || ! method ) { // create new tinyrange var tr = (new TinyRange(this)); tr.init.apply( this, args ); // save state in jquery data $(this).data('TinyRange', tr); } else { $.error( 'Method ' + method + ' does not exist on jQuery.range' ); } }); }; })(jQuery);