### Eclipse Workspace Patch 1.0 #P jQuery Index: demos/slider/multiple-handles.html =================================================================== --- demos/slider/multiple-handles.html (revision 0) +++ demos/slider/multiple-handles.html (revision 0) @@ -0,0 +1,51 @@ + + + + jQuery UI Slider - Range slider + + + + + + + + + + + + +
+ +

+ + +

+ +
+ +
+ +
+ +

Set the range option to true to capture a range of values with two drag handles. The space between the handles is filled with a different background color to indicate those values are selected.

+ +
+ + + Index: tests/unit/slider/slider_options.js =================================================================== --- tests/unit/slider/slider_options.js (revision 3816) +++ tests/unit/slider/slider_options.js (working copy) @@ -89,7 +89,22 @@ }); test("range", function() { - ok(false, "missing test - untested code is broken code."); + el = $('
'); + + options = { + max: 100, + min: 0, + orientation: 'horizontal', + values: [10,50], + range:true + }; + + el.slider(options); + var handles = handle(); + ok(el.slider("option", "range") == options.range); + equals((options.values.length), 2, "range is set to true, length of values is"); + el.slider('destroy'); + }); test("step", function() { @@ -97,11 +112,52 @@ }); test("value", function() { - ok(false, "missing test - untested code is broken code."); + el = $('
'); + + options = { + max: 100, + min: 0, + orientation: 'horizontal', + value: 5 + }; + + el.slider(options); + var handles = handle(); + ok(el.slider("option", "value") == options.value); + equals(handles.attr("aria-valuenow"), 5, "the aria-valuenow is"); + el.slider('destroy'); + }); test("values", function() { - ok(false, "missing test - untested code is broken code."); + el = $('
'); + + options = { + max: 100, + min: 0, + orientation: 'horizontal', + step: 1, + values: [10,50], + range: true + }; + + el.slider(options, options.step); + var handles = handle(); + var firstHandle = handles.eq(0); + equals(firstHandle.attr("aria-valuenow"), 10, "The aria-valuenow of the first handle is"); + var secondHandle = handles.eq(1); + equals(secondHandle.attr("aria-valuenow"), 50, "The aria-valuenow of the second handle is"); + firstHandle.simulate("keydown", { keyCode: $.ui.keyCode.RIGHT }); + equals(firstHandle.attr("aria-valuenow"), 11, "The aria-valuenow of the first handle after keydown RIGHT is" ); + firstHandle.simulate("keydown", { keyCode: $.ui.keyCode.LEFT }); + equals(firstHandle.attr("aria-valuenow"), 10, "The aria-valuenow of the first handle after keydown LEFT is" ); + secondHandle.simulate("keydown", { keyCode: $.ui.keyCode.LEFT }); + equals(secondHandle.attr("aria-valuenow"), 49, "The aria-valuenow of the second handle after keydown LEFT is"); + secondHandle.simulate("keydown", { keyCode: $.ui.keyCode.RIGHT }); + equals(secondHandle.attr("aria-valuenow"), 50, "The aria-valuenow of the second handle after keydown RIGHT is"); + + el.slider('destroy'); + }); })(jQuery); Index: demos/slider/default.html =================================================================== --- demos/slider/default.html (revision 3816) +++ demos/slider/default.html (working copy) @@ -14,7 +14,7 @@ Index: ui/jquery.ui.slider.js =================================================================== --- ui/jquery.ui.slider.js (revision 3816) +++ ui/jquery.ui.slider.js (working copy) @@ -30,7 +30,9 @@ range: false, step: 1, value: 0, - values: null + values: null, + unittext: null, + name: null }, _create: function() { @@ -122,7 +124,9 @@ }); this.handles.each(function(i) { - $(this).data("index.ui-slider-handle", i); + $(this).data("index.ui-slider-handle", i).attr("aria-valuenow", o.values ? o.values[i] : o.value); + if (self.options.unittext) + $(this).data("index.ui-slider-handle", i).attr("aria-valuetext", (o.values ? o.values[i] : o.value) + " " + self.options.unittext); }); this.handles.keydown(function(event) { @@ -200,11 +204,37 @@ } }); - + var ariaDefaults = {role: 'slider', + "aria-valuemin": this.options.min, + "aria-valuemax": this.options.max, + }; + + if (this.options.value && this.options.label) + ariaDefaults.title = this.options.label; + else if (!this.options.labels && this.options.label) { + this.handles.each(function(i,e) { + + if (self.options.range && i < 2) { + $(this).attr('title', self.options.label + " " + (i == 0 ? "min" : "max")); + } + else + $(this).attr('title', self.options.label + " " + (i + 1)) + }); + } + else if (this.options.labels) { + this.handles.each(function(i,e) { + if (self.options.labels[i]) + $(this).attr("title", self.options.labels[i]); + }); + } + + this.handles.attr(ariaDefaults); this._refreshValue(); this._animateOff = false; - + this._updateAriaLimit("min"); + this._updateAriaLimit("max"); + }, destroy: function() { @@ -390,6 +420,9 @@ var otherVal = this.values(index ? 0 : 1); if (allowed !== false) { this.values(index, newVal, true); + $(handle).attr("aria-valuenow",newVal); + if (this.options.unittext) + $(handle).attr("aria-valuetext", newVal + " " + this.options.unittext); } } @@ -403,6 +436,9 @@ }); if (allowed !== false) { this.value(newVal); + $(handle).attr("aria-valuenow",newVal); + if (this.options.unittext) + $(handle).attr("aria-valuetext", newVal + " " + this.options.unittext); } } @@ -512,6 +548,10 @@ this._refreshValue(); this._animateOff = false; break; + case 'min': + case 'max': + this._updateAriaLimit(key); + break; } }, @@ -591,6 +631,12 @@ } } lastValPercent = valPercent; + + $(this).attr('aria-valuenow', self.values(i)); + //since ranged thumbs can't pass each other, update ARIA min/max boundary for opposite handle + if (self.options.range && i < 2) { + self.handles.eq(i == 0 ? 1 : 0).attr(i == 0 ? 'aria-valuemin' : 'aria-valuemax', self.values(i)); + } }); } else { var value = this.value(), @@ -606,8 +652,22 @@ (oRange == "max") && (this.orientation == "horizontal") && this.range[animate ? 'animate' : 'css']({ width: (100 - valPercent) + '%' }, { queue: false, duration: o.animate }); (oRange == "min") && (this.orientation == "vertical") && this.range.stop(1,1)[animate ? 'animate' : 'css']({ height: valPercent + '%' }, o.animate); (oRange == "max") && (this.orientation == "vertical") && this.range[animate ? 'animate' : 'css']({ height: (100 - valPercent) + '%' }, { queue: false, duration: o.animate }); + + this.handle.attr('aria-valuenow', value); } + }, + + _updateAriaLimit : function(key) { + var value = this.options[key]; + if (this.range && this.options.values && this.options.values.length == 2) { + this.handles.eq(key == "min" ? 0 : 1).attr(key == "min" ? 'aria-valuemin' : 'aria-valuemax', value); + } + else { + this.handles.each(function(i) { + $(this).attr(key == "min" ? 'aria-valuemin' : 'aria-valuemax', value); + }); + } } }); Index: tests/unit/slider/slider_defaults.js =================================================================== --- tests/unit/slider/slider_defaults.js (revision 3816) +++ tests/unit/slider/slider_defaults.js (working copy) @@ -14,7 +14,8 @@ range: false, step: 1, value: 0, - values: null + values: null, + unittext: null }; commonWidgetTests('slider', { defaults: slider_defaults }); Index: demos/slider/range.html =================================================================== --- demos/slider/range.html (revision 3816) +++ demos/slider/range.html (working copy) @@ -19,6 +19,8 @@ min: 0, max: 500, values: [75, 300], + unittext: "dollar", + label: "price range", slide: function(event, ui) { $("#amount").val('$' + ui.values[0] + ' - $' + ui.values[1]); } @@ -29,7 +31,7 @@ -
+

Index: tests/unit/slider/slider_core.js =================================================================== --- tests/unit/slider/slider_core.js (revision 3816) +++ tests/unit/slider/slider_core.js (working copy) @@ -289,4 +289,83 @@ el.slider("destroy"); }); +test("ARIA Min and Max", function() { + el = $('

'); + + options = { + max: 54, + min: 3, + orientation: 'horizontal', + value:15 + }; + + el.slider(options); + var handles = handle(); + + equals(handles.attr("aria-valuemax"), 54, "The ARIA-valuemax should be 54" ); + equals(handles.attr("aria-valuemin"), 3, "The ARIA-valuemin should be 3" ); + equals(handles.attr("aria-valuenow"), 15, "The ARIA-valuenow should be 15" ); + el.slider('destroy'); +}); + +test("ARIA Min and Max with default options", function() { + el = $('
'); + + el.slider(); + var handles = handle(); + + equals(handles.attr("aria-valuemax"), 100, "The ARIA max should be 100" ); + equals(handles.attr("aria-valuemin"), 0, "The ARIA min should be 0" ); + equals(handles.attr("aria-valuenow"), 0, "The ARIA-valuenow should be 0" ); + el.slider('destroy'); +}); + +test("ARIA-valuenow after keydown LEFT", function(){ + el = $('
'); + options = { + max: 5, + min: -5, + orientation: 'horizontal', + step: 1, + value: 4 + }; + el.slider(options); + var handles = handle(); + + el.slider(options.value, options.min + options.step); + + handle().simulate("keydown", { keyCode: $.ui.keyCode.LEFT }); + equals(handles.attr("aria-valuenow"), 3, "The ARIA-valuenow should be 3" ); + + handle().simulate("keydown", { keyCode: $.ui.keyCode.LEFT }); + equals(handles.attr("aria-valuenow"), 2, "The ARIA-valuenow should be 2" ); + + el.slider("destroy"); + +}); + +test("ARIA-valuenow after keydown RIGHT", function(){ + el = $('
'); + options = { + max: 5, + min: -5, + orientation: 'horizontal', + step: 1, + value: 2 + }; + el.slider(options); + var handles = handle(); + + el.slider(options.value, options.min + options.step); + + handle().simulate("keydown", { keyCode: $.ui.keyCode.RIGHT }); + equals(handles.attr("aria-valuenow"), 3, "The ARIA-valuenow should be 3" ); + + handle().simulate("keydown", { keyCode: $.ui.keyCode.RIGHT }); + equals(handles.attr("aria-valuenow"), 4, "The ARIA-valuenow should be 4" ); + + el.slider("destroy"); + +}); + })(jQuery);