/*! * jQuery "stepper" Plugin * version 0.0.1 * @requires jQuery v1.3.2 or later * @requires jCanvas * * Authored 2011-06-11 Scott Lahteine (thinkyhead.com) * * A very simple numerical stepper. * TODO: place arrows based on div size, make 50/50 width * * Usage example: * * $('#mydiv').jstepper({ * min: 1, * max: 4, * val: 1, * arrowWidth: 15, * arrowHeight: '22px', * color: '#FFF', * acolor: '#F70', * hcolor: '#FF0', * id: 'select-me', * stepperClass: 'inner', * textStyle: {width:'1.5em',fontSize:'20px',textAlign:'center'}, * onChange: function(v) { }, * }); * */ ;(function($) { var un = 'undefined'; $.jstepperArrows = [ { name:'prev', poly:[[1.0,0],[0,0.5],[1.0,1.0]] }, { name:'next', poly:[[0,0],[1.0,0.5],[0,1.0]] } ]; $.fn.jstepper = function(args) { return this.each(function() { var defaults = { min: 1, max: null, val: null, active: true, placeholder: null, arrowWidth: 0, arrowHeight: 0, color: '#FFF', hcolor: '#FF0', acolor: '#F80', id: '', stepperClass: '', textStyle: '', onChange: (function(v){ if (typeof console.log !== 'undefined') console.log("val="+v); }) }; args = $.extend(defaults, args || {}); var min = args.min * 1, max = (args.max !== null) ? args.max * 1 : min, span = max - min + 1, val = (args.val !== null) ? args.val * 1 : min, active = !args.disabled, placeholder = args.placeholder, arrowWidth = 1 * args.arrowWidth.toString().replace(/px/,''), arrowHeight = 1 * args.arrowHeight.toString().replace(/px/,''), color = args.color, hcolor = args.hcolor, acolor = args.acolor, $prev = $(''), $marq = $('
').css({float:'left',textAlign:'center'}), $next = $(''), arrow = [ $prev.find('canvas')[0], $next.find('canvas')[0] ], $stepper = $('').append($prev).append($marq).append($next).append(''), onChange = args.onChange; if (args.id) $stepper[0].id = args.id; if (args.stepperClass) $stepper.addClass(args.stepperClass); if (args.textStyle) $marq.css(args.textStyle); // replace a span, but embed elsewhere if (this.tagName == 'SPAN') { var previd = this.id; $(this).replaceWith($stepper); if (previd) $stepper.attr('id',previd); } else { $(this).append($stepper); } // hook to call functions on this object $stepper[0].ui = { refresh: function() { this.updateNumber(); this._drawArrow(0, 1); this._drawArrow(1, 1); return this; }, _drawArrow: function(i,state) { var $elm = $(arrow[i]), desc = $.jstepperArrows[i], fillStyle = (state == 2) ? hcolor : (state == 3) ? acolor : color, draw = { fillStyle: fillStyle }, w = $elm.width(), h = $elm.height(); if (w <= 0) w = $elm.attr('width'); if (h <= 0) h = $elm.attr('height'); $.each(desc.poly,function(i,v){ ++i; draw['x'+i] = v[0] * w; draw['y'+i] = v[1] * h; }); $elm.restoreCanvas().clearCanvas().drawLine(draw); }, updateNumber: function() { $marq.html((active || placeholder === null) ? val.toString() : placeholder); return this; }, _doclick: function(i) { this.add(i ? 1 : -1); this._drawArrow(i, 3); var self = this; setTimeout(function(){ self._drawArrow(i, 2); }, 50); }, add: function(x) { val = (((val - min) + x + span) % span) + min; this.updateNumber(); this.didChange(val); return this; }, min: function(v) { if (typeof v === un) return min; this.setRange(v,max); return this; }, max: function(v) { if (typeof v === un) return max; this.setRange(min,v); return this; }, val: function(v) { if (typeof v === un) return val; val = (((v - min) + span) % span) + min; this.updateNumber(); return this; }, setRange: function(lo, hi, ini) { if (lo > hi) hi = (lo += hi -= lo) - hi; min = lo; max = hi; span = hi - lo + 1; if (typeof ini !== un) val = ini; if (val < min) val = min; if (val > max) val = max; this.updateNumber(); return this; }, active: function(a) { if (typeof a === un) return active; (active = a) ? $marq.removeClass('inactive') : $marq.addClass('inactive'); this.updateNumber(); return this; }, disable: function() { this.active(false); return this; }, enable: function() { this.active(true); return this; }, clearPlaceholder: function() { this.setPlaceholder(null); return this; }, setPlaceholder: function(p) { placeholder = p; if (!active) this.updateNumber(); return this; }, didChange: onChange }; // set hover and click for each arrow $.each($.jstepperArrows, function(i,desc) { var $elm = $(arrow[i]), w = arrowWidth ? arrowWidth : $elm.width() ? $elm.width() : 15, h = arrowHeight ? arrowHeight : $elm.height() ? $elm.height() : 24; $elm[0]._index = i; $elm .css({float:'left'}) .attr({width:w,height:h,'class':desc.name}) .hover( function(e) { $stepper[0].ui._drawArrow(e.target._index, 2); }, function(e) { $stepper[0].ui._drawArrow(e.target._index, 1); } ) .click(function(e){ $stepper[0].ui._doclick(e.target._index); return false; }); }); // init the visuals first time $stepper[0].ui.refresh(); }); // this.each }; // $.fn.jstepper })( jQuery );