Pretty form validation - javascript

I am currently validating my forms using an alert system from jquery. Just with this following code:
function validateForm() {
var a = document.getElementById('inf_field_FirstName').value;
var b = document.getElementById('inf_field_Email').value;
if (a == null || a == "" || a == "First Name") {
alert("Please enter your First Name!");
return false;
}
var emailRegEx = /^[A-Z0-9._%+-]+#[A-Z0-9.-]+\.[A-Z]{2,4}$/i;
if (document.getElementById('inf_field_Email').value.search(emailRegEx) == -1) {
alert("Please enter a valid email address.");
return false;
}
}
However, I would like this to be a cooler looking validation rather than just having a popup telling a user to go back and complete the form again.
I stumbled across this form here: http://lewishowes.com/ at the 'start living the dream now' part. Whenever you don't type something in some text pops up in a box below the field telling you how you didn't fill out the form correctly.
How can a method like this be achieved?

In that particular example, there is actually no libraries or cool work done, he simply uses built in HTML5 validation methods. On the email field, for example, he does not do type="text" but instead type="email". That means that when the form tries to be submitted, the browser will automatically check to make sure it is valid. There are also more advanced, custom, methods, I believe, but using an email type on the input tag is the first step, and is often enough for simple cases. You also use required attribute to make a field required. And instead of leaving just First Name as the default value for the first name field, use the placeholder attribute. e.g:
<input type="text" id="inf_field_FirstName" placeholder="First Name" required>
<input type="email" id="inf_field_Email" placeholder="Email Address" required>
jsfiddle: http://jsfiddle.net/markasoftware/UdJ4Z/1/
Note that you will get an error when submitting the form because there is nothing on the server side to handle the form. However, you will be able to see the messages when you enter invalid text
Note that you should also use standard JavaScript or server-side validation, as this has limited browser support. If user input is going to do something on the server that could be abused, MAKE SURE you have server-side validation, or somebody will hack your website.

Related

Why are custom validation messages causing my HTML form elements to stay invalid?

I've implemented a custom validation message on my input for the pattern validation rule while leaving the default message for required as is. However, when I do so, once the input becomes invalid, it never becomes valid again, even though I am meeting the pattern criteria.
document.addEventListener("DOMContentLoaded", function () {
const txtUsername = document.getElementById("UserName");
txtUsername.oninvalid = function (e)
{
const input = e.target;
if (input.validity.patternMismatch)
{
input.setCustomValidity("Usernames cannot contain the # symbol");
}
}
})
<form onsubmit="event.preventDefault(); alert('Form submitted');" action="post">
<!--pattern regex prohibits use of the # symbol-->
<input id="UserName" type="text" pattern="^((?!#).)*$" required />
<button type="submit">Submit</button>
</form>
JSFiddle demo
When I remove my custom oninvalid event handler, this issue does not occur. What am I doing wrong?
One additional question, though not essential to me resolving this issue: why does Chrome's built in validation pop-up text animate in so slowly and choppy, almost as if there's some sort of performance bottleneck? My machine is powerful and has no issues with any other type of graphical processing.
First of all, per MDN:
It's vital to set the message to an empty string if there are no errors. As long as the error message is not empty, the form will not pass validation and will not be submitted.
This agrees with that the HTML standard says:
Suffering from a custom error
When a control's custom validity error message (as set by the element's setCustomValidity() method or ElementInternals's setValidity() method) is not the empty string.
An element satisfies its constraints if it is not suffering from any of the above validity states.
Your sample does not clear the custom error if the form field is determined to be valid. As such, once the field is determined invalid, it stays so for the remainder of the session.
Moreover, you modify custom error only after the field has already been determined invalid. This means the form will still not be submitted even if you clear the message in the same handler.
A better way to accomplish your goal would be to monitor the field in the change event handler for the field and set the custom message there:
document.getElementById('UserName').addEventListener('change', function (ev) {
const input = ev.target;
if (input.validity.patternMismatch) {
input.setCustomValidity("Usernames cannot contain the # symbol");
} else {
input.setCustomValidity("");
}
}, false);
<form onsubmit="event.preventDefault(); alert('Form submitted');" action="post">
<!--pattern regex prohibits use of the # symbol-->
<input id="UserName" type="text" pattern="^((?!#).)*$" required />
<button type="submit">Submit</button>
</form>

<textarea> has some text, after updating it in form, change is not reflecting while submitting the form

I wanted to construct a form, When it loads, it should have data which is currently stored in back end DB. At the same time user should be able to change content and submit form to update DB.
For this purpose I have used input and textarea elements. textarea is used to show email. But after update data, data of input elements changed but not for textarea
Here is code:
In HTML Form this is textarea, Where text is echoed via PHP
<textarea placeholder="EMAIL" class="form-control" rows="2" cols="6" id="email" style="resize:none;"><?php echo $retention_config['email'] ?></textarea>
In browser I updated the email content of this
After that before submitting data, I wished to validate that this field should not be empty, for this used JS
Here is JS code:
var email_text = $('#email').text().trim();
if(email_text == "") {
alert("Email is Mandatory");
}
But, I was not getting this alert, after deleting whole content of email, Then I checked the value of this using javascript.
console.log('#email').text();
I got the text which, i initially loaded via PHP, When I updated text in form it should be updated then, Please help, as I ran into this problem for first time. Please forgive me if there is any error in this post as I am learning to post in stack overflow, earlier only I got ready made help from this platform only.
This is an input so you need to get the value of it, as you are using jQuery you can use val(), like so:
var email_text = $('#email').val().trim();
if(email_text == "") {
alert("Email is Mandatory");
}
and your console log would be:
console.log($('#email').val());
You need to use val instead of text
var email_text = $('#email').val().trim();
if(email_text == "") {
alert("Email is Mandatory")
}

How to stop a browser storing password values

I am going through an old site adding autocomplete="off" onto passwords fields, ensuring they are hashed and so on to try and increase security.
However how can I stop passwords being stored if chosen by the user in the browser. As if someone left their computer unlocked they could easily get into an admin login due to the username and password being pre-filled even with autocomplete="off" on the input boxes.
I thought I could use JavaScript to check for the existence of a value in the password field (e.g when the browser fills it) and then remove it. But to check for a value you need to change the type of the input box to "text" and once you change it back to "password" the browser fills the boxes up again with values.
Is there anyway to stop this as I would have thought that this could be a security hole for those people who use the same passwords etc as you could just change the DOM element to text, view the value in plain text, then try on other sites the same value.
The code I was trying to use was this where
getEl = an old cross browser function for document.getElement
DOM = my own DOM on load function
function clearPSW()
{
var p=getEl('strPassword');
p.setAttribute("type","text");
console.log("value is " + p.value);
// if I exit here without changing back BOTH username and password fields
// remain blank - although the PSW field is now a text field.
//return;
if(p.value!="")
{
console.log("clear");
p = "";
}
// as soon as I do this the browser re-fills the input boxes!
p.setAttribute("type","password");
}
DOM(function(){
console.log("run DOM");
setTimeout(1000,clearPSW());
});
Is there any method at all or is down to the user to be clever and not store passwords in browsers etc? Obviously I am trying to handle these insecure people and force them to re-enter their password each time.
Thanks!
Browsers such as Chrome now ignore autocomplete=off.
It is really up to the user whether they store passwords. If they do they should really lock the desktop when not at the computer and not share their OS account with others.
You could argue that turning autocomplete off means that the user will either pick a really simple to guess password or they will write it on a post-it note and stick it to the keyboard.
Include a hidden password field before your "real" password field:
<input type="password" style="display:none"/>
<input type="text" name="username"/>
<input type="password" name="password"/>
This works!
My solution is:
Change type of that input inside HTML from type="password" to type="text"
Write script that changes type of that input from type="text" to type="password"
suppose that input has id="pwd". Then:
document.getElementById('pwd').setAttribute('type', 'password')
Make a delay for calling this function (because if you would not, most browsers would still insert their cached password. My browser stops doing that when delay is > 1400):
setTimeout(
() => document.getElementById('pwd').setAttribute('type' 'password')
, 1500)

Disabling form password autocompletion but not other fields

I know you can disable the autocomplete on a form by setting autocomplete="off" on the form itself.
The problem I have is, I want to prevent the browser from populating the password field but do not want to disable username or other fields.
The other thing to consider is legacy data. Using autocomplete="off" on the form (or even the field itself) does not prevent existing users with saved passwords from getting a free-pass. Or ones that use web inspector, change the value of autocomplete and submit, allowing themselves to save the password.
I know it is possible to change the password field name attribute to a random/new one on every visit. Regretfully, I am working with a java/spring back-end and I am being told this is NOT easily manageable without a huge refactor/override.
How would you architect this? How would you enforce that the field always starts empty? There is no consistent way for browsers to event notify you of pre-population by a password manager - some may fire an onChange, others may not.
I guess I can move fields around with javascript and build the real form on the fly and submit it but once again, this will have implications with spring security and validations etc. Any other ideas?
you can made a temp variable when onFocus is call to set a variable to true ( like userFocus )
and on the onChange attribut but a short code for reseting "value" to NULL if userFocus== false) kind of overkilling imo but migth work
EDIT
function reset()
{
if (document.getElementById("hidden").value!=" ")
{
document.getElementById("demo").value=" ";
}
else;
}
function getfocus()
{
document.getElementById("hidden").value=" ";
}
else;
}
<input type="password" id="pwd" onchange="reset()" onfocus="getfocus()"/>
<input type="hidden" id="hidden" value="not focus"/>
I had to find this solution for IE 11 (since it ignores the autocomplete attribute). It works fine in other browsers. Really more of a work around, but it works.
https://stackoverflow.com/a/20809203/1248536
I was recently faced with this problem, and with no simple solution since my fields can be prepopulated, I wanted to share an elegant hack I came up with by setting password type in the ready event.
Don't declare your input field as type password when creating it, but add a ready event listener to add it for you:
function createSecretTextInput(name,parent){
var createInput = document.createElement("input");
createInput.setAttribute('name', name);
createInput.setAttribute('class', 'secretText');
createInput.setAttribute('id', name+'SecretText');
createInput.setAttribute('value', 'test1234');
if(parent==null)
document.body.appendChild(createInput);
else
document.getElementById(parent).appendChild(createInput);
$(function(){
document.getElementById(name+'SecretText').setAttribute('type', 'password');
});
};
createSecretTextInput('name', null);
http://jsfiddle.net/N9F4L/

Javascript to prevent invalid user input

I have written a set of javascript functions that allow me to validate user input on a form. I only want to accept valid input, and impose the following behaviour:
When a user enters an invalid form, I display an alert and inform them that the value entered is incorrect. Crucially, the original (valid) value in the form is not changed.
The value is only changed when the value has been validated.
For example, suppose I want to accept only positive integers in a field.
This is the sequence of events that describes the desired behaviour.
Scenario 1 (valid input)
Form loads with valid default in the input field
User types in valid number
Input field value is updated (as per normal form behaviour)
Scenario 2 (INvalid input)
Form loads with valid default in the input field
User types in INvalid number
Alert box is shown alert('Invalid value')
Input field value is NOT CHANGED (i.e. the value is the same as BEFORE the user typed in the invalid number)
[Edit]
The only problem I am facing at the moment (i.e. what this question is seeking an answer for), is Scenario 2, action point 4. More specifically put, the question degenerates to the following question:
How do I stop the value of a field from changing, if I (somehow) determine that the value being entered by the user is invalid. This is really, all I'm trying to answer.
I am also doing server side checks, this question is just about the front end - i.e. refusing to change a field (form text input) value if I determine that the value is incorrect.
BTW, I am using jQuery, and would like to implement this in a manner that separates behaviour from display (I think this is what is meant by the term 'unobtrusive' ?)
Any suggestions on how to implement this behaviour as described above, would be very much appreciated.
PS: I dont want to use yet another jQuery plugin for this. I should be able to use jQuery + the simple javascript validation functions I have already written.
When loading the page, couldn't you create a hidden form value or js variable in which you store the initial/default value for the field? When they change the form field, validate it, and if it passes, update the hidden field or js variable to match that in the field they updated.
When the input given by the user fails validation, show the invalid entry along with the error message and then update the form field back to the value you have saved which would be either the
default value or the last valid value that they entered.
EDIT:
Note that this is only a quick and (very) dirty example of doing what I explained in my answer above. If you have a lot of inputs, you will probably want to store the values in an associative array instead of in hidden form values, but this should give you a good handle on what I am suggesting. I would also strongly encourage you to NOT use alert boxes for notification of invalid answers.
<html>
<head>
<script type="text/javascript">
function validate()
{
var field1 = document.getElementById("field1");
var saved = document.getElementById("field1_save");
if (field1.value < 0 || field1.value > 10)
{
alert("Field1 value of " + field1.value + " is invalid");
// Change the value back to the previous valid answer
field1.value = saved.value;
return false;
}
// Save the valid input
saved.value = field1.value;
return true;
}
</script>
</head>
<body>
Test User Input
<form name="form1" id="form1" method="post">
<input name="field1" id="field1" type="text" value="2" onblur="validate();"/>
<input name="field1_save" id="field1_save" type="hidden" value="2" />
<input name="btnSubmit" type="submit" value="Submit" />
</form>
</body>
</html>

Categories