HTML5 forms - semantic way of displaying errors from php validation - html

I'm building a html5 form. To validate it at first I use html5 validate mechanisms (patterns, required, etc...), and then PHP server side validation. I'm writting it as a library, so I can't predict all possible cases.
For example, I've got email input:
<input type="email" name="mail" placeholder="you#domain.com" />
Now I'm checking with php if the domain: domain.com exists (* - see footnote).
If no, PHP render the form once more but should display error near the input that has validation mistakes.
HOW TO DO THAT SEMANTICALY? What html element is good for it?
I will give some wrong examples to ilustrate my problem (I will write only important fragments of code) :
<label for="mail">Email:</label>
<input type="email" name="mail" id="mail" /> - given mail does not exist
Error without of html5 element. This is what I found to be most popular on websites, and most hopeless (stupid - no offense :) ) solution...
<label for="mail">Email (given mail does not exist):</label>
<input type="email" name="mail" id="mail" />
Is the error realy a label fragment? Or label is label, and error is not a fragment of label. In that case labels can be diferent (according to a given mail). Is this semantic?
<label for="mail">Email</label>
<input type="email" name="mail" id="mail" />
<span class="error">Given mail does not exist</span>
No idea solution. Span can be used here, but this is another no better idea solution.
Another ideas:
<details> - this isn't a detail...
<aside> - this isn't aside, this is important!
<mark>, <strong>, <emph> - with a given class?
Thanks for Your time and ideas. I know that even complicated error handling can be done using html5 validation methods, but there should be an object that is the best for showing such things in html5 semantic (for example for blind people - imagine the screen reader application, form filling by such a person by voice, and the first stupid solution usage. The screen reader should read whole page to hear just one error...)
Best regards
PS. If someone think, that there are better problems on earth (:D), yes of course there are. But we are those, who try to make the web more clean and available. And we really should take care about such details.
(*) which is not that easy in html5 You must use ajax, with php function, and override default Error handling mechanisms with Your own texts, and much much more...).

In order for an error message to be announced by assistive technology, it has to be associated with the field. When a screen reader arrives on a form, it triggers what's known as "forms mode" and at that point it will only read out that which is associated with the fields themselves.
<label for="mail">Email</label>
<input type="email" name="mail" id="mail" aria-describedby="email_error" />
<span class="error" id="email_error">Given mail does not exist</span>
In the above example, the use of aria-describedby allows you to create an explicit reference between the field and the error, which will ensure it is announced by screen readers.

semantics are debatable; that said, the "stupid, no offense" example is the most semantic approach, except its better practice to wrap the message in a span element.
don't let that semantically lacking span fool you: this approach is for addressing accessibility support.
semantics are being used properly here, as this markup is displaying the correct information, its just not an audience that most people realize exists.
Read more about this technique here: Simple inline error message pattern

Related

Chrome/Firefox autocomplete=new-password not working

I'm trying to add autocomplete=new-password to some user-editing forms, but it fails to follow the correct behavior in Chrome 79 and Firefox 71. It's supposed to be supported in both browsers.
What's wrong here?
I created two very simple examples to remove any external interference to the issue. They can be served from any HTTP server (e.g. php -S localhost:8999). The first page triggers the "save login" feature, but the second should NOT use that info to autocomplete the password - yet, it does.
<!-- login.htm -->
<html>
<head></head>
<body>
<form action="edit.htm" method="post">
<label>Login <input type="text" name="login" /></label></br>
<label>Password <input type="password" name="pwd" /></label><br />
<input type="submit">
</form>
</body>
</html>
<head></head>
<body>
<form>
<label>Login <input type="text" name="login" /></label></br>
<label>New Password <input type="password" name="pwd" autocomplete="new-password" /></label><br />
<input type="submit">
</form>
</body>
</html>
This is not exactly a dup from "how to use autocomplete=new-password" as the behavior seems to have changed or is ill-documented.
This seems to be an issue/advantage that browsers force pages to behave this way, and absolutely this is not fixed when setting autocomplete="new-password" or even if you set the value to off. but there seems to be a workaround to fix this issue caused accidentally by the browser.
- HTML way:
You can fix this by adding hidden fields at the top of your form to distract the browser
<!-- fake fields are a workaround for chrome/opera autofill getting the wrong fields -->
<input id="username" style="display:none" type="text" name="fakeusernameremembered">
<input id="password" style="display:none" type="password" name="fakepasswordremembered">
- JS way:
you can just set the password input to readonly the change its state
<html>
<head></head>
<body>
<form>
<label>Login <input type="text" name="login"/></label></br>
<label>New Password <input type="password" id="password" name="pwd" readonly autocomplete="new-password"/></label><br/>
<input type="submit">
</form>
<script>
document.getElementById('password').onfocus = function() {
document.getElementById('password').removeAttribute('readonly');
};
</script>
</html>
As you didn't reply to my comments I suppose that my assumption was correct. So I'll post the comments as the answer:
I don't have Chrome 79 and Firefox 71. I've tested it on Chrome 85 and FF 80 on Ubuntu.
It works as intended.
I assume that by
should NOT use that info to autocomplete the password - yet, it does.
you mean that:
When the password field gets focus browsers show a drop-down list with an option to fill in the field with previously stored password.
This looks to you as
[browsers] should NOT use that info to autocomplete the password.
[...] the behavior seems to have changed or is ill-documented.
But actually this is exactly the intended behavior.
From this (the previous paragraph on the same page you've linked) you can see the reason:
Even without a master password, in-browser password management is generally seen as a net gain for security. Since users do not have to remember passwords that the browser stores for them, they are able to choose stronger passwords than they would otherwise.
For this reason, many modern browsers do not support autocomplete="off" for login fields
If a site sets autocomplete="off" for username and password fields, then the browser still offers to remember this login, and if the user agrees, the browser will autofill those fields the next time the user visits the page.
Of course, it's about autocomplete="off" not about autocomplete="new-password"
Let's read further
If you are defining a user management page where a user can specify a new password for another person, and therefore you want to prevent autofilling of password fields, you can use autocomplete="new-password".
This is a hint, which browsers are not required to comply with. However modern browsers have stopped autofilling <input> elements with autocomplete="new-password" for this very reason.
From this:
autofilling is not the same thing as suggestions
browser CAN, but not SHOULD prevent autofilling
autocomplete="new-password" prevents autofilling not suggestions
So when you set autocomplete="new-password" browsers stop filling these fields but continue to show drop-downs with suggestions.
There is nothing about autocomplete="new-password" stopping suggestions, and there is a clear reason why suggestions are always available.
Yes, maybe the wording is a little bit confusing, but follows the behavior to the word.
About the history and use-cases behind this feature you can read here
And now about use-cases... why do you need this?
If several users have access to the computer, disabling suggestions won't stop them from logging in to a site as a different user. They can see passwords in the settings and use them. To prevent this, users must have different accounts on the computer.
If you don't want them to use old password in place of a new-password, then, yes, it will complicate things a little (which is actually bad - when things are complicated users tend to use poor passwords), but won't stop them from remembering the old password or, again, from getting it from the settings. For that you need to check if the password is really new in your code.
If you want to prevent suggestions anyway, then you can use hacks from #Moayad.AlMoghrabi's answer (I haven't tested them, but I believe he did). But without knowing your use case, I would strongly recommend against it. It breaks user experience and does not boost security. On the contrary, lessens it.
I know what your talking about, and in your case you should leave it. Security is a major issue, obviously, and the answers above are absolutely correct. There are work-arounds though, like using read-only which has been mentioned, I would try to achieve your goal using read-only, however; read-only does not always give disired results. A less favorable, and I feel like someone is going to lecture me hard for answering with this, but I feel as a developer, you need all the information, what you do with that information is your decision.
PSEUDO ELEMENTS
Googles chrome and Safari, imho, are the most annoying when it comes to auto-fill. To get around this, one option is to create HTML pseudo elements for the pwd and login inputs. Hide them using CSS display property set to none. Since google will only auto-fill one password-input element, and one username text-input element, this work around tricks Google into auto-filling elements that are not displayed.
The Problem With This Method
The problem with this method is that you need to make sure that you validate the data on the backend, and even more so, you need to make-sure your using the right elements to pull data from for your database. The worst problem is that as things update this work-around will guaranteed, at some-point, either stop working and the elements will one-day show without you knowing, making not developers using your site very confused, or confuse the browser in ways we cannot predict because the changes have not come. Its somthing you always have to be aware of. I use to use this method alot, but I stopped because people who know a lot more than I do, really did not like me doing it.
End Note:
Every browser is programed to present forms differently. Some browsers, especially mobile versions and safari actually change the physical look of your elements, which IMO is uncalled for. At the same time though they do this to try and deliver web standards to boost security and make things easier to use for people like my non tech-savvy 85 year-old Grandma. As noted, browser do things differently, and people can choose different browsers, selecting the one they want. Auto-fill is part of the experience that users get from a browser, and is a major deciding factor on which browser people choose. If you use work around, like the one I explained you change that browser experience, and give the user what you want, but it might not be what they want.
If you do decide to use, or at-least try this method, please let me know how it goes, its a pretty easy hack/work-around, and I have got pretty good at tricking browsers and can help you if my example doesn't work for you. Let me know what backend your using and browsers your experimenting with and I will get you working code, but first think about what you really want. Sometimes we have to settle, especially if it is in the best interest of the clients experience using the sites/apps we build, or to improve the security of, not just the client but, our servers and our self.
body{
width: 100vw;
padding: 0;
margin: 0;
background-color: #ddb;
overflow-x: hidden;
}
#login-psuedo{
display: none;
}
#pwd-psuedo{
display: none;
}
<html>
<head>
<style></style>
</head>
<body>
<form>
<input id="login-psuedo" type="text" name="login-psuedo"/>
<input id="pwd-psuedo" type="password" name="pwd-psuedo" autocomplete="new-password"/>
<br />
<label>Login <input type="text" name="login"/></label></br>
<label>New Password <input type="password" name="pwd" autocomplete="new-password"/></label>
<br>
<br>
<input type="submit" value="Submit">
</form>
</html>
I know quite an old question.
But adding autocomplete="off" in the form tag might help (I know not in all cases - as some fields might require autocomplete fills - Specially when you are testing)
works for firefox now* (*98.0.2 (64-bit))

is form enctype "application/json" available?

I was reading this w3c document about post JSON data with html form, and trying to test it.
my test form is as follows:
<form action="postjson.php" method="POST" enctype="application/json">
<input type="hidden" name="touser" value="shenkwen" />
<input type="hidden" name="msgtype" value="text" />
<input type="hidden" name="agentid" value="23" />
<input type="hidden" name="text[content]" value="test message" />
<input type='submit' value="submit" />
</form>
and content for postjson.php
<?php var_dump($_POST);
I was expecting the value of $_POST being a JSON string, however, it is just a normal PHP object:
array(4) { ["touser"]=> string(8) "shenkwen" ["msgtype"]=> string(4) "text" ["agentid"]=> string(2) "23" ["text"]=> array(1) { ["content"]=> string(33) "test message" } }
I tried removing the enctype attribute and the output is exactly the same. Then I went back to the document page and noticed that it says something indicating this standard may not be in effect.
So this is also a question about how to use W3C website, it seems to me some pages on it are just drafts. So is this page a draft? When I read pages on w3c how do I tell whether it is a draft or it is a working standard? And finally and most importantly, is enctype='application/json' working or not?
The W3C publishes many drafts and proposals which are then discussed within the community at large. If a draft makes it to the stage where it's generally considered useful, browser vendors will/may start implementing it. The draft then typically advances to a "recommendation" stage, meaning the W3C officially recommends that browsers implement the technology as specified; but of course they can't twist anyone's arm to actually do so.
Each document will say at its top what its current status is, and http://www.w3.org/TR/ lists all current documents and their status. The one you picked is listed as "obsolete" and "retired" on that page and has a ginormous banner at its top saying:
Beware. This specification is no longer in active maintenance and the HTML Working Group does not intend to maintain it further.
So, no, probably no browser is currently implementing it.
To track the real-world availability of a feature you need to look to 3rd party resources like https://developer.mozilla.org/en-US/docs/Web/HTML/Element/form#attr-enctype and http://caniuse.com.
FYI.. there's a hacky way to mimic this functionality using javascript. Seem my library here: https://github.com/keithhackbarth/submitAsJSON

Is there a way to give HTML inputs some sort of namespace to avoid collisions?

<!-- Some place on the webpage -->
<input type="text" id="firstName">
<!-- Some other place on the same webpage, or maybe content ajaxed in later -->
<input type="text" id="firstName">
Let's say I have a server-side script that generates an HTML page with some input fields each with its own ID. One server-side class may be responsible for adding input fields to one part of the webpage while another class handles another part of the webpage. Or you might have different programmers working on different parts of the page. I want to avoid collision with the HTML input field IDs. An example of this could be a parent form that has a jQuery dialog popup with input field IDs the same as the parent. Currently, I am prefixing the IDs with the name of the server-side class that generates them (and an underscore to make it clear which part is the prefix). To get a fully unique ID this way, I might have to start including the full namespace of the server-side class, and this might make my IDs very long.
Is there a better approach than prefixing the inputs or what is the best practice for this? I normally use camelCase for all my variables, with only this exception. Is this a good exception for breaking that rule?
What are most of you doing? Are you altering the way you select these input fields instead of by ID? Wrapping the input fields in form tags or div tags and adding functionality to the server-side to create these? (I'd like to have the freedom of not restricting what I wrap these inputs in to select them. My server-side code should just generate client-side code that grabs the values only knowing those inputs are going onto the page, and not knowing about any other tags on the page. Much easier to manage.) Are you adding css classes to each group of fields?
This answer is a little more directed towards users coming in from search engines. In my opinion, if you are using the id attribute in a dynamically generated form, they should probably be some kind of generated id/hash, unless it truly is a unique field. That aside, this is probably the best way to namespace HTML forms, especially when it is subject to collision:
<input name="pet_store[name]" value="" />
<input name="dogs[0][name]" value="" />
<input name="dogs[1][name]" value="" />
<input name="dogs[2][name]" value="" />
<input name="cats[0][name]" value="" />
<input name="cats[1][name]" value="" />
<input name="cats[2][name]" value="" />
If submitted all at once, the inputs will automatically be organized into arrays (at least in PHP, for nodejs you might have success with https://www.npmjs.com/package/qs).
In jQuery, you can select all dog name fields like this:
$('input[name$="[name]"][name^=dogs]')
I would use classes in this case. If you can't control what the uniqueness of ID's then they become pretty meaningless.
Instead of generating a super-long class name from the code that generates the html, you could add many shorter css classes to inputs that need them. It's not unusual to have lots of different classes in your document and they can all be used together with jQuery selectors. Also remember that if your inputs are in different forms then the form id (or class) could also be considered to work a bit like a 'namespace' too.
For reference, point 7.5.2 of the W3C Global Structure of an HTML document states that the id must be unique.
The idea of ids is that they are a unique reference to an element and as such it is not legal (valid HTML) to have multiple elements referring to the same id. If you want to avoid collisions and still identify the element you could use a combination of classes.
For example if you have 2 forms asking for a name (as in your previous comment) you could use:
<input type="text" class="ajax firstName" />
For the form generated by ajax, and
<input type="text" class="initial-form firstName" />
For the initial form on the webpage.
Equally you could use the data- attribute to hold a namespace. E.g:
<input type="text" data-namespace="ajax" class="firstName" />
(This can be accessed through Javascript with element.dataset["namespace"])
Use data-xxx attributes if you must, but I can't really think of a practical case of independent server-side scripts generating hundreds of DOM elements with unique IDs up to the point where name collision would become an issue.

HTML5 Validation - Easy Way to have real time validation?

I am using HTML5 for user validation. Here is a snippet of my code:
<input type="text" name="name" id="usernametb" title="Minimum 8 Characters, only letters
and numbers" pattern="^[A-Za-z0-9]{8,40}$" placeholder="Enter a Valid UserName" required />
I would like for user to get an error message either as soon as they type a username that doesnt match the validation pattern or when they tab to next field. Is there an easy way to do this with HTML5.
Right now, the error message doesn't display until I click "submit" and force a postback.
I have had good experiences with the parsley.js library:
http://parsleyjs.org/
Also for other input types (eg phone, email, URL) html5 can validate by itself, won't fix the example you have but it is very powerful and an insanely lightweight tool when it fits.
eg:
<input type="tel" name="cellPhone"></input>
Good luck!
This is a html5 validation plugin for jquery: http://ericleads.com/h5validate/ .
Quote from the plugin site:
Best practice realtime HTML5 form validation for jQuery. Works on all popular browsers, including old ones like IE6.
If you want to use your own javascript, use something like:
onkeyup="validateUsername(this)"
…so for example:
<input type="text" name="name" id="usernametb" title="Minimum 8 Characters, only letters and numbers" pattern="^[A-Za-z0-9]{8,40}$" placeholder="Enter a Valid UserName" onkeyup="validateUsername(this)" required />
Happy coding!

HTML - Will browsers autofill hidden fields?

My site suffers from a lot of spam bots. If I have the login form:
<input name="username" type="hidden" />
<input name="password" type="hidden" />
<input name="hidden_1" type="text" />
<input name="hidden_2" type="password" />
So the user actually see's the 'hidden' prefix fields, and the username/password named fields are actually the hidden ones. If the username or password field is submitted with values, we know bot filled them out and can ban them.
My question is, do browsers auto fill hidden fields? Is this quite a good technique? I know this isn't going to stop all bots that are semi intelligent, but if this even blocks 1 bot, without affecting any genuine users it's worth doing.
I think that not all bots just search for "username" and "password" names, but also type="password". So this might not avoid bot access at all.
You can use a capture like ReCAPTCHA. It is free and easy to use. Additionally you can create a banlist and show a 404 to bots via htaccess.
This article might help you:
http://www.smashingmagazine.com/2011/03/04/in-search-of-the-perfect-captcha/
Your method is actually fairly decent, but you may still suffer from some spam, especially if forms are manually filled out