I'd like to use the <input type='range' />
from HTML5 for browsers that support it and degrade to a <select />
if not. I'm using Ruby-on-Rails, so failing all else, I could do something like this on the server-side.
I would prefer, though, to have something more inline with the idea of progressive enhancement done via Javascript. Bonus points if it's JQuery.
Check out Modernizr, it will tell you if range is supported. I believe the technique is to create a range input and check it's type — if it is still "range" then it is supported. Otherwise it should report "text" which is the fallback in other browsers.
First detect if the browser can handle HTML 5 then use something like this:
$('input').each(function (i, item) {
if ($(item).attr('min') !== undefined && $(item).attr('max') !== undefined) {
var select = document.createElement("SELECT");
$(select).attr('name', $(item).attr('name'));
$(select).attr('id', $(item).attr('id'));
$(select).attr('disabled', $(item).attr('disabled'));
var step = 1;
if ($(item).attr('step') !== undefined) {
step = parseFloat($(item).attr('step'));
}
var min = parseFloat($(item).attr('min'));
var max = parseFloat($(item).attr('max'));
var selectedValue = $(item).attr('value');
for (var x = min; x <= max; x = x + step) {
var option = document.createElement("OPTION");
$(option).text(x).val(x);
if (x == selectedValue) { $(option).attr('selected', 'selected'); }
$(select).append(option);
};
$(item).after(select);
$(item).remove();
}
});
Since you can't use the input[type=range]
selector i had to go with the $(item).attr('min') && $(item).attr('min')
approach, this will get a little weird if you have other types of input controls with those two attributes.