form.checkValidity checking that two password fields match - javascript

First post here so please be gentle. I'm trying to self learn how to write a responsive website for a local club. Is there any way of checking that two password fields are identical and error accordingly using the bootstrap 4 method of form validation? I can do it server side but since I am doing a fair amount of client side form validation, it would be nice if I could check that the passwords were the same before submitting the form.
<form class="container" id="form-validation" method="post" action="./register.php" novalidate>
<div class="row">
<div class="col-md-10 mb-3">
<label for="validation1">Username</label>
<input type="text" class="form-control" name="username" id="validation1" placeholder="Username" required pattern="^[_a-zA-Z0-9\-]{5,15}$">
<div class="invalid-feedback">
Must be alpha-numeric, dash or underscore, between 5 & 15 characters
</div>
</div>
</div>
<div class="row">
<div class="col-md-10 mb-3">
<label for="validation2">Password</label>
<input type="password" class="form-control" name="pwd1" id="validation2" placeholder="Password" required pattern="^[_a-zA-Z0-9\-]{5,15}$">
<div class="invalid-feedback">
Must be alpha-numeric, dash or underscore, between 5 & 15 characters
</div>
</div>
</div>
<div class="row">
<div class="col-md-10 mb-3">
<label for="validation3">Confirm Password</label>
<input type="password" class="form-control" name="pwd2" id="validation3" placeholder="Re-enter Password" required pattern="^[_a-zA-Z0-9\-]{5,15}$">
<div class="invalid-feedback">
Must be alpha-numeric, dash or underscore, between 5 & 15 characters and match original Password
</div>
</div>
</div>
<div class="row">
<div class="col-md-10 mb-3">
<button class="btn btn-success" type="submit" value="Send" name="registerbtn">Register</button>
</div>
</div>
</form>
(function() {
"use strict";
window.addEventListener("load", function() {
var form = document.getElementById("form-validation");
form.addEventListener("submit", function(event) {
if (form.checkValidity() == false) {
event.preventDefault();
event.stopPropagation();
}
form.classList.add("was-validated");
}, false);
}, false);
}());

Using this should work.
var form = document.getElementById("form-validation");
form.addEventListener("submit", function(event) {
if ( document.getElementById("validation2").value != document.getElementById("validation3").value ) {
alert("Password mismatch");
event.preventDefault();
event.stopPropagation();
}
else if (form.checkValidity() == false) {
event.preventDefault();
event.stopPropagation();
}
form.classList.add("was-validated");
}, false);

You can achieve this validation through the JavaScript constraint validation API, it's a customError, which you can set prior to form submission.
I'll provide the example for BootStrap4 and assume jQuery as an optional but common BootStrap dependency to abbreviate $("#pw1").val()
The HTML
<form>
<div class="form-group">
<label for="pw1">Password</label>
<input type="password" class="form-control"
id="pw1" placeholder="Password"
required minLength=8>
</div>
<div class="form-group">
<label for="pw2">Repeat Password</label>
<input type="password" class="form-control"
id="pw2" placeholder="Password" aria-describedby="pwHelp"
required minLength=6
oninput="validate_pw2(this)">
<small id="pwHelp" class="form-text text-muted">Please repeat your password</small>
</div>
<button type="submit" class="btn btn-primary">Register</button>
</form>
The Script
<script>
function validate_pw2(pw2) {
if (pw2.value !== $("#pw1").val()) {
pw2.setCustomValidity("Duplicate passwords do not match");
} else {
pw2.setCustomValidity(""); // is valid
}
}
</script>
The important parts are the oninput in #pw2, which attempts to validate every time the value its changed. Then the setCustomValidity call provides the user message displayed when invalid, the empty string is used when it is now valid.

You can put a check to verify the password values are the same and abort the submission if they're not.
var form = document.getElementById("form-validation");
form.addEventListener("submit", function(event) {
if ( document.getElementById("validation2").value != document.getElementById("validation3").value ) {
alert("Password mismatch");
event.preventDefault();
event.stopPropagation();
}
else if (form.checkValidity() == false) {
event.preventDefault();
event.stopPropagation();
}
form.classList.add("was-validated");
}, false);
You would just change the alert window to show error text to your user. Here is an example to see how it would look: https://jsfiddle.net/aq9Laaew/55184/
Another suggestion would be to use something like jQuery so that the syntax is less cumbersome to deal with. But that's up to you.

From your code checkValidity() will check only the validity of the form HTML5 constraint (required, format, pattern, min, max), but there is no constraint for verify password. In reality this is like comparing if the content of 2 fields is the same. Also if you want to cancel the form submission, you also needs to return false; at the end. Normally HTML5 will not submit a form that has validation errors.
In you case I will suggest make a validation while you are typing on the validation field, and disable the submit button until the passwords match.
document.getElementById('validation3').addEventListener('keyup',function(e){
if(this.value !== document.getElementById('validation2').value){
document.getElementById('validation4').disabled=true;
this.classList.replace('pass','nopass');
}else{
document.getElementById('validation4').disabled=false;
this.classList.replace('nopass','pass');
}
}
You will need to assign an id='validation4' to the submit button. To make visual changes you could create a CSS rules to handle this ('pass','nopass').

Related

Form validation with express

I have read that form validations on client-side is not enough to prevent any malicious actions from users. For that case i have read that is needed to validate the form on the server-side too. Since i am first time using express, can someone give me a clue for what i need to do?
I'm leaving here the html form and the js validation function. My form doesn't have the "action" and "methods" for test purposes. I know that the "action" leads to my validation page and the method is POST on this specific case.
Is it safer to create a module for the validation and then call it on the server.js? or can i code it inside of the server.js?
HTML
<div class="containerfrm" id="frmcntn">
<!--Form Creation with method POST, JavaScript input validations and php file validation-->
<form action="" method="" class="cntbox" id="formBoard" name="formOfBoard" onsubmit="validateIndexForm(event)">
<!--Close Button of the pop up-->
<div class="righttopicon" onclick="closeForm()">
<img src="images/square-x.png" alt="close icon">
</div>
<!--Form with the necessary inputs (Name of the Board, IP Address, Port and upload file). All the inputs are required-->
<div class="col-100">
<h3>Add new board:</h3>
</div>
<!--Input for the boards name with max length of 50 characters-->
<div class="col-75">
<label for="bname">Name of the Board: *</label><br>
<input type="text" id="boardname" name="boardname" placeholder="Ex: Board 1" maxlength="50">
</div>
<!--Input for the IP Address that can only accept IP's and with a max length of 15 characters-->
<div class="row">
<div class="col-75">
<label for="ipadd">IP Address: *</label><br>
<input type="text" name="ipadd" id="ipaddress" placeholder="Ex: 192.168.1.1" maxlength="15">
</div>
</div>
<!--Input for the Port that can only accept numbers with a max length of 4-->
<div class="row">
<div class="col-75">
<label for="portnum">Port: *</label><br>
<input type="text" name="portnum" id="portnum" placeholder="Ex: 8080" maxlength="4" minlength="2">
</div>
</div>
<!--Input for the upload of the boards image that can only accept .png files-->
<div class="row">
<div class="col-75">
<label for="imgadd">Upload image:</label><br>
<img src="images/file-upload.png" alt="Insert image" class="insrtimg" name="imageboard" id="insertimage">
<input type="file" id="myFile" name="filename" onchange="fileValidation(event)">
</div>
</div>
<!--'Save' and 'Discard' buttons -->
<div class="row">
<div class="col-80">
<div class="btnformcontainer">
<input type="submit" class="btnfrm btnconfrm" value="Save">
<div class="btnfrm btndel" onclick="discardValues()">Discard</div>
</div>
</div>
</div>
</form>
</div>
JS Validation
function validateIndexForm(event){
let x = document.getElementById("boardname").value;
let y = document.getElementById("ipaddress").value;
let z = document.getElementById("portnum").value;
let w = document.getElementById("myFile").value;
let ipformat = /^(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/;;
if(x == ""){
//prevent the form submit
event.preventDefault();
alert("Please insert the boards name");
return false;
}
if(!y.match(ipformat) && !y === "localhost"){
//prevent the form submit
event.preventDefault();
alert("Please insert a valid IP address");
return false;
}
if(z != isNaN() && !(z > 0)){
//prevent the form submit
event.preventDefault();
alert("Please insert the correct port");
return false;
}
if(w == ""){
event.preventDefault();
alert("Please insert a valid image");
return false;
}
return x, y, z, w;
}
The uploaded file is getting validated on other function successfully.
Whether you create a module for the validation and bring it in to your server file or code the logic directly into your server file, it does not affect security and produces the same behavior.
For securing your server-side form validation, I recommend a tool like express-validator in combination with a body-parser.
Check out this article for a hands-on approach to the above mentioned setup.
You can just do the same thing in the post request code on your server side.
Ex:
app.post('/register', (req, res) => {
let username = req.body.username;
let password = crypto.createHash('sha256').update(req.body.password).digest('base64');
let repassword = crypto.createHash('sha256').update(req.body.repassword).digest('base64');
if(password != repassword) return res.redirect('/login');
});
You can also do queries in your redirect like this:
res.redirect('/login/?e=4&t=l');
And parse them client side to display errors like passwords do not match.

add customized field for bootstrap validation modal

i'm using bootstrap's form validation to validate a form. i wan to add an extra field called discount code. this field should accept only specified codes. when the field is empty it should light green, when the code is right it should light green and when the code is wrong it should light red. how can i do that using the bootstrap form validation?
thats how my form almost looks like
<form class="needs-validation" novalidate>
<div class="form-group">
<div class="col-md-12">
<strong>Enter your name </strong>
<input type="text" name="name" id="name" class="form-control" value="" required minlength="3" />
<div class="invalid-feedback">
Name should be at least 3 characters
</div>
</div>
</div>
<div class="col-12">
<button class="btn btn-primary" type="submit">Submit form</button>
</div>
</form>
<script>
(function () {
'use strict'
// Fetch all the forms we want to apply custom Bootstrap validation styles to
var forms = document.querySelectorAll('.needs-validation')
// Loop over them and prevent submission
Array.prototype.slice.call(forms)
.forEach(function (form) {
form.addEventListener('submit', function (event) {
if (!form.checkValidity()) {
event.preventDefault()
event.stopPropagation()
}
form.classList.add('was-validated')
}, false)
})
})()
</script>

Adding functionality to submit button within validation form - Bootstrap 4

I know this is a simple fix but through multiple google searches, I can't seem to find the answer to my question. I'm using a validation form from bootstrap 4, and I'm just trying to add functionality to my button by simply linking it to a different page. I tried using the anchor tag,
i.e. Submit
which will work, but the obviously validation is bypassed.
so currently I have this button within a form:
<button class="btn btn-primary" type="submit" >Submit form</button>
</form>
with this java script:
<script>
// Example starter JavaScript for disabling form submissions if there are invalid fields
(function() {
'use strict';
window.addEventListener('load', function() {
// Fetch all the forms we want to apply custom Bootstrap validation styles to
var forms = document.getElementsByClassName('needs-validation');
// Loop over them and prevent submission
var validation = Array.prototype.filter.call(forms, function(form) {
form.addEventListener('submit', function(event) {
if (form.checkValidity() === false) {
event.preventDefault();
event.stopPropagation();
}
form.classList.add('was-validated');
}, false);
});
}, false);
})();
</script>
What needs to be added to the js to make the button functional?? Thank you for any assistance!!
Here's a simplified version, the code is heavily commented.
// wait for page to load then run the code inside
window.onload = () => {
// Select the form we want to validate
let form = document.querySelector('form');
// listen for submit event
form.onsubmit = (event) => {
// prevent the form from posting so the page won't refresh
event.preventDefault();
// debugging log statememnet (not needed)
console.log('Form submitted')
// checking for form validation
if (form.checkValidity() === false) {
// if we're inside this if statement, the form is invalid
// we add the boostrap class to handle styling
form.classList.add('was-validated');
// debugging log statememnet (not needed)
console.log('Form not valid')
} else {
// if we're inside this if statement, the form is valid and ready for further actions
// debugging log statememnet (not needed)
console.log('Form valid')
// redirect to the target page
location.href = "www.example.com"
}
}
};
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.1/css/bootstrap.min.css">
<form class="needs-validation" novalidate>
<div class="form-row">
<div class="col-3">
<label for="validationCustom01">First name</label>
<input type="text" class="form-control" id="validationCustom01" placeholder="First name" value="Mark" required>
<div class="valid-feedback">
Looks good!
</div>
</div>
<div class="col-3">
<label for="validationCustom02">Last name</label>
<input type="text" class="form-control" id="validationCustom02" placeholder="Last name" value="" required>
<div class="valid-feedback">
Looks good!
</div>
</div>
<div class="col-3">
<label for="validationCustomUsername">Username</label>
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text" id="inputGroupPrepend">#</span>
</div>
<input type="text" class="form-control" id="validationCustomUsername" placeholder="Username" aria-describedby="inputGroupPrepend" required>
<div class="invalid-feedback">
Please choose a username.
</div>
</div>
</div>
</div>
<button class="btn btn-primary" type="submit">Submit form</button>
</form>
If you're a beginner i suggest you stay away from libraries and just play with vanilla js/css build everything from scratch if you get stuck your research on every single line of code, Then and only then you can start messing with libraries and such.

Field with removed 'required' attribute keeps validating after submit

I have a form to submit several fields. Two of them are for changing a password.
These password fields aren't required to be filled out before submitting. However, if one of them isn't blank I add the required attribute to both fields when it's changed through jQuery. I remove the attributes when I empty one and the other is already empty too.
The thing it seems to work the most of the times with an exception:
I fill out password
password2 is blank
I submit the form
In this case the validation for password2 shows up, but if I want to remove everything and submit, I can't:
I remove password
I submit the form again
The validation for password2 shows up again. Even if the 'required' attributed is removed in the HTML source
This is the HTML code:
<form id="edicionPerfilForm" action="actor/edit.do" method="post">
<div class="row">
<div class="form-group col-md-4">
<div>
<label for="password">Password</label>
<input id="password" name="password" class="form-control" type="password" value="" oninvalid="this.setCustomValidity('Fill out this field')" oninput="this.setCustomValidity('')">
<br>
</div>
</div>
<div class="form-group col-md-4">
<div>
<label for="password2">Repeat password</label>
<input id="password2" name="password2" class="form-control" type="password" value="" oninvalid="this.setCustomValidity('Fill out this field')" oninput="this.setCustomValidity('')">
</div>
</div>
</div>
<button name="save" type="submit" class="btn btn-dark">Send</button>
</form>
And the jQuery code:
$('#password').change(function() {
if($(this).val() != ''){
$(this).attr('required', true);
$( '#password2' ).attr('required', true);
}else{
if($('#password2').val() == ''){
$(this).removeAttr('required');
$( '#password2' ).removeAttr('required');
}
}
});
$('#password2').change(function() {
if($(this).val() != ''){
$(this).attr('required', true);
$('#password').attr('required', true);
}else{
if($('#password').val() == ''){
$(this).removeAttr('required');
$('#password').removeAttr('required');
}
}
});
And it's an example in JSFiddle:
https://jsfiddle.net/jke3pgh0/
I will suggest you a different approach here...
First, you only need one handler for this, since the logic is the same for both inputs. You can use more than one selector... Ex: $('#password, #password2'). But I would use a class instead... Like $(".password"). It's up to you.
Second, I said the «logic is the same»... That is:
If one of the two inputs is not empty, both are required.
So having the same change event handler on both inputs mean you don't really know which one triggered the event. So I suggest to use an .each() loop here (to make sure you check all values)... and a boolean "flag" (true/false).
After that loop, use that "flag" to set the required attribute.
I used a CSS rule to make the result obvious in the snippet below.
$('#password, #password2').change(function(){
// Look up for the password inputs in that "row".
var pass_inputs = $(this).closest(".row").find("[type='password']");
// Flag to determine if at least one is not empty.
var not_empty = false;
// Loop throug the password inputs and change the flag.
pass_inputs.each(function(){
if($(this).val() != ''){
not_empty = true
}
});
// Use the flag as the boolean argument for the required attribute.
pass_inputs.attr('required', not_empty);
});
[required]{
border: 3px solid red;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<form id="edicionPerfilForm" action="actor/edit.do" method="post">
<div class="row">
<div class="form-group col-md-4">
<div>
<label for="password">Password</label>
<input id="password" name="password" class="form-control" type="password" value="" oninvalid="this.setCustomValidity('Fill out this field')" oninput="this.setCustomValidity('')">
<br>
</div>
</div>
<div class="form-group col-md-4">
<div>
<label for="password2">Repeat password</label>
<input id="password2" name="password2" class="form-control" type="password" value="" oninvalid="this.setCustomValidity('Fill out this field')" oninput="this.setCustomValidity('')">
</div>
</div>
</div>
<button name="save" type="submit" class="btn btn-dark">Send</button>
</form>

Unable to set cuctom html5 validation message

I am trying to use browser validation messaging. I am not able to define a custom message when 2 fields are NOT identical.
My situation is that i have to test when the field IS valid, so i used jquery on.blur to test, but for some reason, the message is empty.
Try entering 2 valid but different email addresses. The expected result is supposed to be "Test why not working" has a browser message.
Working jsFiddle of my situation
HTML:
<form id="newsletter_form" class="form" role="form" name="newsletter_form" method="post" action="/" autocomplete="off">
<div class="row">
<div class="col-xs-12 col-sm-6 col-md-6 col-lg-6">
<input type="email" class="form-control" name="email" id="email" value="" maxlength="250" placeholder="email" aria-required="true" required="required" />
</div>
<div class="col-xs-12 col-sm-6 col-md-6 col-lg-6">
<input type="email" class="form-control" name="confirm_email" id="confirm_email" value="" maxlength="250" placeholder="confirm email" aria-required="true" required="required" />
</div>
</div>
<input type="submit" class="btn submit btn-default" value="submmit!" />
</form>
JAVASCRIPT:
$('form #email').on('change invalid', function () {
var field = $(this).get(0);
field.setCustomValidity('');
if (!field.validity.valid) {
field.setCustomValidity("custom email invalid");
}
});
/* THIS IS MY BUGGY ONE */
$('form #confirm_email').on('blur valid', function () {
var field = $(this).get(0);
field.setCustomValidity('');
if ($("#email").val() != $("#confirm_email").val()) {
/* i tried setting the field to invalid, nothing */
//field.validity.invalid;
//alert('s');
field.setCustomValidity("test why not working");
}
});
$('form #confirm_email').on('change invalid', function () {
var field = $(this).get(0);
field.setCustomValidity('');
if (!field.validity.valid) {
field.setCustomValidity("custom error message");
}
});
I tried jquery.on(change valid .. and so on, i get the alert() bot not the changed text.
Any help will be appreciated, i am getting bored of this 'bug'?
but for some reason, the message is empty.
That is because you are explicitly setting it to be empty:
field.setCustomValidity('');
in your "custom error message" handler that is used to grump about the invalid email. That handler is executed after the 'blur valid', and will always reset what happened before. You can try it by uncommenting above line.
Any help will be appreciated
Check both reasons in the same handler:
$('form #confirm_email').on('change valid invalid', function () {
// var field = $(this).get(0); -- don't do this!!! field = this.
this.setCustomValidity('');
if (!this.validity.valid) {
this.setCustomValidity("custom message for standard errors");
} else if ($("#email").val() != this.value) {
this.setCustomValidity("test now working");
}
});
(updated demo)

Categories