1. 01. Incoming
  2. 02. Hifi
  3. 03. Lofi
  4. 04. The Lab
  5. 05. Tags

frequency decoder

Unobtrusive Slider Control Revisited

Posted Monday September 10, 2007

frequency decoder

An attempt at creating a keyboard-accessible, unobtrusive slider control that conforms to the WAI-ARIA defined role of "slider"

A big bold disclaimer

The slider is created using DIV elements, which means that only browsers that support the extending of DOM elements with a tabIndex (for the purposes of making them keyboard accessible) will be able to catch both the focus & blur events on the DIVs in question (currently Internet Explorer and Firefox/Mozilla).

I could have replaced one of the DIVs with an element that already handles the focus & blur events in all browsers; for example, an input (type=“image”) and indeed, the code could be altered to use such an element (with caveats of course, you would also have to hijack the encapsulating form’s onsubmit event should an input element be used) but the aim of the excercise was not to try to bend over backwards accommodating non ARIA aware browsers.

Once Safari & Opera integrate support for the extending of DOM elements with a tabIndex, the full slider functionality should automatically become available.

UPDATE: I’ve rewritten the code to use a BUTTON element for the slider handle which automatically makes it keyboard accessible across all grade A browsers. Both Opera & Safari still have some quirks to be dealt with, which are explained in full at the end of the article.

Remember folks, It’s nothing but a Sunday morning experiment…

Configuring the Slider

The slider can be associated with both text input and select list form elements. All of the Sliders configuration parameters should be defined within the form element’s className as described below.

Stipulating the Sliders range

If using a select list as the sliders associated form element, the range is automatically calculated for you (using the value attribute of each option tag) and does not have to be defined within the className. Additionally, selectlists are no longer constrained to having numeric values, non-numeric values such as “low”, “lower” and “lowest” can be used.

If using a text input, add the className fd_range_lowerlimit_upperlimit to the associated input’s className e.g. the classname ‘fd_range_-255_255’ will give the slider a numeric range of -255 to 255. This is a required className – without it, no slider control is created for text input elements.

The Animated Tween

Should the associated form element’s className contain fd_tween, clicking on the slider bar initiates a tween animation that scrolls the slider’s “drag-handle” to the point in which the mouseDown event occurred.

Should this className be omitted, clicking on the slider bar will move the slider drag-handle 10% of the defined range in the direction of where the mouseDown event occurred for sliders created from text inputs and one “step” for sliders created from select lists. Clicking and holding down the mouse button will initiate a timer that automatically moves the drag-handle i.e. repeatedly clicking on the slider bar isn’t necessary.

Stipulating a JavaScript callback function

Should you wish the slider to call another JavaScript function each time the slider handle is moved, give the associated input a className fd_callback_callbackFunctionName e.g. the classname ‘fd_callback_updateColor’ will get the slider to call the javascript function ‘updateColor()’ each time the drag-handle moves (as can be seen in the demo).

Of course, as the function name is being declared within a CSS className, the name itself is limited to the set of alphanumeric characters valid for use within such a CSS className i.e. while the character “$” is a valid JavaScript function name, it is not a valid character for use within a CSS className and so should be avoided.

Stipulating an Object.method as a callback function

It is now possible to stipulate an object method as the callback function. Object.methods can be stipulated by converting the “dots” (i.e. the full-stops) to minus signs (-); for example, the className “fd_callback_myObject-myMethod” will tell the script to call the “myMethod” method of the JavaScript Object “myObject” e.g. myObject.myMethod();

Hiding the original input

Giving the input a className of fd_hide_input will do exactly that, and hide the associated input element on slider creation (the default functionality is to keep the input visible). Sliders that are associated with select lists will always have the select list hidden and so the fd_hide_input class is not required.

Form elements are hidden by setting their display to “none” and so their value will still be submitted to the server – unfortunately, setting an element to display “none” makes it unavailable to assistive technologies such as JAWS, and until assistive technology can use the ARIA information sent by the browser, it is recommended that you keep the input displayed.

Vertical sliders

Vertical sliders can be created by adding fd_vertical to the associated input’s className.

Styling the slider

Sliders can have an additional className given to them (to enable you to style them differently to the others) by adding fd_classname_yourclassnamehere to the associated input’s className e.g. the className ‘fd_classname_hunkydory’ will give the associated slider control an extra class of ‘hunkydory’.

Additionally each slider control is given a unique ID of the form ‘fd-slider-theAssociatedInputElementsId’. This enables you to target individual sliders within the CSS and also enables DOM access to the top level slider div by using document.getElementById.

Keyboard accessibility and ARIA roles & states

Once a slider has focus, the arrow keys can be used to move the drag handle (by default, the drag handle moves by 5% of the defined range), the Home button to move the slider to it’s minimum value and the End button to move the slider to its maximum value. Additionally, each slider is given the WAI-ARIA role of slider and it’s associated states valuemax, valuemin, valuetext (for sliders created from selectlists) and valuenow.

Should an element with an id of fd_slider_describedby exist within the DOM, this is used to set the ARIA describedby relationship.

Additionally, should the sliders associated form element itself have an associated label, this label is used to set the ARIA labelledby relationship.

MouseWheel support

MouseWheel support currently exists for Internet Explorer and FireFox/Mozilla and Safari.

Bugs and annoyances

Opera

Opera does not enable the cancelling of the default keypress/keydown event which means the screen will scroll when the Up/Down arrow or the Home/End keys are used.

Additionally, Opera fires the blur event onmouseup which means I have to programmatically reset the focus, this causes a slight “flicker” as the styles are swapped.

Additionally, the mouseWheel support does not currently work in Opera – something I’m currently looking into.

Safari

Safari only calls the focus event handler on keyboard, not mouse events, which again means I have to programatically set the focus.

Internet Explorer

The demo uses png images for the slider drag-handles and will therefore will only display in Internet Explorer (5.5 & 6) by using additional and proprietary css filter behaviours (which are passed using conditional comments within the demo). All other modern browsers display the png images as intended.

The License

The script is now released under a creative commons Attribution-ShareAlike 2.5 license. Should you use the script within a commercial context please think about clicking the payPal donate button – it’s certainly not an obligation but it would most certainly put a smile on my face.

References

  • The WAI-ARIA roadmap
  • A List Apart’s primer on Accessible Web 2.0 Applications with WAI-ARIA
  • Juicy Studio’s WAI-ARIA in HTML article and slider control demo
  • schillmania, where the slider styles and png images were originally located
  • Mouse wheel programming in JavaScript, general information about handling mouse wheel-generated events in JavaScript programming language

Demo, Downloads and Updates

Tested in Internet Explorer 6, Opera 9, Safari 3 (Win), Firefox and Mozilla.

View the slider demo, the tooltip demo (that creates a tooltip to display the sliders current value) or download the javascript source.

31/03/2008 (v1.4):

  • MouseWheel support for Opera
  • Added a workaround for the dreaded IE window.resize problem
  • Added the ARIA “valuetext” state for sliders created from selectLists
  • Added the tooltip demo – IE users get a non png version of the tooltip

28/03/2008 (v1.3):

  • Selectlists are now not limited to using numeric data
  • Selectlists can now use optgroups to group the options
  • Object.methods can now be decalred as a callback
  • Demo updated to show a non-numeric selectlist

03/12/2007 (v1.2):

  • Fixed a bug that incorrectly calculated the handle increment when using a selectList as the associated form element

10/09/2007 (v1.1):

  • Creation (based on the older, non ARIA aware 1.0 slider code)

Tags: accessibility, aria, javascript, slider, unobtrusive

Previous Comments ~

Maria · http://www.qualitysites.nl
#1 · Tuesday October 2, 2007

Unobtrusive Table Sort Script (revisisted) 2007.
Couldn’t find your email address.
Just one question: I have a (nice) button on a div absolute positioned at the bottom of 20 rows. The table has 100 rows. That button has to do exactly the same as in your pagination script but not using the “list” attribute. Is that possible?

Sorry to use this way around to reach you, seems to be the only possible wat to contact you!

Mabe you’re willing to help me. (I’m NOT a javascripter….!). Thank you!
Maria.

frequency decoder
#2 · Monday October 8, 2007

@ Maria: Hi Maria, sorry but I can’t comment on issues that aren’t directly related to the script. It should be very easy to do if you use the pagination code as a base (just remove the list creation, add a global variable to hold the current page number and increment this variable each button click).

Regards,
Brian

Arnout
#3 · Wednesday October 24, 2007

I have a little question, is there a way to add 2 handels to slider?
So i can be used for a Price slider with a min price and max price.

Im currently using a Jquery based slider, but i fell i love with this slider. So if i could kick away Jquery and use this script. I would make my day.

Regards,

Arnout

frequency decoder
#4 · Wednesday October 24, 2007

@ Arnout: Hi Arnout, unfortunately, the slider was written with only one “handle” in mind and it would require a substantial rewrite to take a second slider handle into consideration. sorry to be the harbinger of bad news!

Regards,
Brian

Arnout
#5 · Wednesday October 24, 2007

@ Arnout: Hi Arnout, unfortunately, the slider was written with only one “handle” in mind and it would require a substantial rewrite to take a second slider handle into consideration. sorry to be the harbinger of bad news!
Regards,
Brian

Thanks for the fast reply, i guess have to mess a bit my self than . Its always worth the try.

Regards,
Arnout

Dan
#6 · Wednesday October 24, 2007

Is it possible to reposition the slider from an html link? I would like to use the slider as a secondary navigational aid. the primary method would be a link in a table.

frequency decoder
#7 · Friday October 26, 2007

@ Dan: Hi Dan, repositioning the slider would be easy but it would still require an INPUT element to be present (as the entire slider is based around the idea of being attached to an associated INPUT).

Regards,
Brian

Daniel Arabia
#8 · Saturday October 27, 2007

How can I reference the slider to assign a new value and reposition it via javascript?

Arnout
#9 · Monday October 29, 2007

How can I reference the slider to assign a new value and reposition it via javascript?

document.getElementById(“idofinputfield”).value = “30”; // value is new position

tryed that?

daniel Arabia
#10 · Thursday November 1, 2007

Is it possible to reposition the slider from an html link? I would like to use the slider as a secondary navigational aid. the primary method would be a link in a table.

Daniel Arabia
#11 · Thursday November 1, 2007

I had tried to assign the value as you indicated. This updates the value, but does not reposition the handle to the new current location on the slider.

Thanks,
Dan

frequency decoder
#12 · Monday November 5, 2007

@ Daniel: Hi Daniel, sorry for the late reply but I was on holiday and far from the keyboard…

You should be able to call:

fdSliderController.sliders[“the associated input id”].resetHandlePosition();

after setting the (new) value of the input.

Regards,
Brian

Hui
#13 · Monday November 5, 2007

Hi,Brain. I try to find your email but I fail. So I post my question here.
I am using your js code for a slider.
Could you please tell me how can I get the slider value at any place?

Thanks for your help.

Hui

frequency decoder
#14 · Monday November 5, 2007

@ Hui: Hi Hui, if you need the sliders current value, just grab the associated inputs value. If you need the pixel position of the slider handle (why would you need this?), you can grab a reference to the handle by using:

document.getElementById(“fd-slider-” + “the inputs ID”).getElementsByTagName(“div”)[2];

Hui
#15 · Monday November 5, 2007

Hi,Brain. I need the sliders current value, just grab the associated inputs value.
But I don’t know how to do it.
I am not strong on it. Could you please provide more details?
Thanks for your help.

Hui

frequency decoder
#16 · Monday November 5, 2007

@ Hui: Hi Hui, if your input has an ID of “myId” then you just call:

document.getElementById(‘myId’).value

Why don’t you look at the source code to the demo, it has all the info (and code) you need.

Hui
#17 · Monday November 5, 2007

Hi,Brain. sorry to bother you again.
The slider still doesn’t come out.(I ignored the html tags in my code)

body onload=“show(‘red’)”
div class=“slider” name=slider2 width=200 value=10 min=10 max=1000 int onchange=‘document.getElementById( “report” ).innerHTML =this.value;’ /...

div id=“MyId” class=“slider”..

Regards
Hui

frequency decoder
#18 · Tuesday November 6, 2007

@ Hui: Hi Hui, I just don’t understand what your attempting to do here! Why are you adding crazy attributes to a DIV when you should be adding classNames to an INPUT form element. Please view the demo source code to see how it’s done.

Joao
#19 · Thursday November 29, 2007

Hello – I really like the full keyboard/mouse support, and find the documentation and code very clear to read. My question relates to setting the number of steps that the slider is to take when using the keyboard/mouse.

I have associated the slider to a select list with 5 values (1 through 5), but when I use the keyboard/mouse, 11 steps are taken to go from the min to the max. I am planning to use the slider on a questionnaire, where the user chooses one of 5 answers. Ideally, I would like the Tween effect to bring the handle to one of the 5 values (the closest one) instead of the onclick event position. Is this possible?

Thanks,
Joao.

frequency decoder
#20 · Monday December 3, 2007

@ Joao: Hi Joao, the select list support was pretty much tacked on at the last minute and, as you have found out, requires more work/testing… I’ll try to have a look this week to see if I can tidy the code a bit.

P.S. The ARIA support is currently out of date as namespaces are no longer required for FireFox3…

Patrick
#21 · Friday December 14, 2007

Hi— The sliders are great. I’m using them in an application (7 to be exact). I’m using 4 horizontal and 3 vertical. I’m doing a bit of mouse interaction in another part of the web app, and for some reason the vertical sliders immediately snap to zero on any attempt at a move. The funny thing is that I can make them move and show correct values via function calls. Any hunches as to why the horizontal work, but not the vertical

$$$$ · http://q
#22 · Monday February 4, 2008

please, pack zip-arhive with files for slider.
It’s realy good work! Thank you!

frequency decoder
#23 · Tuesday February 5, 2008

@ Patrick: Hi Patrick, sorry for the incredibly late reply! Can you give me the URL to the page in question? Thanks.

@ $$$$: I’ll see what I can do.

Gordon
#24 · Thursday February 7, 2008

Hi,
The slider is great, but I needed a callback for the mouseup event. I have patched the code and added fd_released class/parameter following your lead with fd_callback. Unfortunately it is only for mouseup since I can’t think of a good way for keyboard interaction. BTW, my released callback (in another js file) does some stuff to the page and snaps the slider handle to one of my marked values. BTW, You can use the below code for free under the same license as slider.js

The diff is below against version 1.2
30c30
< function fdSlider(inp,range,callback,classname,hide,tween,vertical,released) {
—-
> function fdSlider(inp,range,callback,classname,hide,tween,vertical) {
44d43
< this._released = released;
217,218d215
< self.doReleased();
<
220a218
>
406,412d403
< this.doReleased = function() {
< if(self._released) {
< if(typeof self._released == “string” && self._released in window) window[self._released]();
< else if(typeof self._released == “function”) self._released();
< };
< };
<
539d529
< self._released = null;
599d588
< var regExp_4 = /fd_released_([a-zA-Z0-9_]+)/;
601c590
< var range, callback, classname, hide, tween, vertical, released;
—-
> var range, callback, classname, hide, tween, vertical;
623,624d611
< // mouse released function
< released = inp.className.search(regExp_4) != -1 ? inp.className.match(regExp_4)[1] : “”;
631c618
< fdSliderController.sliders[inp.id] = new fdSlider(inp, range, callback, classname, hide, tween, vertical, released);
—-
> fdSliderController.sliders[inp.id] = new fdSlider(inp, range, callback, classname, hide, tween, vertical);

Jon Wilson · http://www.toastboy.co.uk
#25 · Tuesday February 26, 2008

Thanks for a great leg-up into the world of unobtrusive, accessible, gracefully-degrading JavaScript! I have a small suggestion for an improvement, maybe you could even call it a bugfix. I wanted horizontal sliders for percentage values, so I specified them with ‘class=“fd_range_0_100”’ – but they only went to 99%! It seems that the “updateInput” function needs to do a round() rather than a floor() to get this right: line 372 of slider.js.

frequency decoder
#26 · Tuesday February 26, 2008

@ Gordon: Hi Gordon, and sorry for forgetting to reply before! Thanks for the code, if you send me it I’ll repost it without all of the textile madness – brian (at) modernartcafe [d0t] net. Thanks.

@ Jon: Hi Jon, in fact, you need to floor() if the current value is < 50% of the range and ceil() if above.

As an aside, you didn’t happen to attend “Kite High” or “The proper stuff” around 1990-1991 did you? (I’m asking this as I lived in Cambridge for 6 years and, as it’s an unbelievably small place, there’s a larger than life chance that we met down the Kings Arms/King Street Run etc etc). Oh yeah, sweet dog by the way.

Dave Hoernig
#27 · Friday March 28, 2008

Brian, first thanks a bunch for posting this code…really great stuff! I’ve made some enhancements, specifically in the area of select elements and the introduction of fd_dropdown to support optional drop-down functionality. If you send me your email address, I’ll return a sample (htm,css,js,gifs) for your ongoing use and general enjoyment!

frequency decoder
#28 · Monday March 31, 2008

@ Dave: Hi Dave, you can send the code to brian (at) modernartcafe [d0t] net. Thanks in advance…

JoLee
#29 · Sunday May 4, 2008

Thank you very much for the slider. It works great and is written neatly! Just a suggestion for later version: (1) Allowing configurable display of minimum value, maximum value and scaling indicators in the sliding bar. (2) Allowing optional display of ““ and ““ buttons at the beginning and ending points so that pressing ““ or ““ will increment the position of the bullet and the input value by a configurable parameter of pixels or percentage per click.

frequency decoder
#30 · Monday May 5, 2008

@ JoLee: Hi JoLee, I’m currently rewriting the slider to improve performance etc and have already integrated the “inc/del” key commands. I’ve also integrated a few more callback functions, including one for the “oncreate” event which should allow you to create the “visible scale” yourself. I’ll try to write a generic oncreate callback function you can use to create a scale for any slider.

I’ll hopefully have an update by the end of the week.

frequency decoder
#31 · Monday May 5, 2008

@ JoLee: Hi JoLee, I’m currently rewriting the slider to improve performance etc and have already integrated the “inc/del” key commands. I’ve also integrated a few more callback functions, including one for the “oncreate” event which should allow you to create the “visible scale” yourself. I’ll try to write a generic oncreate callback function you can use to create a scale for any slider.

I’ll hopefully have an update by the end of the week.

JoLee
#32 · Wednesday May 7, 2008

Thanks for your quick and positive feedback! Wish you all the best!
/JoLee

Karim · http://xhtml-css.com
#33 · Monday May 12, 2008

Great job here! I really love it! :)
I’d really like to be able to add sliders on the fly. I mean, say, I have a form,
to which I want to add (with javascript) new sliders, can you please give me an idea on how to do such a thing? It seems that the sliders are created on windows’s load. What would be great is having a function like: add_slider(id_input)
which will “convert” an input that has and id =id_input to a slider and that i can call in my code.

karim · http://xhtml-css.com
#34 · Monday May 12, 2008

Hi again :)

Just figured out how to do what i’ve asked for before. It’s actually simple:
Just call fdSliderController.construct(); inside my “add on the fly function”.

I’ve also tried to tweak the thing a little bit, in fact, I have made a single “sprite” image from the 4 given and changed the style a little bit, to just use one image and hence download a single image (no need to preload 4)
You can have the image and the css here:

http://xhtml-css.com/stuff/sliderh.png
http://xhtml-css.com/stuff/slider.css

Now I have to work on the ie.css file, how i hate this! ;-)
I’ll keep you informed, and if you made it, please tell us about it!

Again thanks!

frequency decoder
#35 · Wednesday May 14, 2008

@ Karim: Hi Karim, I’m currently rewriting the script from scratch (almost finished) so things will inevitably change in the next release. As for making just one sprite – you can do it for all browsers but Internet Explorer 5.5/6 (that requires the 4 separate images). I’ve already a “addSlider” method available within the new code.

Regards,
Brian

A penny for your thoughts…

Remember: Off-topic or dumb-ass comments will, of course, be deleted. Spammers shall have the scary flying-monkeys from “The Wizard of Oz” dispatched to their abode. Please remember to RTM before asking questions pertaining to any of the Lab experiments.

Reporting a bug? The error message and browser and operating system details would be much appreciated. Thanks.

Popular Frequencies

  • Unobtrusive Table Sort Script (revi…
    Saturday September 16, 2006
  • Unobtrusive Date-Picker Widget Upda…
    Monday October 02, 2006
  • Unobtrusive Table Sort Script
    Friday November 18, 2005
  • Unobtrusive Date-Picker Widgit
    Friday October 14, 2005
  • Unobtrusive Table Actions Script
    Thursday November 15, 2007

Google Ads

All articles