HTML5 Input Types Alternative
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.
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.
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.
Very nice. Wonder if you baked in accessibility features
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.
pretty pretty. i wonder what fall back to on mobile?
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
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?
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.
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
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
and I’d like to create a new element
and automatically handle it with .w2int.
Thanks for your response
Pavel
Doesn’t work with GBP sign £ nor encoded as £ nor as £.
? how do I get GBP sign to work?
I have tried this
And it seems to be working fine
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
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
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?
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.