diff --git a/js/jquery.mobile.forms.slider.js b/js/jquery.mobile.forms.slider.js index db827135..ddc61c49 100644 --- a/js/jquery.mobile.forms.slider.js +++ b/js/jquery.mobile.forms.slider.js @@ -4,134 +4,159 @@ * Dual licensed under the MIT or GPL Version 2 licenses. * http://jquery.org/license */ -(function($, undefined ) { + +( function( $, undefined ) { + $.widget( "mobile.slider", $.mobile.widget, { options: { theme: null, trackTheme: null, disabled: false }, - _create: function(){ + + _create: function() { + + // TODO: Each of these should have comments explain what they're for var self = this, control = this.element, - parentTheme = control.parents('[class*=ui-bar-],[class*=ui-body-]').eq(0), + parentTheme = control.parents( "[class*='ui-bar-'],[class*='ui-body-']" ).eq( 0 ), - parentTheme = parentTheme.length ? parentTheme.attr('class').match(/ui-(bar|body)-([a-z])/)[2] : 'c', + parentTheme = parentTheme.length ? parentTheme.attr( "class" ).match( /ui-(bar|body)-([a-z])/ )[ 2 ] : "c", theme = this.options.theme ? this.options.theme : parentTheme, trackTheme = this.options.trackTheme ? this.options.trackTheme : parentTheme, - cType = control[0].nodeName.toLowerCase(), - selectClass = (cType == 'select') ? 'ui-slider-switch' : '', - controlID = control.attr('id'), - labelID = controlID + '-label', - label = $('[for="'+ controlID +'"]').attr('id',labelID), - val = function(){ - return (cType == 'input') ? parseFloat(control.val()) : control[0].selectedIndex; - }, - min = (cType == 'input') ? parseFloat(control.attr('min')) : 0, - max = (cType == 'input') ? parseFloat(control.attr('max')) : control.find('option').length-1, - step = window.parseFloat(control.attr('step') || 1), - slider = $('
'), - handle = $('') - .appendTo(slider) - .buttonMarkup({corners: true, theme: theme, shadow: true}) - .attr({ - 'role': 'slider', - 'aria-valuemin': min, - 'aria-valuemax': max, - 'aria-valuenow': val(), - 'aria-valuetext': val(), - 'title': val(), - 'aria-labelledby': labelID - }); + cType = control[ 0 ].nodeName.toLowerCase(), - $.extend(this, { + selectClass = ( cType == "select" ) ? "ui-slider-switch" : "", + + controlID = control.attr( "id" ), + + labelID = controlID + "-label", + + label = $( "[for='"+ controlID +"']" ).attr( "id", labelID ), + + val = function() { + return cType == "input" ? parseFloat( control.val() ) : control[0].selectedIndex; + }, + + min = cType == "input" ? parseFloat( control.attr( "min" ) ) : 0, + + max = cType == "input" ? parseFloat( control.attr( "max" ) ) : control.find( "option" ).length-1, + + step = window.parseFloat( control.attr( "step" ) || 1 ), + + slider = $( "
" ), + + handle = $( "" ) + .appendTo( slider ) + .buttonMarkup({ corners: true, theme: theme, shadow: true }) + .attr({ + "role": "slider", + "aria-valuemin": min, + "aria-valuemax": max, + "aria-valuenow": val(), + "aria-valuetext": val(), + "title": val(), + "aria-labelledby": labelID + }), + options; + + $.extend( this, { slider: slider, handle: handle, dragging: false, beforeStart: null }); - if(cType == 'select'){ - slider.wrapInner('
'); - var options = control.find('option'); + if ( cType == "select" ) { - control.find('option').each(function(i){ - var side = (i==0) ?'b':'a', - corners = (i==0) ? 'right' :'left', - theme = (i==0) ? ' ui-btn-down-' + trackTheme :' ui-btn-active'; - $('
').prependTo(slider); - $(''+$(this).text()+'').prependTo(handle); + slider.wrapInner( "
" ); + + options = control.find( "option" ); + + control.find( "option" ).each(function( i ) { + + var side = !i ? "b":"a", + corners = !i ? "right" :"left", + theme = !i ? " ui-btn-down-" + trackTheme :" ui-btn-active"; + + $( "
" ) + .prependTo( slider ); + + $( "" + $( this ).text() + "" ) + .prependTo( handle ); }); } - label.addClass('ui-slider'); + label.addClass( "ui-slider" ); // monitor the input for updated values - control - .addClass((cType == 'input') ? 'ui-slider-input' : 'ui-slider-switch') - .change(function(){ + control.addClass( cType === "input" ? "ui-slider-input" : "ui-slider-switch" ) + .change( function() { self.refresh( val(), true ); }) - .keyup(function(){ // necessary? + .keyup( function() { // necessary? self.refresh( val(), true, true ); }) - .blur(function(){ + .blur( function() { self.refresh( val(), true ); }); // prevent screen drag when slider activated - $(document).bind( "vmousemove", function(event){ + $( document ).bind( "vmousemove", function( event ) { if ( self.dragging ) { self.refresh( event ); return false; } }); - slider - .bind( "vmousedown", function(event){ - self.dragging = true; - if ( cType === "select" ) { - self.beforeStart = control[0].selectedIndex; - } - self.refresh( event ); - return false; - }); + slider.bind( "vmousedown", function( event ) { + self.dragging = true; - slider - .add(document) - .bind( "vmouseup", function(){ + if ( cType === "select" ) { + self.beforeStart = control[0].selectedIndex; + } + self.refresh( event ); + return false; + }); + + slider.add( document ) + .bind( "vmouseup", function() { if ( self.dragging ) { + self.dragging = false; + if ( cType === "select" ) { - if ( self.beforeStart === control[0].selectedIndex ) { - //tap occurred, but value didn't change. flip it! - self.refresh( self.beforeStart === 0 ? 1 : 0 ); + + if ( self.beforeStart === control[ 0 ].selectedIndex ) { + //tap occurred, but value didn"t change. flip it! + self.refresh( !self.beforeStart ? 1 : 0 ); } var curval = val(); - var snapped = Math.round( curval / (max - min) * 100 ); + var snapped = Math.round( curval / ( max - min ) * 100 ); handle - .addClass("ui-slider-handle-snapping") - .css("left", snapped + "%") - .animationComplete(function(){ - handle.removeClass("ui-slider-handle-snapping"); + .addClass( "ui-slider-handle-snapping" ) + .css( "left", snapped + "%" ) + .animationComplete( function() { + handle.removeClass( "ui-slider-handle-snapping" ); }); } return false; } }); - slider.insertAfter(control); + slider.insertAfter( control ); // NOTE force focus on handle this.handle - .bind( "vmousedown", function(){ - $(this).focus(); + .bind( "vmousedown", function() { + $( this ).focus(); }) .bind( "vclick", false ); @@ -165,24 +190,24 @@ $.widget( "mobile.slider", $.mobile.widget, { // move the slider according to the keypress switch ( event.keyCode ) { case $.mobile.keyCode.HOME: - self.refresh(min); + self.refresh( min ); break; case $.mobile.keyCode.END: - self.refresh(max); + self.refresh( max ); break; case $.mobile.keyCode.PAGE_UP: case $.mobile.keyCode.UP: case $.mobile.keyCode.RIGHT: - self.refresh(index + step); + self.refresh( index + step ); break; case $.mobile.keyCode.PAGE_DOWN: case $.mobile.keyCode.DOWN: case $.mobile.keyCode.LEFT: - self.refresh(index - step); + self.refresh( index - step ); break; } }) // remove active mark - .keyup(function( event ) { + .keyup( function( event ) { if ( self._keySliding ) { self._keySliding = false; $( this ).removeClass( "ui-state-active" ); @@ -192,82 +217,98 @@ $.widget( "mobile.slider", $.mobile.widget, { this.refresh(); }, - refresh: function(val, isfromControl, preventInputUpdate){ + refresh: function( val, isfromControl, preventInputUpdate ) { if ( this.options.disabled ) { return; } var control = this.element, percent, cType = control[0].nodeName.toLowerCase(), - min = (cType === "input") ? parseFloat(control.attr("min")) : 0, - max = (cType === "input") ? parseFloat(control.attr("max")) : control.find("option").length - 1; + min = cType === "input" ? parseFloat( control.attr( "min" ) ) : 0, + max = cType === "input" ? parseFloat( control.attr( "max" ) ) : control.find( "option" ).length - 1; if ( typeof val === "object" ) { var data = val, // a slight tolerance helped get to the ends of the slider tol = 8; - if ( !this.dragging - || data.pageX < this.slider.offset().left - tol - || data.pageX > this.slider.offset().left + this.slider.width() + tol ) { + if ( !this.dragging || + data.pageX < this.slider.offset().left - tol || + data.pageX > this.slider.offset().left + this.slider.width() + tol ) { return; } - percent = Math.round( ((data.pageX - this.slider.offset().left) / this.slider.width() ) * 100 ); + percent = Math.round( ( ( data.pageX - this.slider.offset().left ) / this.slider.width() ) * 100 ); } else { if ( val == null ) { - val = (cType === "input") ? parseFloat(control.val()) : control[0].selectedIndex; + val = cType === "input" ? parseFloat( control.val() ) : control[0].selectedIndex; } - percent = (parseFloat(val) - min) / (max - min) * 100; + percent = ( parseFloat( val ) - min ) / ( max - min ) * 100; } - if ( isNaN(percent) ) { return; } - if ( percent < 0 ) { percent = 0; } - if ( percent > 100 ) { percent = 100; } + if ( isNaN( percent ) ) { + return; + } - var newval = Math.round( (percent / 100) * (max - min) ) + min; - if ( newval < min ) { newval = min; } - if ( newval > max ) { newval = max; } + if ( percent < 0 ) { + percent = 0; + } - //flip the stack of the bg colors + if ( percent > 100 ) { + percent = 100; + } + + var newval = Math.round( ( percent / 100 ) * ( max - min ) ) + min; + + if ( newval < min ) { + newval = min; + } + + if ( newval > max ) { + newval = max; + } + + // Flip the stack of the bg colors if ( percent > 60 && cType === "select" ) { - + // TODO: Dead path? } - this.handle.css("left", percent + "%"); - this.handle.attr({ - "aria-valuenow": (cType === "input") ? newval : control.find("option").eq(newval).attr("value"), - "aria-valuetext": (cType === "input") ? newval : control.find("option").eq(newval).text(), + this.handle.css( "left", percent + "%" ); + this.handle.attr( { + "aria-valuenow": cType === "input" ? newval : control.find( "option" ).eq( newval ).attr( "value" ), + "aria-valuetext": cType === "input" ? newval : control.find( "option" ).eq( newval ).text(), title: newval }); // add/remove classes for flip toggle switch if ( cType === "select" ) { if ( newval === 0 ) { - this.slider.addClass("ui-slider-switch-a") - .removeClass("ui-slider-switch-b"); + this.slider.addClass( "ui-slider-switch-a" ) + .removeClass( "ui-slider-switch-b" ); } else { - this.slider.addClass("ui-slider-switch-b") - .removeClass("ui-slider-switch-a"); + this.slider.addClass( "ui-slider-switch-b" ) + .removeClass( "ui-slider-switch-a" ); } } - if(!preventInputUpdate){ - // update control's value + if ( !preventInputUpdate ) { + // update control"s value if ( cType === "input" ) { - control.val(newval); + control.val( newval ); } else { control[ 0 ].selectedIndex = newval; } - if (!isfromControl) { control.trigger("change"); } + if ( !isfromControl ) { + control.trigger( "change" ); + } } }, - enable: function(){ - this.element.attr("disabled", false); - this.slider.removeClass("ui-disabled").attr("aria-disabled", false); - return this._setOption("disabled", false); + enable: function() { + this.element.attr( "disabled", false ); + this.slider.removeClass( "ui-disabled" ).attr( "aria-disabled", false ); + return this._setOption( "disabled", false ); }, - disable: function(){ - this.element.attr("disabled", true); - this.slider.addClass("ui-disabled").attr("aria-disabled", true); - return this._setOption("disabled", true); + disable: function() { + this.element.attr( "disabled", true ); + this.slider.addClass( "ui-disabled" ).attr( "aria-disabled", true ); + return this._setOption( "disabled", true ); } });