Having fun with HTML5 and Vaadin

Matti Tahvonen
Matti says about web apps…
5 min readFeb 5, 2016

I have been in a terrible flu for a week now. I hate not to be able to go out and enjoy the nice winter weather, but I have also had lots of time to spend with my computer, hacking with HTML5 features and Vaadin. Pretty fun actually. I wanted to try a slider (aka <input type=”range” />), number field with a steppers (aka <input type=”number” />), clearable search field (aka <input type=”search” />) etc. — on Vaadin of course.

As Vaadin has a rather wide browser support (currently until IE 6 with Vaadin 6 , IE8 with Vaadin 7), we haven’t rushed to get these all these new and somewhat non-standard features baked into the core framework. Instead the community has been active and created lots of cross-browser compatible add-ons, using composition and some GWT/JS magic, like e.g. the Stepper add-on and multiple number field implementations. But on the other hand, not everybody needs to support legacy browsers and many of these cool new HTML5 features degrade gracefully. Let’s make using them possible!

The basis

Vaadin TouchKit has for years had a really handy helper class called Html5InputSettings. Even if you didn’t know about it, you might have used it — via e.g. NumberField in the same add-on. I have for a long time planned to build similar tool to Viritin, but the issue has been that one of Viritin’s main targets has been to avoid requiring a widgetset (and that way bit sluggy GWT compiliation).

The workaround was to use a JavaScript extension. I had never used those before and almost got dropped the whole idea due to some issue I had in the beginning, but finally I got my extension working pretty well. HtmlElementPropertySetter extension now supports setting html element properties in any Vaadin component and with a more advanced XPath selector API, you can set properties of virtually any elements — and also multiple elements at once. And, in addition to just setting basic properties, I also added a possibility to assign JavaScript handlers as well.

Below are some some examples that I used while developing the extension:

TextField rawTextField = new TextField();
HtmlElementPropertySetter s1 = new HtmlElementPropertySetter(
rawTextField);
s1.setProperty("type", "number");
s1.setProperty("min", "10");
s1.setProperty("max", "100");
// prevent all but numbers with a simple js
s1.setJavaScriptEventHandler("keypress",
"function(e) {var c = viritin.getChar(e); return c==null || /^[\\d\\n\\t\\r]+$/.test(c);}");
mVerticalLayout.add(rawTextField);

HtmlElementPropertySetter s2 = new HtmlElementPropertySetter(
mVerticalLayout);
// sets with xpath, same could be also done via s1 as
// using document global selector (// vs .//)
s2.setProperty("//input", "step", "10");
s2.setProperty("//input", "required", "true");

TextField rawTextField2 = new TextField();
TextField rawTextField3 = new TextField();
final MVerticalLayout dates = new MVerticalLayout(rawTextField2,
rawTextField3).withCaption("dates");

HtmlElementPropertySetter s3 = new HtmlElementPropertySetter(
dates);
// set all inputs inside dates layout to be of type date
s3.setProperty(".//input", "type", "date");

mVerticalLayout.add(dates);

It makes this for example this kind of input elements:

<input type="number" min="10" max="100" step="10" required=""> <input type="date" step="10" required="">

And this is how it looks in Chrome:

On mobile devices you’d get a number keyboard for the upper field and with desktop browser you’ll get small up and down steppers (shown only when focused). Pretty handy.

One thing I want to emphasis at this point: please, don’t make me mad, I don’t want to see your application code where you use this tool directly. That will be really bad for your code quality and breaks the abstraction of web technologies that Vaadin gives you. Always hide these browser level details behind your own Vaadin components (extensions, compositions) and a proper Java API.

So how to use it then? At least I was able to create couple of fancy inputs components and, also, fixed some bugs and UX issue that this HTML5 era has caused for us.

Disabling autocomplete

“autocomplete” is one of the properties supported by most modern browsers. Autocomplete (and related autocorrect and autocapitalise) are generally really nice features, especially on small mobile devices, but in certain fields it can be really disturbing feature. Think of a login screen of an old web app and think about using that with your iPhone. I guess you know what I mean.

I used the HtmlElementPropertySetter extension right away in MTextField. Now it is really simple to disable these handy, but in some situations really disturbing, features, per field basis:

private MTextField username = new MTextField("User")
.withAutocompleteOff()
.withAutoCorrectOff()
.withAutoCapitalizeOff();

Autocomplete can be even trickier in some composites, like ComboBox. There the suggestions of a browser might pop over the “real suggestion” provided by your application. See this ticket if you don’t know what I mean. In Viritin pretty much all ComboBoxes (in e.g. via TypedSelect or LazyComboBox) now automatically add a workaround for this issue with the following rules:

HtmlElementPropertySetter heps = new 
HtmlElementPropertySetter(comboBox);
heps.setProperty("./input", "autocorrect", "off"); heps.setProperty("./input", "autocomplete", "off"); heps.setProperty("./input", "autocapitalize", "off");

Creating a number field

Adding a type=”number” property sure makes the UX already better, but I’d argue that it is still far form a perfect number field. There are different types of numbers, different kind of localisations and the number type alone don’t prevent you users input normal characters as well to the field. I wanted to start from the most simple component, so I created a component called IntegerField to Viritin.

With only the type number, you’ll get the number oriented keyboard activated on mobile devices and modern desktop browsers will show “steppers”, but practically users can still input pretty much anything if they want. I wanted to prevent inserting any non-numeric characters. This is where the JS support became handy:

// prevent all but numbers with a simple js s.setJavaScriptEventHandler("keypress",         "function(e) {var c = viritin.getChar(e); return c==null || /^[\d\n\t\r]+$/.test(c);}");

The code is mostly typical JavaScript so it needs a more throughout explanation 🙂 Practically i’m intercepting all keypress events, and using a helper function to grab the character to by added with this key stroke. If it is not a number, enter or tab, I’m cancelling the event and the character will never be added to the input. Enter and tab are “passed through” as we’ll want to let users to enter the value or move to next field with keyboard.

The new IntegerField supports all known goodies from Viritin, like the “eager validation”, which is essential for those who aim for the best possible UX. I also extracted a superclass form it, so it should be rather easy to add other number field implementations (Double, Long, Float…) in the future. DoubleField probably needs bit more thinking to a get proper localisation and formatting to it, but adding one shouldn’t be rocket surgery.

Instead of getting to implement DoubleField, I decided to try <input type=”range” />. That practically creates a native slider component, similar to our Slider. Not that big aid for Vaadin developers as we already have a good Slider, but a cool technology demo 😉 The new IntegerSliderField has one advantage over our Slider though: it automatically reads min and max configurations from your bean validation annotations!

For more details how to use IntegerField or IntegerSlider field, see the IntegerFieldUsage example class in Viritin project or just download the latest version from the Directory and try it yourself. All input is highly appreciated, preferably as GitHub issues. I’d like to get worst typos and brain farts fixed as soon as possible!

I enjoyed hacking with this stuff, I hope you like using it!

--

--