input range polyfill

During The Highland Fling (an excellent conference by the way – highly recommend), James Edwards aka Brothercake was talking about the graceful degradation of HTML5 Web Form elements, in particular the input range type.

He points out that degrading to text isn’t graceful at all, because with a range, you have predefined options. Much like a select box.

In the wild

In the last week I’ve worked on two small projects of which both needed a slider aka range element. In one the user gives a rating to an item, 1 – 5. In the second, the user slides from a scale from 10 to 3000.

With <input type=range> the apps looked great. Then I opened them in Firefox 5 and iOS 4.x and there’s no range, but a text box. Not useful at all.

Good thing that during James’ Q&A session at The Highland Fling I wrote the solution he was describing :)

Jack watching me code

Solution

Instead of the input range, you use a select with a type attribute of range. In that select you offer the options the user can select (in the case of my problem 10-3000, actually I wanted them to chose device widths, so the options were 10, 320, 340, 420, etc for various device widths).

For a rating, here’s what you’d have without JavaScript:

<select data-type="range" name="rating"> 
  <option>1</option> 
  <option>2</option> 
  <option>3</option> 
  <option>4</option> 
  <option>5</option> 
</select>

After the DOM is ready, my range polyfill kicks in, and upgrades our select elements with data-type=range to an input range type only if the browser supports it. My code tries to replicate all the attributes from the select element, class, id, etc. It will read the first and last options and use those as the min and max, and then read the selected value and use that as the initial value.

The code

You can download it from here: range.js

Here’s a live example using the range.js code: http://jsbin.com/atocep/11/edit

I’ve included the range.js script in my polyfills github repo, so if you find a bug do help yourselves to contributing too.

I’ve changed the search for the select to look for data-type="range" instead of type="range" – for those validation junkies out there :)

5 Responses to “input range polyfill”

  1. alexander farkas July 18th, 2011 at 7:07 pm

    I’m not really convinced by this script. Last time you talked about polyfills, you sayed, that a polyfill implements the API/UI of modern web standards. With a polyfill webdeveloper can simply use these modern standards in all browsers.

    Now you, ask the web developer community to write non-standard, invalid code and this code will be than transformed to a modern webstandard, if the browser supports this. And you call it a polyfill.

    Even if you would have used select.range instead of select[type="range"], I would be very confused, why this should be called a polyfill. The select.range transformation is something like a simple progressive enhancement with modern technologies (see also http://www.filamentgroup.com/lab/update_jquery_ui_slider_from_a_select_element_now_with_aria_support/). The select[type="range"] on the other hand is something no web developer should use.

    To be clear on select[type="range"]. It is not cool to introduce non-standard HTML attributes. There are some sites out there, which have done this cool thing some years ago. For example there are sites, which have introduced input[required="no"], very clever.

  2. @Alexander – dooood…. you gotta chill out. A script shouldn’t try to convince anyone :) I think I was getting a little liberal with the word polyfill – you’re right, it’s (to me) not quite a polyfill, it’s just progressive enhancement.

    Would it make you happier if it was <select data-type="range">? Then you wouldn’t have to worry about it not being cool by using a non-standard HTML attribute.

    I’ve updated the post to reflect that. Now if only I could change the blog title….meh – I’ll leave it as it is :)

  3. alexander farkas July 19th, 2011 at 9:36 am

    @Remy: I’m always a little bit harsh, if I’m criticizing something. Simply ignore that. (This is my dark side). :-)

    About the script: much better now.

  4. Howdy

    Well this won’t be the first pollyfill I’ve examine in hopes of not having to do the task myself. Actually as matter of spec debate, I would agree that the fallback should have been a select box and not the dead-end text box. Of course I’ve voiced my opinion in the direction of the spec-sters that the select box would find benefit in the datalist attribute too, but we’ll see how tone deaf the does or does not turn out to be.

    Now I’ve not tried your code yet , but will likely in the next few hours. My “hope” would be that your code looks for the defunct [type='range'] input turns it’s opacity to 0, perhaps lays the select box over it so as to hide in it’s natural focus aura, and relays the data and events into it so as to complete the illusion. If not I hope the distance from there to where it is proves to be more on the trivial side of things then not.

    I’m also hoping that it does the (foo=createElement(‘input’)).setAttribute(“type”,”range”); if(foo.type==”range”)fallaway bit for when various browser do get their act together.

    The thing is I have nice sliders working with my 3d stuff which I use to drive 3D roller wheels for various UI tasks, including setting the expiration for credit cards and a roller wheel of card types via mouse mousewheel and mobile touch, so I’m already abusing the heck out of things.

    Anyways , I’ll go take a look at your wares and see how much troubles they can possible save me.
    BTW , anyone interested in a 3D pyramid complete with the brick work (mummy and curse optional)

  5. Well, had a moment to give it a spin at the online demo link you have here in the page, but alas it does not want to come up in any of my browsers, even after a nice clean boot. Probably has something to do with the fact I boot to a Linux desktop, but the various widgets out there most often work just fine if they are spec legal.

    soooo it looks like I’m going to have to instead of working on my other 3D ui control stuff see about whipping up something. While I do agree with you that the spec-sters should really have based fallback around the select box, I’m going to do what I always have in these situations and simply make a spec legal polyfill. Maybe later I’ll add in anything they don’t specifically preclude me from doing.

    It’s sorta like the narrow path that affords me a way to feed 3d form elements their data through datalist.
    Since the current leveraging of the slider supports mouse,various mouse wheels , keyboard , and mobile touch , the poly will too.

    As in any other case calling for a form element overload , the actual original form element will be used so that such as the case for me , existing programs that already use the sliders will simply perceive them as normal sliders. Folks authoring pages will simply treat them as normal sliders, and the script can arrive early or late and require no API or configuration.

    I think everyone making these things are putting forth their best offerings which is all anyone can really ask, especially when it’s free. Here the work with the web started back when even uttering the word “internet” was guaranteed to evoke the response “The Inter-what?” from probably better than 99% of the population.
    Been down this path before with the form controls , but this time around the browsers are a darn site more robust .

Leave a Reply
Not required

CODE: Please escape code and wrap in <pre><code>, doing so will automatically syntax highlight