]> source.dussan.org Git - jquery-ui.git/commitdiff
Slider: allow range option to be changed. Fixed #5602 - Slider Does Not Exhibit Prope...
authorDavid Petersen <public@petersendidit.com>
Wed, 30 Jan 2013 19:07:33 +0000 (13:07 -0600)
committerDavid Petersen <public@petersendidit.com>
Tue, 5 Feb 2013 14:31:42 +0000 (08:31 -0600)
tests/unit/slider/slider_options.js
ui/jquery.ui.slider.js

index a7bd3ae8315afa6c5b6d411dbd03a5338499a5a2..dd213d03b263458f73dd5a86ac993ccdc5d45ed5 100644 (file)
@@ -203,4 +203,107 @@ test("values", function() {
        );
 });
 
+test( "range", function() {
+       expect( 27 );
+       var element, range;
+
+       // min
+       element = $("<div></div>").slider({
+               range: "min",
+               min: 1,
+               max: 10,
+               step: 1
+       });
+
+       equal( element.find( ".ui-slider-handle" ).length, 1, "range min, one handle");
+       equal( element.find( ".ui-slider-range-min" ).length, 1, "range min" );
+       element.slider( "destroy" );
+
+       // max
+       element = $("<div></div>").slider({
+               range: "max",
+               min: 1,
+               max: 10,
+               step: 1
+       });
+
+       equal( element.find( ".ui-slider-handle" ).length, 1, "range max, one handle");
+       equal( element.find( ".ui-slider-range-max" ).length, 1, "range max" );
+       element.slider( "destroy" );
+
+       // true
+       element = $("<div></div>").slider({
+               range: true,
+               min: 1,
+               max: 10,
+               step: 1
+       });
+
+       range = element.find( ".ui-slider-range" );
+       equal( element.find( ".ui-slider-handle" ).length, 2, "range true, two handles");
+       ok( !range.is( ".ui-slider-range-min"), "range true" );
+       ok( !range.is( ".ui-slider-range-max"), "range true" );
+       element.slider( "destroy" );
+
+       // Change range from min to max
+       element = $("<div></div>").slider({
+               range: "min",
+               min: 1,
+               max: 10,
+               step: 1
+       }).slider( "option", "range", "max" );
+
+       equal( element.find( ".ui-slider-handle" ).length, 1, "range switch from min to max, one handle");
+       equal( element.find( ".ui-slider-range-min" ).length, 0, "range switch from min to max" );
+       equal( element.find( ".ui-slider-range-max" ).length, 1, "range switch from min to max" );
+       element.slider( "destroy" );
+
+       // Change range from max to min
+       element = $("<div></div>").slider({
+               range: "max",
+               min: 1,
+               max: 10,
+               step: 1
+       }).slider( "option", "range", "min" );
+
+       equal( element.find( ".ui-slider-handle" ).length, 1, "range switch from max to min, one handle");
+       equal( element.find( ".ui-slider-range-max" ).length, 0, "range switch from max to min" );
+       equal( element.find( ".ui-slider-range-min" ).length, 1, "range switch from max to min" );
+       element.slider( "destroy" );
+
+       // Change range from max to true
+       element = $("<div></div>").slider({
+               range: "max",
+               min: 1,
+               max: 10,
+               step: 1
+       }).slider( "option", "range", true );
+
+       equal( element.find( ".ui-slider-handle" ).length, 2, "range switch from max to true, two handles");
+       equal( element.find( ".ui-slider-range-max" ).length, 0, "range switch from max to true" );
+       equal( element.find( ".ui-slider-range-min" ).length, 0, "range switch from max to true" );
+       equal( element.slider( "option", "value" ), 0 , "option value" );
+       equal( element.slider( "value" ), 1 , "value" );
+       deepEqual( element.slider( "option", "values" ), [1, 1], "option values" );
+       deepEqual( element.slider( "values" ), [1, 1], "values" );
+       element.slider( "destroy" );
+
+       // Change range from true to min
+       element = $("<div></div>").slider({
+               range: true,
+               min: 1,
+               max: 10,
+               step: 1
+       }).slider( "option", "range", "min" );
+
+       equal( element.find( ".ui-slider-handle" ).length, 1, "range switch from true to min, one handle");
+       equal( element.find( ".ui-slider-range-max" ).length, 0, "range switch from true to min" );
+       equal( element.find( ".ui-slider-range-min" ).length, 1, "range switch from true to min" );
+       equal( element.slider( "option", "value" ), 1, "value" );
+       equal( element.slider( "value" ), 1 , "value" );
+       equal( element.slider( "option", "values" ), null, "values" );
+       deepEqual( element.slider( "values" ), [] , "values" );
+       element.slider( "destroy" );
+});
+
 })(jQuery);
index ceb8e1320b1f6471fd7e135833a2941bc2f298b2..b3e609aa2342726bb1cde760a33060ed219dc933 100644 (file)
@@ -42,12 +42,6 @@ $.widget( "ui.slider", $.ui.mouse, {
        },
 
        _create: function() {
-               var i, handleCount,
-                       o = this.options,
-                       existingHandles = this.element.find( ".ui-slider-handle" ).addClass( "ui-state-default ui-corner-all" ),
-                       handle = "<a class='ui-slider-handle ui-state-default ui-corner-all' href='#'></a>",
-                       handles = [];
-
                this._keySliding = false;
                this._mouseSliding = false;
                this._animateOff = true;
@@ -62,29 +56,32 @@ $.widget( "ui.slider", $.ui.mouse, {
                                " ui-widget-content" +
                                " ui-corner-all");
 
-               this.range = $([]);
+               this._refresh();
+               this._setOption( "disabled", this.options.disabled );
 
-               if ( o.range ) {
-                       if ( o.range === true ) {
-                               if ( !o.values ) {
-                                       o.values = [ this._valueMin(), this._valueMin() ];
-                               } else if ( o.values.length && o.values.length !== 2 ) {
-                                       o.values = [ o.values[0], o.values[0] ];
-                               } else if ( $.isArray( o.values ) ) {
-                                       o.values = o.values.slice(0);
-                               }
-                       }
+               this._animateOff = false;
+       },
 
-                       this.range = $( "<div></div>" )
-                               .appendTo( this.element )
-                               .addClass( "ui-slider-range" +
-                               // note: this isn't the most fittingly semantic framework class for this element,
-                               // but worked best visually with a variety of themes
-                               " ui-widget-header ui-corner-all" +
-                               ( ( o.range === "min" || o.range === "max" ) ? " ui-slider-range-" + o.range : "" ) );
-               }
+       _refresh: function() {
+               this._createRange();
+               this._createHandles();
+               this._setupEvents();
+               this._refreshValue();
+       },
+
+       _createHandles: function() {
+               var i, handleCount,
+                       options = this.options,
+                       existingHandles = this.element.find( ".ui-slider-handle" ).addClass( "ui-state-default ui-corner-all" ),
+                       handle = "<a class='ui-slider-handle ui-state-default ui-corner-all' href='#'></a>",
+                       handles = [];
 
-               handleCount = ( o.values && o.values.length ) || 1;
+               handleCount = ( options.values && options.values.length ) || 1;
+
+               if ( existingHandles.length > handleCount ) {
+                       existingHandles.slice( handleCount ).remove();
+                       existingHandles = existingHandles.slice( 0, handleCount );
+               }
 
                for ( i = existingHandles.length; i < handleCount; i++ ) {
                        handles.push( handle );
@@ -94,41 +91,56 @@ $.widget( "ui.slider", $.ui.mouse, {
 
                this.handle = this.handles.eq( 0 );
 
-               this.handles.add( this.range ).filter( "a" )
-                       .click(function( event ) {
-                               event.preventDefault();
-                       })
-                       .mouseenter(function() {
-                               if ( !o.disabled ) {
-                                       $( this ).addClass( "ui-state-hover" );
-                               }
-                       })
-                       .mouseleave(function() {
-                               $( this ).removeClass( "ui-state-hover" );
-                       })
-                       .focus(function() {
-                               if ( !o.disabled ) {
-                                       $( ".ui-slider .ui-state-focus" ).removeClass( "ui-state-focus" );
-                                       $( this ).addClass( "ui-state-focus" );
-                               } else {
-                                       $( this ).blur();
-                               }
-                       })
-                       .blur(function() {
-                               $( this ).removeClass( "ui-state-focus" );
-                       });
-
                this.handles.each(function( i ) {
                        $( this ).data( "ui-slider-handle-index", i );
                });
+       },
 
-               this._setOption( "disabled", o.disabled );
+       _createRange: function() {
+               var options = this.options,
+                       classes = "";
+
+               if ( options.range ) {
+                       if ( options.range === true ) {
+                               if ( !options.values ) {
+                                       options.values = [ this._valueMin(), this._valueMin() ];
+                               } else if ( options.values.length && options.values.length !== 2 ) {
+                                       options.values = [ options.values[0], options.values[0] ];
+                               } else if ( $.isArray( options.values ) ) {
+                                       options.values = options.values.slice(0);
+                               }
+                       }
 
-               this._on( this.handles, this._handleEvents );
+                       if ( !this.range || !this.range.length ) {
+                               this.range = $( "<div></div>" )
+                                       .appendTo( this.element );
 
-               this._refreshValue();
+                               classes = "ui-slider-range" +
+                               // note: this isn't the most fittingly semantic framework class for this element,
+                               // but worked best visually with a variety of themes
+                               " ui-widget-header ui-corner-all";
+                       } else {
+                               this.range.removeClass( "ui-slider-range-min ui-slider-range-max" )
+                                       // Handle range switching from true to min/max
+                                       .css({
+                                               "left": "",
+                                               "bottom": ""
+                                       });
+                       }
 
-               this._animateOff = false;
+                       this.range.addClass( classes +
+                               ( ( options.range === "min" || options.range === "max" ) ? " ui-slider-range-" + options.range : "" ) );
+               } else {
+                       this.range = $([]);
+               }
+       },
+
+       _setupEvents: function() {
+               var elements = this.handles.add( this.range ).filter( "a" );
+               this._off( elements );
+               this._on( elements, this._handleEvents );
+               this._hoverable( elements );
+               this._focusable( elements );
        },
 
        _destroy: function() {
@@ -401,6 +413,16 @@ $.widget( "ui.slider", $.ui.mouse, {
                var i,
                        valsLength = 0;
 
+               if ( key === "range" && this.options.range === true ) {
+                       if ( value === "min" ) {
+                               this.options.value = this._values( 0 );
+                               this.options.values = null;
+                       } else if ( value === "max" ) {
+                               this.options.value = this._values( this.options.values.length-1 );
+                               this.options.values = null;
+                       }
+               }
+
                if ( $.isArray( this.options.values ) ) {
                        valsLength = this.options.values.length;
                }
@@ -408,12 +430,6 @@ $.widget( "ui.slider", $.ui.mouse, {
                $.Widget.prototype._setOption.apply( this, arguments );
 
                switch ( key ) {
-                       case "disabled":
-                               if ( value ) {
-                                       this.handles.filter( ".ui-state-focus" ).blur();
-                                       this.handles.removeClass( "ui-state-hover" );
-                               }
-                               break;
                        case "orientation":
                                this._detectOrientation();
                                this.element
@@ -441,6 +457,11 @@ $.widget( "ui.slider", $.ui.mouse, {
                                this._refreshValue();
                                this._animateOff = false;
                                break;
+                       case "range":
+                               this._animateOff = true;
+                               this._refresh();
+                               this._animateOff = false;
+                               break;
                }
        },
 
@@ -466,7 +487,7 @@ $.widget( "ui.slider", $.ui.mouse, {
                        val = this._trimAlignValue( val );
 
                        return val;
-               } else {
+               } else if ( this.options.values && this.options.values.length ) {
                        // .slice() creates a copy of the array
                        // this copy gets trimmed by min and max and then returned
                        vals = this.options.values.slice();
@@ -475,6 +496,8 @@ $.widget( "ui.slider", $.ui.mouse, {
                        }
 
                        return vals;
+               } else {
+                       return [];
                }
        },
 
@@ -629,6 +652,9 @@ $.widget( "ui.slider", $.ui.mouse, {
 
                        this._slide( event, index, newVal );
                },
+               click: function( event ) {
+                       event.preventDefault();
+               },
                keyup: function( event ) {
                        var index = $( event.target ).data( "ui-slider-handle-index" );