{"id":82886,"date":"2019-01-09T21:36:40","date_gmt":"2019-01-09T21:36:40","guid":{"rendered":"https:\/\/www.red-gate.com\/simple-talk\/?p=82886"},"modified":"2022-05-02T20:46:22","modified_gmt":"2022-05-02T20:46:22","slug":"better-html5-input-fields","status":"publish","type":"post","link":"https:\/\/www.red-gate.com\/simple-talk\/development\/javascript\/better-html5-input-fields\/","title":{"rendered":"Better HTML5 Input Fields"},"content":{"rendered":"<p>HTML5 boldly came with the claim that it would offer more realistic input fields able to serve the needs of web applications. Apparently the HTML5 standards supports a long list of input types well beyond the historical short group of text, password, checkbox, radio, file, and button form input fields. The new list includes date\/time specific input fields and types of input fields to accept ad hoc data such email addresses, URLs, phone numbers and plain numbers. The syntax of the <code>INPUT<\/code> element was extended to make up for new features. For example, the <code>date<\/code> input field now recognizes two extra attributes such as <code>min<\/code> and <code>max<\/code> to denote the earliest and latest dates that the control can accept.<\/p>\n<p>It\u2019s not gold all that shines though. Much of the work is left to browsers, and browsers, for a number of reasons, don\u2019t typically hard-code much of the behavior that one might expect. In particular, no browser would check the validity of the input the user entered until the form is submitted. This means that users are apparently allowed to type any sort of characters in, say, a numeric input field just to find out that the input is invalid when they push the submit button. The same thing happens for phone numbers, websites, email addresses, dates and the like.<\/p>\n<p>Finding a workaround is not a hard task, but it takes a bit of JavaScript code. Worse yet, it takes a bit of JavaScript code that must be written over and over again for every single use of any of the rich HTML5 input fields. This article intends to provide a jQuery-based JavaScript library\u2014just a bunch of selectors actually\u2014that when loaded into a layout page will extend a standard and more specific behavior to some HTML5 input fields. In particular, the library will automatically pre-process a number of HTML5 input fields adding to them the ability to react to invalid input on the <code>blur<\/code> event. The benefit for web developers is that you only need to reference the JavaScript library and that\u2019s it\u2014all will happen silently and effectively.<\/p>\n<p>Although the library is provided as a jQuery extension, it wouldn\u2019t take much to adapt jQuery selectors to plain DOM selectors and make it work even without jQuery.<\/p>\n<h2>Covered Use Cases<\/h2>\n<p>The HTML form input fields being modified in this article is described in the table below that lists the type of the input field and the implemented changes.<\/p>\n<table>\n<tbody>\n<tr>\n<td>\n<p>INPUT<\/p>\n<\/td>\n<td>\n<p>DESCRIPTION<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p>&lt;input type=&#8221;email&#8221; \/&gt;<\/p>\n<\/td>\n<td>\n<p>Validate the email address as the user tabs out based on a fixed regular expression<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p>&lt;input type=&#8221;url&#8221; \/&gt;<\/p>\n<\/td>\n<td>\n<p>Validate the URL as the user tabs out based on a fixed regular expression<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p>&lt;input type=&#8221;tel&#8221; \/&gt;<\/p>\n<\/td>\n<td>\n<p>Validate the phone number based as the user tabs out based on user-defined regular expression<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p>&lt;input type=&#8221;number&#8221; \/&gt;<\/p>\n<\/td>\n<td>\n<p>Forces the user to only enter digits and automatically refuses any number outside the min\/max range.<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p>&lt;input type=&#8221;password&#8221; \/&gt;<\/p>\n<\/td>\n<td>\n<p>Adds a button to toggle the type of the field between <em>password<\/em> and <em>text <\/em>allowing users to read the current password in clear.<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p>&lt;input type=&#8221;text&#8221; \/&gt;<\/p>\n<\/td>\n<td>\n<p>Honors the <em>pattern<\/em> attribute when the user tabs out of the field.<\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>Let\u2019s find out more and proceed case by case. Note that to exercise more control over validation phase of HTML5 forms, you might want to check out the <a href=\"https:\/\/html.spec.whatwg.org\/multipage\/form-control-infrastructure.html#the-constraint-validation-api\">spec of the validity browser API<\/a>.<\/p>\n<h2>Validating Email Addresses<\/h2>\n<p>Certainty vanishes suddenly when it comes to validating emails. Every application, depending on the locales, may have different edge cases. HTML5 browsers do have a built-in engine to validate email addresses but, as mentioned, validation is only triggered upon form submission. If you want to have the email validated as soon as the user tabs out of the input field, then some ad hoc JavaScript is the only option left.<\/p>\n<p>Here\u2019s the skeleton of the JavaScript you want to have in place in all of your web pages with some HTML forms.<\/p>\n<pre class=\"lang:c# theme:vs2012\">$(\"input[type=email]\").on(\"blur\",\r\n\u00a0\u00a0\u00a0\u00a0function\u00a0()\u00a0{\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0var\u00a0email\u00a0=\u00a0$(this).val();\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0var\u00a0re\u00a0= \/ ... \/;\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0var\u00a0success\u00a0=\u00a0re.test(email);\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0if\u00a0(success)\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0$(this).removeClass(\"is-invalid\");\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0else\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0$(this).addClass(\"is-invalid\");\r\n\u00a0\u00a0\u00a0\u00a0});<\/pre>\n<p>A handler for the DOM <code>blur<\/code> event is set up for any <code>INPUT<\/code> element with the type attribute set to <em>email<\/em>. The jQuery-based body of the handler first grabs the current value of the input field and then checks it against a provided regular expression.<\/p>\n<pre class=\"lang:c# theme:vs2012\">\/\/\u00a0YBQ\u00a0FORMS\r\nvar\u00a0success\u00a0=\u00a0re.test(email);<\/pre>\n<p>If the check is successful, then input field removes any <code>is-invalid<\/code> CSS class it may have. Otherwise, the input field just adds the <code>is-invalid<\/code> CSS class. Note that <code>is-invalid<\/code> is a Bootstrap 4 specific class aimed at rendering input fields with a red border to notify the invalid state. Needless to say, if you do not wish to use Bootstrap 4 to style your web page, then you\u2019re welcome to apply any other CSS transformation to the DOM that reflects the invalid state of the element.<\/p>\n<p>There\u2019s a bit more you want to do, however, in the <code>blur<\/code> handler. First, you might want to deal with an empty or whitespace content. A blank field is valid or not? The idea here is to use the HTML5 <code>required<\/code> attribute to settle the question. If required is found, then the blank content should be parsed against the regular expression, otherwise, any further check is skipped and the content is validated.<\/p>\n<pre class=\"lang:c# theme:vs2012\">$(\"input[type=email]\").on(\"blur\",\r\n\u00a0\u00a0\u00a0\u00a0function\u00a0()\u00a0{\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0var\u00a0email\u00a0=\u00a0$.trim($(this).val());\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<strong>var\u00a0required\u00a0=\u00a0$(this).attr(\"required\")\u00a0!=\u00a0null;<\/strong>\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0if\u00a0(email.length\u00a0===\u00a00\u00a0&amp;&amp;\u00a0!required)\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0return;\r\n\r\n        \/\/ more code ...\r\n});<\/pre>\n<p>Second, you can use the HTML5 <code>pattern<\/code> attribute to indicate a form-specific regular expression for the handler to process. If the attribute is not specified then the handler uses a built-in regular expression. Check out the <a href=\"https:\/\/bit.ly\/2znGhVP\">source code<\/a> for details.<\/p>\n<pre class=\"lang:c# theme:vs2012\"> $(\"input[type=email]\").on(\"blur\",\r\n\u00a0\u00a0\u00a0\u00a0function\u00a0()\u00a0{\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0var\u00a0email\u00a0=\u00a0$.trim($(this).val());\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0<strong>var\u00a0required\u00a0=\u00a0$(this).attr(\"required\")\u00a0!=\u00a0null;<\/strong>\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0if\u00a0(email.length\u00a0===\u00a00\u00a0&amp;&amp;\u00a0!required)\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0return;\r\n        var\u00a0re\u00a0= \/ ... \/;\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0var\u00a0pattern\u00a0=\u00a0$(this).attr(\"pattern\");\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0if\u00a0(pattern\u00a0!=\u00a0null)\u00a0{\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0re\u00a0=\u00a0new\u00a0RegExp($(this).attr(\"pattern\"));\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}\r\n        var\u00a0success\u00a0=\u00a0re.test(email);\r\n        \r\n        \/\/ more code ...\r\n});<\/pre>\n<p>The net effect is shown in the figure below. Note that most browsers also provide detailed error messages in the form of tooltips. Note also that the error message displayed through the tooltip is based on the browser\u2019s internal email regular expression which might be different from the one hard-coded in the library or that you may have set through the <code>pattern<\/code> attribute. To turn off the tooltip, you just set the <code>title<\/code> attribute of the <code>INPUT<\/code> field to the empty string or anything else you like.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"645\" height=\"314\" class=\"wp-image-82887\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2019\/01\/word-image-80.png\" \/><\/p>\n<h2>Validating URLs<\/h2>\n<p>Validating a URL input field poses exactly the same challenges as validating an email address as in the HTML5 spec. The type <code>url<\/code> supports the same attributes as the type <code>email<\/code>. Here\u2019s then the code you need to have in place.<\/p>\n<pre class=\"lang:c# theme:vs2012\">$(\"input[type=url]\").on(\"blur\",\r\n\u00a0\u00a0\u00a0\u00a0function\u00a0()\u00a0{\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0var\u00a0url\u00a0=\u00a0$.trim($(this).val());\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0var\u00a0required\u00a0=\u00a0$(this).attr(\"required\")\u00a0!=\u00a0null;\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0if\u00a0(url.length\u00a0===\u00a00\u00a0&amp;&amp;\u00a0!required)\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0return;\r\n        var\u00a0re\u00a0= \/ ... \/;\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0var\u00a0pattern\u00a0=\u00a0$(this).attr(\"pattern\");\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0if\u00a0(pattern\u00a0!=\u00a0null)\u00a0{\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0re\u00a0=\u00a0new\u00a0RegExp($(this).attr(\"pattern\"));\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}\r\n\r\n        var\u00a0success\u00a0=\u00a0re.test(url);\r\n        if\u00a0(success)\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0$(this).removeClass(\"is-invalid\");\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0else\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0$(this).addClass(\"is-invalid\");\r\n});<\/pre>\n<p>For details about the default regular expression used to check the scheme of the URL refer to the <a href=\"https:\/\/bit.ly\/2znGhVP\">source code<\/a>.<\/p>\n<h2>Validating Phone Numbers<\/h2>\n<p>The code to extend input fields of type <code>tel<\/code> is slightly simpler and for a good reason: there\u2019s nearly no chance that someone can come up with a sufficiently agreed, default regular expression for validating phone numbers. Because of this, the sample library doesn\u2019t even attempt to support a default regular expression and just uses any expressions provided through the HTML5 <code>pattern<\/code> attribute. This makes the overall <code>blur<\/code> handler a bit shorter, as below.<\/p>\n<pre class=\"lang:c# theme:vs2012\">$(\"input[type=tel]\").on(\"blur\",\r\n\u00a0\u00a0\u00a0\u00a0function\u00a0()\u00a0{\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0var\u00a0tel\u00a0=\u00a0$(this).val();\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0var\u00a0required\u00a0=\u00a0$(this).attr(\"required\")\u00a0!=\u00a0null;\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0if\u00a0(tel.length\u00a0===\u00a00\u00a0&amp;&amp;\u00a0!required)\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0return;\r\n \r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0var\u00a0re\u00a0=\u00a0new\u00a0RegExp($(this).attr(\"pattern\"));\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0var\u00a0success\u00a0=\u00a0re.test(tel);\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0if\u00a0(success)\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0$(this).removeClass(\"is-invalid\");\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0else\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0$(this).addClass(\"is-invalid\");\r\n\u00a0\u00a0\u00a0\u00a0});<\/pre>\n<p>This said, what would be at least a good candidate to validate phone numbers? Here\u2019s my shot at it:<\/p>\n<pre class=\"lang:c# theme:vs2012\">&lt;div\u00a0class=\"form-group\"&gt;\r\n\u00a0\u00a0\u00a0\u00a0&lt;label\u00a0for=\"phone\"&gt;Phone&lt;\/label&gt;\r\n\u00a0\u00a0\u00a0\u00a0&lt;input\u00a0type=\"tel\"\u00a0class=\"form-control\"\u00a0\r\n           id=\"phone\"\u00a0name=\"phone\"\u00a0\r\n\u00a0\u00a0\u00a0pattern=\"[+][0-9]{1,3}\u00a0[0-9]{3}[\\s-][0-9]{4}[\\s-][0-9]{3}\"\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0placeholder=\"+x\u00a0xxx-xxxx-xxx\"&gt;\r\n\u00a0\u00a0\u00a0\u00a0&lt;div\u00a0class=\"invalid-feedback\"&gt;\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0Phone\u00a0number\u00a0must\u00a0be\u00a0+x\u00a0xxx-xxxx-xxx\r\n\u00a0\u00a0\u00a0\u00a0&lt;\/div&gt;\r\n&lt;\/div&gt;<\/pre>\n<p>The phone number matched by the expression above is <em>+X XXX-XXXX-XXX<\/em>. To be precise, the dash (-) can also be replaced with a blank character. The international country code is up to three digits and number is grouped in three chunks of 3, 4, 3 digits respectively.<\/p>\n<h2>Accepting Numbers<\/h2>\n<p>Personally, I just hate to be able to type anything into a textbox only to receive a warning through a tooltip and an error message later. If the input field is declared to be of type <code>number<\/code>, then users should never be able to type in anything but digits. Here\u2019s how to do it.<\/p>\n<pre class=\"lang:c# theme:vs2012\">$(\"input[type=number]\")\r\n\u00a0\u00a0\u00a0\u00a0.on(\"keypress\",\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0function\u00a0(event)\u00a0{\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0if\u00a0(event.charCode\u00a0&lt;\u00a048\u00a0||\u00a0event.charCode\u00a0&gt;\u00a057)\u00a0{\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0event.preventDefault();\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0return\u00a0false;\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0})\r\n\u00a0\u00a0\u00a0\u00a0.on(\"keyup\",\u00a0function\u00a0()\u00a0{\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0var\u00a0buffer\u00a0=\u00a0$(this).val();\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0var\u00a0maxLength\u00a0=\u00a0parseInt($(this).attr(\"maxlength\"));\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0if\u00a0(buffer.length\u00a0&gt;\u00a0maxLength)\u00a0{\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0$(this).val(\"\");\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0return\u00a0false;\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0var\u00a0minVal\u00a0=\u00a0parseInt($(this).attr(\"min\"));\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0var\u00a0maxVal\u00a0=\u00a0parseInt($(this).attr(\"max\"));\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0var\u00a0number\u00a0=\u00a0parseInt(buffer);\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0if\u00a0(number\u00a0&lt;\u00a0minVal\u00a0||\u00a0number\u00a0&gt;\u00a0maxVal)\u00a0{\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0$(this).val(\"\");\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0return\u00a0false;\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0return\u00a0true;\r\n\u00a0\u00a0\u00a0\u00a0});<\/pre>\n<p>There are two handlers: one for <code>keypress<\/code> and one for <code>keyup<\/code>. The former refuses any keyboard button different from 0-9 digits. Admittedly, this implementation doesn\u2019t support anything but positive integers. The <code>keyup<\/code> handler, instead, ensures that any number typed falls within the defined min\/max range.<\/p>\n<p>HTML5, in fact, allows you to set a <code>min<\/code> and a <code>max<\/code> attribute on numeric fields to delimit the range of feasible values. However, those boundaries are not checked until the form is submitted. With the <code>keyup<\/code> implementation, instead, the current value of the buffer is turned into an integer, checked against the min\/max interval and emptied if it falls outside. In this way, the input field only returns integers (or blanks) in the given range.<\/p>\n<p>In addition, the <code>keyup<\/code> handler also ensures that no more digits than <code>maxlength<\/code> are ever typed. The point is that, even though the range is, say, 1-20 and no value outside 1-20 will ever be allowed when tabbing out, then there\u2019s no reason for the user to be able to type in more than 2 digits.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"596\" height=\"182\" class=\"wp-image-82888\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2019\/01\/word-image-2.gif\" \/><\/p>\n<h2>Extended Password Input Fields<\/h2>\n<p>The HTML5 spec adds a couple of features on password input fields that alone reduce the need for validating the password at least on the client. They are <code>minlength<\/code> and <code>maxlength<\/code> attributes, whose meaning is quite self-explanatory. In addition, HTML5 password input fields also support the <code>pattern<\/code> attribute which can be set to a JavaScript acceptable regular expression. In all these cases, though, remains the issue that any validation is performed when it might be annoying for users to note\u2014upon form submission. Here\u2019s how to add prompt notification of min\/max length violation in the proposed password.<\/p>\n<pre class=\"lang:c# theme:vs2012\">$(\"input[type=password]\").on(\"blur\",\r\n\u00a0\u00a0\u00a0\u00a0function()\u00a0{\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0var\u00a0pswd\u00a0=\u00a0$.trim($(this).val());\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0var\u00a0minLength\u00a0=\u00a0parseInt($(this).attr(\"minlength\"));\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0var\u00a0maxLength\u00a0=\u00a0parseInt($(this).attr(\"maxlength\"));\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0if\u00a0(isNaN(minLength))\u00a0{\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0minLength\u00a0=\u00a00;\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0if\u00a0(isNaN(maxLength))\u00a0{\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0maxLength\u00a0=\u00a0100;\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0if\u00a0(pswd.length\u00a0&lt;\u00a0minLength\u00a0||\u00a0\r\n            pswd.length\u00a0&gt;\u00a0maxLength)\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0$(this).addClass(\"is-invalid\");\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0else\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0$(this).removeClass(\"is-invalid\");\r\n\u00a0\u00a0\u00a0\u00a0});<\/pre>\n<p>Quite simply, the blur handler captures the value of the <code>minlength<\/code> and <code>maxlength<\/code> attributes, turns them into numbers and compares with the actual length of the password buffer. Leading and trailing blanks are automatically removed. The password field also supports a <code>pattern<\/code> attribute for you to add some regular expressions to parse the proposed password. To add support for the pattern, just copy the same code seen above for email and URL fields.<\/p>\n<p>One more thing you can do for password fields is adding\u2014automatically\u2014a button to switch between the password and text mode so that the password can be seen in clear.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"776\" height=\"118\" class=\"wp-image-82889\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2019\/01\/word-image-3.gif\" \/><\/p>\n<p>The necessary code is shown below. You just add it to the input field reference side by side with the <code>blur<\/code> handler.<\/p>\n<pre class=\"lang:c# theme:vs2012\">$(\"input[type=password]\").each(function()\u00a0{\r\n\u00a0\u00a0\u00a0\u00a0$(this)\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0.add(\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\"&lt;span\u00a0class='input-group-btn'&gt;\"\u00a0+\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\"&lt;button\u00a0type='button'\u00a0class='btn\u00a0btn-primary'\u00a0\r\n             onclick='__togglePswdView(this)'&gt;\"\u00a0+\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\"&lt;i\u00a0class='fa\u00a0fa-eye'&gt;&lt;\/i&gt;&lt;\/button&gt;&lt;\/span&gt;\")\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0.wrapAll(\"&lt;div\u00a0class='input-group'\u00a0\/&gt;\");\r\n}).on(\"blur\", function() {\r\n    <strong>\/\/\u00a0blur handler body<\/strong>\r\n});<\/pre>\n<p>The code just uses the Bootstrap 4 markup for input button groups and attached some plain JavaScript code to toggle the value of the password\u2019s <code>type<\/code> attribute.<\/p>\n<pre class=\"lang:c# theme:vs2012\">function\u00a0__togglePswdView(elem)\u00a0{\r\n\u00a0\u00a0\u00a0\u00a0var\u00a0pswd\u00a0=\u00a0$(elem).closest(\"div\").find(\"input\");\r\n\u00a0\u00a0\u00a0\u00a0var\u00a0type\u00a0=\u00a0$(pswd).attr(\"type\");\r\n\u00a0\u00a0\u00a0\u00a0if\u00a0(type\u00a0===\u00a0\"password\")\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0pswd.attr(\"type\",\u00a0\"text\");\r\n\u00a0\u00a0\u00a0\u00a0else\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0pswd.attr(\"type\",\u00a0\"password\");\r\n}<\/pre>\n<h2>Controlling Input in Text Fields<\/h2>\n<p>Sometimes input fields are only allowed to take digits, letters and perhaps a few extra chars. You can use the <code>pattern<\/code> attribute set to a regular expression but if you do so you also need some of the aforementioned JavaScript to force the expression to be matched during the <code>blur<\/code> event.<\/p>\n<pre class=\"lang:c# theme:vs2012\">$(\"input[type=text]\").on(\"blur\",\r\n\u00a0\u00a0\u00a0\u00a0function\u00a0()\u00a0{\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0var\u00a0text\u00a0=\u00a0$(this).val();\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0var\u00a0re\u00a0=\u00a0\/(?:)\/;\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0var\u00a0pattern\u00a0=\u00a0$(this).attr(\"pattern\");\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0if\u00a0(pattern\u00a0!=\u00a0null)\u00a0{\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0re\u00a0=\u00a0new\u00a0RegExp($(this).attr(\"pattern\"));\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0var\u00a0success\u00a0=\u00a0re.test(text);\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0if\u00a0(success)\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0$(this).removeClass(\"is-invalid\");\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0else\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0$(this).addClass(\"is-invalid\");\r\n\u00a0\u00a0\u00a0\u00a0});<\/pre>\n<p>In this way, to force an alphanumeric input, you only need the following regular expression.<\/p>\n<pre class=\"lang:c# theme:vs2012\">&lt;input\u00a0type=\"text\"\u00a0class=\"form-control\"\u00a0\r\n       id=\"username\"\u00a0name=\"username\"\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0pattern=\"[a-zA-Z0-9]\" \/&gt;<\/pre>\n<h2>Summary<\/h2>\n<p><a id=\"post-82886-_gjdgxs\"><\/a> HTML5 is now widely supported across modern browsers, but it pays for the goal of being a broad specification. As far as <code>INPUT<\/code> fields are concerned, there are plenty of options and a good enough range of attributes. The only problem is when those attributes are honored. Validation always takes place when the form is submitted, but this is not ideal for most scenarios when you want to give users immediate feedback about what they may have been doing wrong. In this case, JavaScript is necessary and the Ybq free library that comes with this article makes it trivially easy to trigger validation when and how you most need it. The source code is available <a href=\"https:\/\/bit.ly\/2znGhVP\">here<\/a>.<\/p>\n<p>&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Filling out online forms is often tedious, but it&#8217;s even more frustrating when the input is not checked until you click Submit. In this article, Dino Esposito shows how to create smart forms that validate the input as it&#8217;s being entered.&hellip;<\/p>\n","protected":false},"author":221911,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[146044],"tags":[95509],"coauthors":[6780],"class_list":["post-82886","post","type-post","status-publish","format-standard","hentry","category-javascript","tag-standardize"],"acf":[],"_links":{"self":[{"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/posts\/82886","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/users\/221911"}],"replies":[{"embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/comments?post=82886"}],"version-history":[{"count":2,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/posts\/82886\/revisions"}],"predecessor-version":[{"id":82891,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/posts\/82886\/revisions\/82891"}],"wp:attachment":[{"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/media?parent=82886"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/categories?post=82886"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/tags?post=82886"},{"taxonomy":"author","embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/coauthors?post=82886"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}