bootstrap 3 validator - change password form - javascript

I have a bootstrap 3 form and I am using validator to validate forms.
I have succesfully implemented basic validations for sign-in forms and now I am implementing validation of change password form.
The form is as follows:
<form id="changepassword-form" role="form" data-toggle="validator" class="form-quote" action="/changepasswordpost" method="POST">
<input name="changepassword-id" type="hidden" value="{{ id }}"/>
<input name="changepassword-token" type="hidden" value="{{ token }}"/>
<div class="form-group row">
<div class="form-field col-md-12 form-m-bttm">
<input name="changepassword-password" type="password" placeholder="Nueva contraseña *" class="form-control required">
</div>
</div>
<div class="form-group row">
<div class="form-field col-md-12 form-m-bttm">
<input name="changepassword-password2" type="password" placeholder="Repita la nueva contraseña *" class="form-control required">
</div>
</div>
<button id="changepassword-submit" type="submit" class="btn btn-primary">Cambiar contraseña</button>
</form>
I see in the documentation that custom validation can be used so I have written the following validation intended to be used in the second password field:
custom: {
passwordmatch: function($el) {
var matchValue = $('#changepassworde-password').value()
if ($el.val() !== matchValue) {
return "Passwords do not match"
}
}
}
But I do not know where or how can I define this custom validation. I understand that once defined I should just apply data-passwordmatch='' to second password field.

You should use html attributes as it is mentioned in the validator
data-match="#inputToMatch" to ensure two fields match, e.g. password confirmations
Validation rules are specified on form inputs via the following standard HTML5 attributes:
type="email"
type="url"
type="number", with additional constraints via max, min and step attributes
pattern="Reg(ular )?Exp(ression)?" (for input types of text, search, tel, url or email)
required
As well as the following non-standard attributes:
data-match="#inputToMatch" to ensure two fields match, e.g. password confirmations
data-minlength="5" to enforce a minimum amount of characters
data-remote="/path/to/remote/validator" to make an AJAX request to determine if the field is valid or not. Be sure to give the input a name attribute, as the request will be sent to /path/to/remote/validator?<name>=<value>. The remote endpoint should return a 200 OK if the field is valid, and a 4xx otherwise. Here's a reference server implementation using Express.

Related

form.checkValidity checking that two password fields match

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').

Get default validation input email on old browsers

I'm trying to build a simple contact form for the newsletter subscription, the CF has just one input field (email) and the submit button. I used type="email" of HTML5 to check the the email and on the new browsers I get the default validation message:
This doesn't happen when I use older browsers obviously so I used the JS alert in case the user is using the old browsers, but this is not what I'd like.
I would like to get the same message (browser default) on all the browsers.
Here my code:
HTML
<div class="newsletter-wrap-flex margin-top-div">
<div class="newsletter-title">
<span>
NEWSLETTER
</span>
</div>
<div class="newsletter-form">
<form id="newsletter-cf" method="post" action="">
<input id="contact-email" type="email" placeholder="Your email" required/>
<input id="contact-send" class="submit" type="submit" value="Subscribe" />
</form>
<div id="message-sent">Congratulation! Your request has been sent.</div>
</div>
</div>
JS
function checkEmail(inputvalue) {
var pattern = /^([a-zA-Z0-9_.-])+#(([a-zA-Z0-9-])+.)+([a-zA-Z0-9]{2,4})+$/;
return pattern.test(inputvalue);
}
$('#newsletter-cf').submit(function () {
var email = document.getElementById("contact-email").value;
if (!checkEmail(email))
{
alert('Email address is invalid');
return false;
}
$("#newsletter-cf").slideUp("slow");
$("#message-sent").slideDown("slow");
return false;
});
I've read there could be some ways like Modernizr but I've never used them before so I don't really know how to start.
Any suggestions?

Pressing Enter doesn't work with AngularJS

I am having a problem with using 'enter button' on the keyboard with an angular js login form. I know this question is asked before but I believe that my problem is a bit different because I tried almost everything written on the stackoverflow questions.
So, I just want to be able to hit enter and submit the form with only using the enter key on keyboard.
Here is login html:
<!-- BEGIN LOGIN FORM -->
<form ng-submit="loginCtrl.login()" class="login-form">
<h3 class="form-title">Sign In</h3>
<div class="alert alert-danger display-hide">
<button class="close" data-close="alert"></button>
<span>
Enter any username and password. </span>
</div>
<div class="form-group">
<!--ie8, ie9 does not support html5 placeholder, so we just show field title for that-->
<label class="control-label visible-ie8 visible-ie9">Username</label>
<input class="form-control form-control-solid placeholder-no-fix" type="text" autocomplete="off" placeholder="Company/username"
ng-model="loginCtrl.username" name="username"/>
</div>
<div class="form-group">
<label class="control-label visible-ie8 visible-ie9">Password</label>
<input class="form-control form-control-solid placeholder-no-fix" type="password" autocomplete="off" placeholder="Password"
ng-model="loginCtrl.password" name="password"/>
</div>
<div class="form-actions">
<input type="submit" class="btn btn-success uppercase" value="Login">
</div>
</form>
<!-- END LOGIN FORM -->
and here is my login:
self.login = function() {
var result = self.username.split("/");
var account = result[0];
var userId = result[1];
UserService.login(userId, self.password,account).then(function(user) {
self.userAccount = user;
$state.go('home');
}, function(err) {
alert("Authentication failure: Please check your credentials. ")
});
I get user name as "companyName/Username" so it is like:
amazon/bigboby
I'm pretty sure your problem is caused by this <button> tag:
<button class="close" data-close="alert"></button>
The answer is found in the documentation:
You can use one of the following two ways to specify what javascript method should be called when a form is submitted:
ngSubmit directive on the form element
ngClick directive on the first button or input field of type submit (input[type=submit])
Note the comment about how it looks for an ng-click handler on the first button. When you are pressing ENTER to submit the form, Angular looks at the form and sees that button. It would execute the ng-click handler on that button (if it had one).
If you include the type attribute on the button, you can prevent that and let it find the actual submit button:
<button type="button" class="close" data-close="alert"></button>

AngularJS clientside validation: Changing validation requirements depending on other fields?

I want to validate my fields using AngularJS's own form validation. However, I only want to check some of the fields when other fields have data. E.g.
<form novalidate name="myForm" ng-submit="submitThisForm()">
<h1>Shipping address</h1>
<!-- These are the inputs -->
<input name="sAddress1" type="text" ng-model="sAddress1" required>
<input name="sAddress2" type="text" ng-model="sAddress2" required>
<input name="sAddress3" type="text" ng-model="sAddress3">
<!-- These are the errors -->
<div class="error" ng-show='(myForm.sAddress1.$invalid) && myForm.submitted'>Required</div>
<div class="error" ng-show='(myForm.sAddress2.$invalid) && myForm.submitted'>Required</div>
<h1>Billing address (if different)</h1>
<!-- These are the inputs -->
<input name="bAddress1" type="text" ng-model="bAddress1" required>
<input name="bAddress2" type="text" ng-model="bAddress2" required>
<input name="bAddress3" type="text" ng-model="bAddress3">
<!-- These are the errors -->
<div class="error" ng-show='(myForm.bAddress1.$invalid) && myForm.submitted'>Required</div>
<div class="error" ng-show='(myForm.address2.$invalid) && myForm.submitted'>Required</div>
</form>
Basically, the Billing address is optional, but once any part of it is filled in, bAdress1 and bAddress2 become Required. How do I achieve this?
(The variable myForm.submitted is set to false on page load, and then set to true when the form is submitted, so it only shows once validation has taken place.) I prefer vanilla JS answers, but I am using jQuery for this project, so that is also okay.
EDIT: Here's the answer with a pretty, formatted layout:
In the HTML file:
<input name="bAddress1" type="text" ng-model="bAddress1" ng-required="doWeNeedThis()"/>
<input name="bAddress2" type="text" ng-model="bAddress2" ng-required="doWeNeedThis()"/>
<input name="bAddress3" type="text" ng-model="bAddress3"/>
In the JS file:
$scope.doWeNeedThis = function() {
if((document.getElementsByName("bAddress1")[0].value != "")
|| (document.getElementsByName("bAddress2")[0].value != "")
|| (document.getElementsByName("bAddress3")[0].value != "")) {
return true;
} else {
return false;
}
};
Many thanks to Davin for the quick (and complete) answer.
ng-required will allow you to run an expression to determine whether the field is required or not.
<input name="bAddress1" type="text" ng-model="bAddress1" ng-required="doWeNeedThis()">
ng-required is documented with form.
So, in your example, you could implement doWeNeedThis() function in your controller and check the values of your model to determine if the input should be required or not.
Otherwise, in simple cases, you can just write the expression directly into the ng-required expression:
<input name="bAddress1" type="text" ng-model="bAddress1" ng-required="bAddress1 || bAddress2">

Jquery Validator does not seem to work

I am pretty sure I am missing something very obvious but I am trying to validate my one of the textbox with required condition and I am using Jquery validator for that. My code looks like below:
var validator = $("#ForgotPassword").validate({
rules: {
EmailAddress: { required: true }
},
messages: {
EmailAddress: {
required: "Email address is required."
}
}
});
My DOm is like something below:
<form id = "ForgotPassword" class="ui-helper-hidden" title="Forgot Password" action="" method="GET">
<p>Please enter the email address you registered with. We’ll send you an email with a password reset link.</p>
<div class="inputwrapper _100">
<label for="Email">Email</label>
<input type="text" id="EmailAddress" name="Email" data-bind ="value : ForgotPasswordEmailAddress"/>
<span id="EmailAddress_Error" class="ui-helper-hidden errorMessage" ></span>
</div>
</form>
But when I put a watch on my validator object on the run time, I do not see any error. Is is because I am looking at the wrong place or my binding are not right?
Try this please or paste rest of your validation code:
For validation plugin you need to have name - EmailAddress in this case:
Hope it help the cause :)
<form id = "ForgotPassword" class="ui-helper-hidden" title="Forgot Password" action="" method="GET">
<p>Please enter the email address you registered with. We’ll send you an email with a password reset link.</p>
<div class="inputwrapper _100">
<label for="Email">Email</label>
<input type="text" id="EmailAddress" name="EmailAddress" class="EmailAddress" data-bind ="value : ForgotPasswordEmailAddress"/>
<span id="EmailAddress_Error" class="ui-helper-hidden errorMessage" ></span>
</div>
</form>
I think the problem is with the name in rules and messages. You should be using Email as the rule and message not EmailAddress because thats the name attribute on the control

Categories