474

In my forms, I'd like to use the new HTML form types, for example <input type="url" /> (more info about the types here).

The problem is that Chrome wants to be super helpful and validate these elements for me, except that it sucks at it. If it fails the built-in validation, there's no message or indication other than the element getting focus. I prefill URL elements with "http://", and so my own custom validation just treats those values as empty strings, however Chrome rejects that. If I could change its validation rules, that would work too.

I know I could just revert back to using type="text" but I want the nice enhancements using these new types offers (eg: it automatically switches to a custom keyboard layout on mobile devices):

Is there a way to switch off or customise the automatic validation?

TylerH
  • 20,799
  • 66
  • 75
  • 101
nickf
  • 537,072
  • 198
  • 649
  • 721
  • 9
    The HTML 5.1 draft spec mentions an [`inputmode` attribute](http://www.w3.org/html/wg/drafts/html/master/single-page.html#input-modalities:-the-inputmode-attribute), which - if I'm understanding what I read correctly - can be used for specifying what keyboard type should be offered to the user when they interact with the field, *without* also implying any validation rules. At some point in the future, using the `inputmode` attribute instead of the `type` attribute will probably be the correct solution to this problem - but not yet. – Mark Amery Dec 12 '13 at 13:55
  • @MarkAmery Although it wouldn't be too hard to get the future now: `$('[inputmode]').each(function () { this.attr({type: this.attr('inputmode'), novalidate: true}) });` – Marnen Laibow-Koser Jul 03 '14 at 19:22
  • 1
    @MarnenLaibow-Koser While what you've described works if all you want to do is turn the validation off (as specified by the question asker), it doesn't quite achieve the same result as `inputmode` would. Doing things your way, you still can't (for example) read non-numeric values that the user types into an input box of type `number`. For example, try typing something non-numeric into the text box in [this fiddle](http://jsfiddle.net/p4uaF/) and clicking the button. – Mark Amery Jul 03 '14 at 20:07
  • @MarkAmery Interesting. Is that because `` doesn't accept non-numeric values at all? – Marnen Laibow-Koser Jul 07 '14 at 13:24
  • @MarnenLaibow-Koser I guess so. The accepted answer on [this question](http://stackoverflow.com/questions/18852244/how-to-get-the-raw-value-an-input-type-number-field) about the problem includes a link to spec that the answerer claims mandates this behaviour. – Mark Amery Jul 07 '14 at 14:21
  • is there a way to disable validation for a single input tag? – blkpingu Oct 04 '19 at 16:53

10 Answers10

851

If you want to disable client side validation for a form in HTML, add the novalidate attribute to the form element. Ex:

<form method="post" action="/foo" novalidate>...</form>

See https://www.w3.org/TR/html5/sec-forms.html#element-attrdef-form-novalidate

TylerH
  • 20,799
  • 66
  • 75
  • 101
Jakob S
  • 19,575
  • 3
  • 40
  • 38
  • 100
    `novalidate="novalidate"` and `novalidate=""` is valid syntax, too. – bassim May 30 '12 at 13:20
  • 14
    @bassim Valid syntax but overly verbose—why type more than you need to? – user1569050 Jan 16 '13 at 14:17
  • @user1569050 True but sometimes it's not your decision and you just want to validate it. So basically just for the sake of completeness. – bassim Jan 23 '13 at 09:36
  • 11
    @user1569050 For example in frameworks like CakePHP, it will use the `novalidate="novalidate"` method when you set the `novalidate => true` in the `$options` array of the `FormHelper::create()`. Thanks bassim for the extra info :) – Jelmer Feb 10 '13 at 20:36
  • 3
    Here a chrome extension to add this attribute: https://chrome.google.com/webstore/detail/html5-form-validation-err/dcpagcgkpeflhhampddilklcnjdjlmlb – Damien Apr 30 '13 at 10:56
  • Doesn't work in chrome. Input gets cleared for number. – mjs Sep 10 '17 at 14:05
36

I had a read of the spec and did some testing in Chrome, and if you catch the "invalid" event and return false that seems to allow form submission.

I am using jquery, with this HTML.

// suppress "invalid" events on URL inputs
$('input[type="url"]').bind('invalid', function() {
  alert('invalid');
  return false;
});

document.forms[0].onsubmit = function () {
  alert('form submitted');
};
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<form>
  <input type="url" value="http://" />
  <button type="submit">Submit</button>
</form>

I haven't tested this in any other browsers.

Dan Dascalescu
  • 143,271
  • 52
  • 317
  • 404
Ben Boyle
  • 1,686
  • 16
  • 13
27

I just wanted to add that using the novalidate attribute in your form will only prevent the browser from sending the form. The browser still evaluates the data and adds the :valid and :invalid pseudo classes.

I found this out because the valid and invalid pseudo classes are part of the HTML5 boilerplate stylesheet which I have been using. I just removed the entries in the CSS file that related to the pseudo classes. If anyone finds another solution please let me know.

BFTrick
  • 5,211
  • 6
  • 24
  • 28
19

The best solution is to use a text input and add the attribute inputmode="url" to provide the URL keyboard facilities. The HTML5 specification was thought for this purpose. If you keep type="url" you get the syntax validation which is not useful in every case (it is better to check if it returns a 404 error instead of the syntax which is quite permissive and is not of a great help).

You also have the possibility to override the default pattern with the attribute pattern="https?://.+" for example to be more permissive.

Putting the novalidate attribute to the form is not the right answer to the asked question because it removes validation for all the fields in the form and you may want to keep validation for email fields for example.

Using jQuery to disable validation is also a bad solution because it should absolutely work without JavaScript.

In my case, I put a select element with 2 options (http:// or https://) before the URL input because I just need websites (and no ftp:// or other things). This way I avoid typing this weird prefix (the biggest regret of Tim Berners-Lee and maybe the main source of URL syntax errors) and I use a simple text input with inputmode="url" with placeholders (without HTTP). I use jQuery and server side script to validate the real existence of the web site (no 404) and to remove the HTTP prefix if inserted (I avoid to use a pattern like pattern="^((?http).)*$" to prevent putting the prefix because I think it is better to be more permissive)

Peter O.
  • 32,158
  • 14
  • 82
  • 96
plancton
  • 324
  • 2
  • 5
14

Instead of trying to do an end run around the browser's validation, you could put the http:// in as placeholder text. This is from the very page you linked:

Placeholder Text

The first improvement HTML5 brings to web forms is the ability to set placeholder text in an input field. Placeholder text is displayed inside the input field as long as the field is empty and not focused. As soon as you click on (or tab to) the input field, the placeholder text disappears.

You’ve probably seen placeholder text before. For example, Mozilla Firefox 3.5 now includes placeholder text in the location bar that reads “Search Bookmarks and History”:

enter image description here

When you click on (or tab to) the location bar, the placeholder text disappears:

enter image description here

Ironically, Firefox 3.5 does not support adding placeholder text to your own web forms. C’est la vie.

Placeholder Support

IE  FIREFOX SAFARI  CHROME  OPERA   IPHONE  ANDROID
·   3.7+    4.0+    4.0+    ·       ·       ·

Here’s how you can include placeholder text in your own web forms:

<form>
  <input name="q" placeholder="Search Bookmarks and History">
  <input type="submit" value="Search">
</form>

Browsers that don’t support the placeholder attribute will simply ignore it. No harm, no foul. See whether your browser supports placeholder text.

It wouldn't be exactly the same since it wouldn't provide that "starting point" for the user, but it's halfway there at least.

Matt
  • 74,352
  • 26
  • 153
  • 180
John Kugelman
  • 349,597
  • 67
  • 533
  • 578
  • 5
    +1 for the tip, but it's not going to be a solution for me unfortunately. I still don't want any validation done, mainly because the UX for it is so poor. – nickf Jun 22 '10 at 05:40
12

I found a solution for Chrome with CSS this following selector without bypassing the native verification form which could be very useful.

form input::-webkit-validation-bubble-message, 
form select::-webkit-validation-bubble-message,
form textarea::-webkit-validation-bubble-message {
    display:none;
} 

By this way, you can also customise your message...

I got the solution on this page : http://trac.webkit.org/wiki/Styling%20Form%20Controls

Val Entin
  • 953
  • 10
  • 18
3

In JSX (JavaScript, React, Angular, Vue & ...) you need to add noValidate (camelCase with the uppercase V is necessary) to the form:

<form onSubmit={handleSubmit(data)} noValidate>

As Jakob S said, in pure HTML cases, add novalidate to form element:

<form method="post" action="/foo" novalidate>...</form>
TylerH
  • 20,799
  • 66
  • 75
  • 101
Ehsan Paknejad
  • 154
  • 1
  • 7
2

you can add some javascript to surpress those obnoxious validation bubbles and add your own validators.

document.addEventListener('invalid', (function(){
    return function(e) {
      //prevent the browser from showing default error bubble / hint
      e.preventDefault();
      // optionally fire off some custom validation handler
      // myValidation();
    };
})(), true);
blkpingu
  • 1,556
  • 1
  • 18
  • 41
0

Here is the function I use to prevent chrome and opera from showing the invalid input dialog even when using novalidate.

window.submittingForm = false;
$('input[novalidate]').bind('invalid', function(e) {
    if(!window.submittingForm){
        window.submittingForm = true;
        $(e.target.form).submit();
        setTimeout(function(){window.submittingForm = false;}, 100);
    }
    e.preventDefault();
    return false;
});
Tony Brix
  • 4,085
  • 7
  • 41
  • 53
0

If you mark a form element as required="" then novalidate="" does not help.

A way to circumvent the required validation is to disable the element.

cweiske
  • 30,033
  • 14
  • 133
  • 194
  • 1
    Please provide a short example. Your answer seems incomplete. – blkpingu Feb 02 '21 at 18:40
  • This was useful to me, as I have hidden elements that I would like to disable the validation of. Example of disabled here: https://jsfiddle.net/yzm4agdp/1/ – Joaquim d'Souza Jul 14 '21 at 13:40
  • 1
    Why would you mark a field as required if you never want to validate it? Just leave it not required. – TylerH Dec 29 '22 at 15:28