HTML5 Input Types Alternative

By  on  

As you may know, HTML5 has introduced several new input types: number, date, color, range, etc. The question is: should you start using these controls or not? As much as I want to say "Yes", I think they are not yet ready for any real life project. The main reason is inconsistent implementation by different browsers.

In the form below you can see some of the HTML5 input types. Depending on your browser you might or might not see any difference from a regular input control.

HTML5 Inputs

What, then, should you use? You can develop your own input types, or use an existing library. Everyone is probably familiar with jQuery date picker or other jQuery plug-ins that come to rescue. However, I have not yet found a comprehensive library that would suit all my input needs, so I decided to put together my own that would be small, consistent and would cover following areas:

I've worked on these controls over the course of past several years as part of a large library called W2UI. However, I've realized that a stand-alone library with just input controls might be quite useful.

Numeric Inputs

Numeric inputs will only allow you to type numbers. They will completely ignore all other characters. Full keyboard support is implemented. Try using up/down arrow keys, control + up/down (command + up/down on mac) to increase numbers. When the number is changed it will be validated and formatted (if needed).

HTML Setup

<!-- General inputs -->
<div class="w2ui-label"> Integer: </div>
<div class="w2ui-field"> <input id="w2int"> </div>
<div class="w2ui-label"> Float: </div>
<div class="w2ui-field"> <input id="w2float"></div>
<div class="w2ui-label"> Hex: </div>
<div class="w2ui-field"> <input id="w2hex"></div>
<div class="w2ui-label"> Color: </div>
<div class="w2ui-field"> <input id="w2color"></div>

<!-- US format -->
<div class="w2ui-label"> Integer: </div>
<div class="w2ui-field"> <input id="us-int" value="0"> </div>
<div class="w2ui-label"> Float: </div>
<div class="w2ui-field"> <input id="us-float" value="0"> </div>
<div class="w2ui-label"> Money: </div>
<div class="w2ui-field"> <input id="us-money" value="0"> </div>
<div class="w2ui-label"> Percent: </div>
<div class="w2ui-field"> <input id="us-percent" value="0"> </div>

<!-- EU common format -->
<div class="w2ui-label"> Integer: </div>
<div class="w2ui-field"> <input id="eu-int" value="0"> </div>
<div class="w2ui-label"> Float: </div>
<div class="w2ui-field"> <input id="eu-float" value="0"> </div>
<div class="w2ui-label"> Money: </div>
<div class="w2ui-field"> <input id="eu-money" value="0"> </div>
<div class="w2ui-label"> Percent: </div>
<div class="w2ui-field"> <input id="eu-percent" value="0"> </div>

Creating the Interactive Fields

// General
$('#w2int').w2field('int', { autoFormat: false });
$('#w2float').w2field('float', { autoFormat: false });
$('#w2hex').w2field('hex');
$('#w2color').w2field('color');

// US Format
$('#us-int').w2field('int', { autoFormat: true });
$('#us-float').w2field('float', { precision: 3 });
$('#us-money').w2field('money', { moneySymbol: '$' });
$('#us-percent').w2field('percent', { precision: 1, min: 0, max: 100 });

// EU Common Format
$('#eu-int').w2field('int', { autoFormat: true, groupSymbol: ' ' });
$('#eu-float').w2field('float', { groupSymbol: ' ', precision: 3 });
$('#eu-money').w2field('money', { groupSymbol: ' ', currencyPrefix: '', currencySuffix: '€' });
$('#eu-percent').w2field('percent', { precision: 1, min: 0, max: 100 });

Second argument is a list of options, that include the following:

options = {
	min             : null,
	max             : null,
	placeholder     : '',
	autoFormat      : true,
	currencyPrefix  : '$',
	currencySuffix  : '',
	groupSymbol     : ',',
	arrows          : false,
	keyboard        : true,
	precision       : null,
	silent          : true,
	prefix          : '',
	suffix          : ''
}

Date and Time

For DATE and TIME types you can use keyboard to increment by a day (or a minute) if you click up/down arrow keys. You can also use ctr + up/down (command + up/down on mac) to increment by a month (or an hour).

HTML Setup

<!-- US format -->
<div class="w2ui-label"> Date: </div>
<div class="w2ui-field"> <input type="us-date"> </div>
<div class="w2ui-label"> From-To: </div>
<div class="w2ui-field"> <input type="us-dateA"> <span class="legend">(from 10th to 20th of current month)</span></div>
<div class="w2ui-label"> Blocked Days: </div>
<div class="w2ui-field"> <input type="us-dateB"> <span class="legend">(12,13,14 of current month are blocked)</span></div>
<div class="w2ui-label"> Date Range: </div>
<div class="w2ui-field"> <input type="us-date1"> - <input type="us-date2"> </div>
<div class="w2ui-label"> Time: </div>
<div class="w2ui-field"> <input type="us-time"> </div>
<div class="w2ui-label"> From-To: </div>
<div class="w2ui-field"> <input type="us-timeA"> <span class="legend">(from 8:00 am to 4:30 pm)</span></div>

<!-- EU common format -->
<div class="w2ui-label"> Date: </div>
<div class="w2ui-field"> <input type="eu-date"> </div>
<div class="w2ui-label"> From-To: </div>
<div class="w2ui-field"> <input type="eu-dateA"> <span class="legend">(from 10th to 20th of current month)</span></div>
<div class="w2ui-label"> Blocked Days: </div>
<div class="w2ui-field"> <input type="eu-dateB"> <span class="legend">(12,13,14 of current month are blocked)</span></div>
<div class="w2ui-label"> Date Range: </div>
<div class="w2ui-field"> <input type="eu-date1"> - <input type="eu-date2"> </div>
<div class="w2ui-label"> Time: </div>
<div class="w2ui-field"> <input type="eu-time"> </div>
<div class="w2ui-label"> From-To: </div>
<div class="w2ui-field"> <input type="eu-timeA"> <span class="legend">(from 8:00 am to 4:30 pm)</span></div>
<div style="height: 20px; clear: both"></div>

Creating the Interactive Fields

var month = (new Date()).getMonth() + 1;
var year  = (new Date()).getFullYear();

// US Format
$('input[type=us-date]').w2field('date');
$('input[type=us-dateA]').w2field('date', { format: 'm/d/yyyy', start:  month + '/5/' + year, end: month + '/25/' + year });
$('input[type=us-dateB]').w2field('date', { format: 'm/d/yyyy', blocked: [ month+'/12/2014',month+'/13/2014',month+'/14/' + year,]});
$('input[type=us-date1]').w2field('date', { format: 'm/d/yyyy', end: $('input[type=us-date2]') });
$('input[type=us-date2]').w2field('date', { format: 'm/d/yyyy', start: $('input[type=us-date1]') });
$('input[type=us-time]').w2field('time',  { format: 'h12' });
$('input[type=us-timeA]').w2field('time', { format: 'h12', start: '8:00 am', end: '4:30 pm' });

// EU Common Format
$('input[type=eu-date]').w2field('date',  { format: 'd.m.yyyy' });
$('input[type=eu-dateA]').w2field('date', { format: 'd.m.yyyy', start:  '5.' + month + '.' + year, end: '25.' + month + '.' + year });
$('input[type=eu-dateB]').w2field('date', { format: 'd.m.yyyy', blocked: ['12.' + month + '.' + year, '13.' + month + '.' + year, '14.' + month + '.' + year]});
$('input[type=eu-date1]').w2field('date', { format: 'd.m.yyyy', end: $('input[type=eu-date2]') });
$('input[type=eu-date2]').w2field('date', { format: 'd.m.yyyy', start: $('input[type=eu-date1]') });
$('input[type=eu-time]').w2field('time',  { format: 'h24' });
$('input[type=eu-timeA]').w2field('time', { format: 'h24', start: '8:00 am', end: '4:30 pm' });

Options for Date

options = {
	format      : 'm/d/yyyy',  // date format
	placeholder : '',
	keyboard    : true,
	silent      : true,
	start       : '',          // string or jquery object
	end         : '',          // string or jquery object
	blocked     : {},          // { '4/11/2011': 'yes' }
	colored     : {}           // { '4/11/2011': 'red:white' }
};

Options for Time

options = {
	format      : 'hh:mi pm',
	placeholder : '',
	keyboard    : true,
	silent      : true,
	start       : '',
	end         : ''
};

Drop Down Lists

Regular <select> input is nice, but quite limited. For example, it is hard to use this control on a large set of options. To provide a solution, I have implemented drop down list based on a text input filed but with a dynamic list of options that get filtered as you type.

HTML Setup

<div class="w2ui-label"> List: </div>
<div class="w2ui-field"> <input type="list"> <span class="legend">Cannot type any text, but only items from the list</span> </div>
<div class="w2ui-label"> Combo: </div>
<div class="w2ui-field"> <input type="combo"> <span class="legend">You can type any text</span> </div>

Full keyboard support is implemented and it comes with lots of configuration parameters: pulling list of options dynamically from a URL, custom render functions, events, etc.

Creating the Interactive Fields

var people = ['George Washington', 'John Adams', 'Thomas Jefferson', 'James Buchanan', ...];
$('input[type=list]').w2field('list', { items: people });
$('input[type=combo]').w2field('combo', { items: people });
// if you need to get to the selected items, use:
// $('#id').data('selected');

Options for List

options = {
	items       : [],
	selected    : {},           // selected item as {}
	placeholder : '',
	url         : null,         // url to pull data from
	cacheMax    : 500,
	maxWidth    : null,         // max width for input control to grow
	maxHeight   : 350,          // max height for input control to grow
	match       : 'contains',   // ['contains', 'is', 'begins with', 'ends with']
	silent      : true,
	onSearch    : null,         // when search needs to be performed
	onRequest   : null,         // when request is submitted
	onLoad      : null,         // when data is received
	render      : null,         // render function for drop down item
	showAll     : false,        // weather to apply filter or not when typing
	markSearch  : true
};

Multi-Select Drop Down Lists

Another control I am proud of is multi-select. I cannot image how I used to live without it. It simplified all my UI designs where I need to select multiple items and now I do not have to use two bulky lists of Available and Selected items.

HTML Setup

<div class="w2ui-label"> Multi-Select: </div>
<div class="w2ui-field"> <input id="enum"> </div>
<div class="w2ui-label"> Max 2 Items: </div>
<div class="w2ui-field"> <input id="enum-max"> </div>
<div class="w2ui-label"> Custom: </div>
<div class="w2ui-field"> <input id="enum-custom"> </div>

Just like the drop down list, it comes with full keyboard support and lots of configuration options (even more then a drop down list). I hope you would enjoy it just as I have over the course of past few years.

Creating the Interactive Fields

var pstyle = 'padding-right: 3px; color: #828AA7; text-shadow: 1px 1px 3px white;';
var people = ['George Washington', 'John Adams', 'Thomas Jefferson', 'James Buchanan', ...];
$('#enum').w2field('enum', { 
	items: people,
	selected: [{ id: 0, text: 'John Adams' }, { id: 0, text: 'Thomas Jefferson' }]
});
$('#enum-max').w2field('enum', { 
	items: people, 
	max: 2 
});
$('#enum-custom').w2field('enum', { 
	items: people, 
	onAdd: function (event) {
		if (Math.random() > 0.8) {
			event.item.bgColor = 'rgb(255, 232, 232)';
			event.item.border  = '1px solid red';
		}
	},
	itemRender: function (item, index, remove) {
		var html =  
			'<li style="'+ (item.bgColor ? 'background-color: '+ item.bgColor + ';' : '') +
				(item.border ? 'border: '+ item.border + ';' : '') +'" index="'+ index +'">'+
				remove +
				'<span class="fa-trophy" style="'+ pstyle +'; margin-left: -4px;"></span>' + 
				item.text +
			'</li>';
		return html;
	},
	render: function (item, options) {
		return '<span class="fa-star" style="'+ pstyle +'"></span>' + item.text;
	}
});
// if you need to get to the selected items, use:
// $('#id').data('selected');

Options for ENUM

options = {
	items       : [],
	selected    : [],
	placeholder : '',
	max         : 0,            // max number of selected items, 0 - unlim
	url         : null,         // not implemented
	cacheMax    : 500,
	maxWidth    : null,         // max width for input control to grow
	maxHeight   : 350,          // max height for input control to grow
	match       : 'contains',   // ['contains', 'is', 'begins with', 'ends with']
	silent      : true,
	showAll     : false,        // weather to apply filter or not when typing
	markSearch  : true,
	render      : null,         // render function for drop down item
	itemRender  : null,         // render selected item
	itemsHeight : 350,          // max height for the control to grow
	itemMaxWidth: 250,          // max width for a single item
	onSearch    : null,         // when search needs to be performed
	onRequest   : null,         // when request is submitted
	onLoad      : null,         // when data is received
	onClick     : null,         // when an item is clicked
	onAdd       : null,         // when an item is added
	onRemove    : null,         // when an item is removed
	onMouseOver : null,         // when an item is mouse over
	onMouseOut  : null          // when an item is mouse out
};

File Upload

And of course, the controls library would not be complete without a file uploader. I have used HTML5 FileReader API (will not work in old browsers, including IE9) to read the file, encode it into base64 and provide to you as a variable that you can submit with any AJAX request.

<div class="w2ui-label"> Attach Files: </div>
<div class="w2ui-field"> <input id="file"> </div>

This approach is new to me, but I kind of like it. It simplifies my file uploads, though has some limitations. The biggest I found so far is the limitation of file size (slow with files over 50MB), however it is comparable to email attachments, which in fact are also base64 encoded into email body.

On a positive side, once you have file encoded into base64, you can use data url API to preview it (if it is an image) or event resize it before submitting to the server with the HTML5 canvas trick.

JavaScript

$('#file').w2field('file', {});
// if you need to get to the selected files, use:
// $('#file').data('selected');

Options for File

options = {
	selected     : [],
	placeholder  : 'Attach files by dragging and dropping or Click to Select',
	max          : 0,
	maxSize      : 0,        // max size of all files, 0 - unlim
	maxFileSize  : 0,        // max size of a single file, 0 -unlim
	maxWidth     : null,     // max width for input control to grow
	maxHeight    : 350,      // max height for input control to grow
	silent       : true,
	itemRender   : null,     // render selected item
	itemMaxWidth : 250,      // max width for a single item
	itemsHeight  : 350,      // max height for the control to grow
	onClick      : null,     // when an item is clicked
	onAdd        : null,     // when an item is added
	onRemove     : null,     // when an item is removed
	onMouseOver  : null,     // when an item is mouse over
	onMouseOut   : null      // when an item is mouse out
}

Download

All these controls are part of W2UI 1.4 (which is in early beta right now). For your convenience, I have put together a small downloadable package with the files you need:

In order to use it, you will need to include w2ui-fields-1.0.js and w2ui-fields-1.0.css into your app or its minified counterparts. As far as file size goes, it is only 18Kb for the JS file and 6Kb for CSS (minified and gzipped) and has only one dependency - jQuery.

Vitali Malinouski

About Vitali Malinouski

Vitali Malinouski is a front-end developer who is passionate about JavaScript UI. He is thinking a lot how to make it easy for people to create user-friendly interfaces and enjoy doing it. He is the author and regular contributor to JavaScript UI library called W2UI.

Recent Features

  • By
    CSS vs. JS Animation: Which is Faster?

    How is it possible that JavaScript-based animation has secretly always been as fast — or faster — than CSS transitions? And, how is it possible that Adobe and Google consistently release media-rich mobile sites that rival the performance of native apps? This article serves as a point-by-point...

  • By
    How I Stopped WordPress Comment Spam

    I love almost every part of being a tech blogger:  learning, preaching, bantering, researching.  The one part about blogging that I absolutely loathe:  dealing with SPAM comments.  For the past two years, my blog has registered 8,000+ SPAM comments per day.  PER DAY.  Bloating my database...

Incredible Demos

  • By
    Introducing MooTools Dotter

    It's best practice to provide an indicator of some sort when performing an AJAX request or processing that takes place in the background. Since the dawn of AJAX, we've been using colorful spinners and imagery as indicators. While I enjoy those images, I am...

  • By
    Create a Brilliant Sprited, CSS-Powered Firefox Animation

    Mozilla recently formally announced Firefox OS and its partners at Mobile World Congress and I couldn't be more excited.  Firefox OS is going to change the lives of people in developing countries, hopefully making a name for itself in the US as well.  The...

Discussion

  1. Very nice. Wonder if you baked in accessibility features

  2. Good point. Though, it was important for me to do full keyboard support (you can increment numbers, dates, times, and select from drop down menu with arrows), I think accessibility still can be improved. For starters, I think defining hot keys for controls would be nice.

  3. pretty pretty. i wonder what fall back to on mobile?

  4. Sorry to say…but this does not support ie8 / 7 , and its very dissapointing for me. I will appreciate if this support with ie8/7 too…thanks

  5. Jason Burnett

    I hate to say it but ALL of your LIST types have failed miserably in a couple of ways:

    PROBLEM: First and foremost, if you have a list of options available and you have an expand triangle to the right of the list, it should show you the list. Plain and simple. NONE of yours do anything.
    SOLUTION: Either remove them or make them work.

    PROBLEM: There is no visual indication of which kind of list we are dealing with. Can I enter anything I want (no visual indicator) Can I type a couple letters to find the one I want (no visual indicator)
    SOLUTION: Give each list type box it’s own distinct style or include a placeholder or placeholder icon to indicate the type. (select from list) for example would work or a list icon would work.

    PROBLEM: In list types that allow you to use the keyboard for selection based on list criteria, there is no “custom…” or “other…” or “manual …” option in the list indicating that you could manually add a value.
    SOLUTION: add it or make it default and indicate in placeholder

    PROBLEM: if you are going to have iconized names with close boxes next to them in the multiple select fields, you should present the list of options in an iconized format. It is incongruent to have the iconized list and a typical drop down list. (that doesn’t work with the drop-down triangle (see prob1)
    SOLUTION: Create a *persistent (optionally) list of iconized options in a separate column that make it look like “this is the group I want” and “this is the group I don’t want” Then the close box or an arrow would make more sense. Right now you are mixing UI metaphors.

    PROBLEM: Inconsistent measure to select multiple results with keyboard search doesn’t work. If I wanted to add a third or fourth name on your list, the highlight methods don’t work either for the list or for the existing options selected.

    I am really sorry if this sounds harsh. This is a good effort and I applaud the idea behind it, but it just doesn’t have the polish that it should.

    • Jason, appreciate your feedback. I agree with some points you raised. Give me a few days to work thru the list and improve. Just a few notes about 4th and 5th issues. About icons in the selection and in the drop down list, I noticed that icons do not match, which is inconsistent, I agree. Well, it is just an example how to add custom renderers (or I misunderstood what you meant). Regarding last issue, I did not understand what exactly did you meant. Did you mean that there should be a way to delete selected items with keyboard?

  6. ohaleck

    Nice :) There are issues with dual displays though. When I clicked the button in date selector, calendard appeared on another screen (Chrome/MacOS X). Just letting u know :)

    • Thanks. I have tried on my mac book pro with an external monitor and when I open in Chrome on laptop, it opens on laptop. When on the monitor, it opens on the monitor. What is your setup like? I wonder if it was just a fluke.

  7. Hey Vitali,

    thanks for the work, is great stuff with nice formating and styling. I have a question: Do you know how and if is possible to implement it with jeditable (http://www.appelsiini.net/projects/jeditable). That would be great

    regards
    florin

  8. Pavel Třupek

    Hi,
    first of all, I would like to thank you for this script. Is there any possibility to make it work for dynamically created elements? Lets say I have the css class .w2int which is “initialized” via

    $('.w2int').w2field('int', { autoFormat: false });

    and I’d like to create a new element

    $(body).append($("").addClass("w2int"));

    and automatically handle it with .w2int.

    Thanks for your response
    Pavel

  9. Craig

    Doesn’t work with GBP sign £ nor encoded as £ nor as &#163.

    ? how do I get GBP sign to work?

    • I have tried this

      w2utils.settings.currencyPrefix = '£';
      $('#field').w2field('money')
      

      And it seems to be working fine

  10. i want use tag .. but it appear only in chrome browser.. what shall i do for render this control in all browser….
    please give any idea abt this……. if any attribute i want to add this tag means , tell that attribute name……..
    thanks

  11. for the Date and Time i wonder if its possible to set the 1st day of the week as Sunday?

    • Yes. But not in the version posted on this website. If you download latest from github, then you can set w2utils.settings.weekStarts = ‘S’ and it will display weeks starting with Sunday

  12. What is “Second argument is a list of options,” means?
    Where’s the second argument?
    Where to put all that Creating the Interactive Fields part?

  13. kt

    Is there a more complete example anywhere of using the file upload field but then actually doing something with the uploaded data?

    I don’t understand how to trigger an operation when a file is uploaded. I thought it was just the “onAdd” option, but this seems to be called when the page loads (FFox 56.0) and not when a file is added/uploaded. None of the examples here, or on the w2ui site cover using the file data.

Wrap your code in <pre class="{language}"></pre> tags, link to a GitHub gist, JSFiddle fiddle, or CodePen pen to embed!