Unable to set cuctom html5 validation message - javascript

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)

Related

Unable to store form data into session storage

I just started to learn JavaScript and I was trying to let user input form data and store them into session storage but I can't seem to do so. Please shed some light on this, thank you.
JavaScript
$(function() {
$("formset").submit(function (event) {
event.preventDefault();
var name = $("#fullname").val();
var email = $("#email").val();
var phonenumber = $("#phonenumber").val();
var message = $("#message").val();
if (typeof (Storage) !== "undefined") {
sessionStorage.setItem("Fullname", name);
sessionStorage.setItem("E-mail", email);
sessionStorage.setItem("Phoneno", phonenumber);
sessionStorage.setItem("Msg", message);
}
});
});
HTML
<form id="formset" class="main_form">
<div class="row">
<div class="col-md-12 ">
<input class="contactus" placeholder="Full Name" type="text" id="fullname" required>
</div>
<div class="col-md-7">
<input class="contactus" placeholder="Email" type="tel" id="email" required>
</div>
<div class="col-md-7">
<input class="contactus" placeholder="Phone Number" type="text" id="phonenumber" required>
</div>
<div class="col-md-12">
<textarea class="contactus1" placeholder="Message" type="text" id="message" required></textarea>
</div>
<div class="col-md-12">
<button class="send_btn" type="submit" id="submitform">Send</button>
</div>
</div>
</form>
Alright, you made a very small typo in your form ID attribute that you try to call from Javascript.
If $ is not undefined in your browser inspector, you should be able to select the form by $('#formset') instead of $('formset'). Let me know if that worked. I got it working on my machine with that adjustment :-)
Another good practice to learn Javascript is to write
console.log("Script entered this <FUNCTION_NAME>");
So I solved your problem in three seconds by doing this:
$(function() {
console.log("Script finished jQuery initialization.")
$("formset").submit(function (event) {
console.log("Script entered submit event.");
event.preventDefault();
var name = $("#fullname").val();
var email = $("#email").val();
var phonenumber = $("#phonenumber").val();
var message = $("#message").val();
if (typeof (Storage) !== "undefined") {
sessionStorage.setItem("Fullname", name);
sessionStorage.setItem("E-mail", email);
sessionStorage.setItem("Phoneno", phonenumber);
sessionStorage.setItem("Msg", message);
}
});
});
With the option 'Preserve Log' on in your inspector, you see the actual submit message in the console. Else you would be redirected after the form sumbit action and your console gets cleared.
And that's how I easily discovered the mistake. I never got the "Script entered submit event." message.

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

html form still showing validation errors even after entering right values with javascript

I have a contact form including validations. Everything is working very well but I have only one issue. An old shown error is not going away when submitting the form another time.
Here is the part of the document I have with the javascript:
<form id="contactForm" th:action="#{/contact}" th:method="POST" entype="utf8" >
<label class="form-control-label on-fonts-style display-7" >Name</label>
<input type="text" value="" class="form-control" placeholder="full name" name="fullName" required="required" >
<label class="form-control-label on-fonts-style display-7" >Email</label>
<input type="email" class="form-control" placeholder="Email Address"
name="email" value="" required="required">
<span id="emailError" style="color:#F41F0E"></span>
<label class="form-control-label on-fonts-style display-7" >Phone</label>
<input type="tel" class="form-control" name="phone" placeholder="phone"
value="">
<label class="form-control-label on-fonts-style display-7" >Message</label>
<textarea type="text" class="form-control" name="message" rows="7">
</textarea>
<span id="messageError" style="color:#F41F0E"></span>
<span id="globalError" class="alert alert-danger col-sm-4"
style="display:none" ></span>
<button type="submit" name="submit" class="btn btn-primary btn-form display-
4">SEND FORM</button>
</form>
<script
src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.2/jquery.min.js"></script>
<script th:inline="javascript">
var serverContext = [[#{/}]];
$(document).ready(function () {
$('form').submit(function(event) {
registerContact(event);
});
});
function registerContact(event){
event.preventDefault();
$(".alert").html("").hide();
$(".error-list").html("");
var formData= $('form').serialize();
$.post(serverContext + "contact",formData ,function(data){
if(data.message == "success"){
window.location.href = serverContext + "successContact.html";
}
})
.fail(function(data) {
if(data.responseJSON.error.indexOf("MailError") > -1)
{
window.location.href = serverContext + "emailError.html";
}
else if(data.responseJSON.error.indexOf("InternalError") > -1){
window.location.href = serverContext + "login?message=" + data.responseJSON.message;
}
else{
var errors = $.parseJSON(data.responseJSON.message);
$.each( errors, function( index,item ){
$("#"+item.field+"Error").show().html(item.defaultMessage);
});
errors = $.parseJSON(data.responseJSON.error);
$.each( errors, function( index,item ){
$("#globalError").show().append(item.defaultMessage+"<br/>");
});
}
});
}
</script>
Let me explain: I have two validations (on message and email), so if I typed them wrong the two errors show up. However if I fixed one of them and submit again the old error is still there. Even if I fix them both and submit the form, the form will be submitted but with still showing the errors.
Please anyone have a solution for this problem?
Add a class for all the error spans called error as an example.
when you get to the error checking part you can first hide all errors
$(".error").hide()
and then carry on with the validation as normal :)

How to Validate an Email Submission Form When There Are Multiple on the Same Page Using the Same Class?

I have three email forms on one page, all using the same class. When someone enters an email address and submits one of those forms, I want to validate the email address entered into that specific form. The problem that I'm having if is someone enters an email address for one of the later forms, it validates against the data in the first form. How can I make it so my validation function validates for the field into which the email address was entered without having to give each form a unique ID and have the validation code multiple times?
The validation code is below and code for one of the forms. Thanks!
<script>
function validateMyForm() {
var sEmail = $('.one-field-pardot-form-handler').val();
if ($.trim(sEmail).length == 0) {
event.preventDefault();
alert('Please enter valid email address.');
return false;
}
if (validateEmail(sEmail)) {
}
else {
event.preventDefault();
alert('Invalid Email Address. Please try again.'); }
};
function validateEmail(sEmail) {
var filter = /^([\w-\.]+)#((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.)|(([\w-]+\.)+))([a-zA-Z]{2,4}|[0-9]{1,3})(\]?)$/;
if (filter.test(sEmail)) {
return true;
}
else {
return false;
}
}
</script>
<form action="https://go.pardot.com/l/43312/2017-10-24/7dnr3n" method="post" onSubmit="return validateMyForm();" novalidate>
<input class="one-field-pardot-form-handler" maxlength="80" name="email" size="20" type="email" placeholder="Enter Email Address" required="required" />
<div style="position:absolute; left:-9999px; top: -9999px;">
<label for="pardot_extra_field">Comments</label>
<input type="text" id="pardot_extra_field" name="pardot_extra_field">
</div>
<button type="submit" name="submit">Submit</button>
</form>
Rather than calling the method from the html onsubmit attribute, wire the whole thing up in jquery.
$('form.myform').submit(function(e){
var $theForm = $(this);
var $theEmailInput = $theForm.find('.one-field-pardot-form-handler');
validateEmail($theEmailInput.val());
});
If you have 3 forms, just target the email field (via the class) within the context of the form.
And, don't use inline HTML event attributes (onsubmit, etc.), there are many reasons why and you can read about those here.
Instead, do all your event binding with JavaScript/JQuery and then you won't need to worry about return false to cancel the event if you are already using .preventDefault(). Additionally, it's best to capture the event reference as an argument to the event callback function, instead of the global event object.
There were other items that should be adjusted as well, so see additional comments inline:
// Get all the form elements and set up their event handlers in JavaScript, not HTML
$("form").on("submit", validateMyForm);
function validateMyForm(evt) {
// First, get the form that is being filled out
var frm = evt.target;
evt.preventDefault();
// Now, just supply the form reference as context for the email search
// Notice the extra argument after the selector "frm"? That tells JQuery
// where within the DOM tree to search for the element.
var sEmail = $('.one-field-pardot-form-handler', frm).val();
// Just to show that we've got the right field:
$('.one-field-pardot-form-handler', frm).css("background-color", "yellow");
// ***************************************************************************
// No need to convert a string to a JQuery object and call .trim() on it
// when native JavaScript has a .trim() string method:
if (sEmail.trim().length == 0) {
evt.preventDefault();
alert('Please enter valid email address.');
}
// Don't have empty branches, reverse the logic to avoid that
if (!validateEmail(sEmail)) {
evt.preventDefault();
alert('Invalid Email Address. Please try again.');
}
}
function validateEmail(sEmail) {
var filter = /^([\w-\.]+)#((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.)|(([\w-]+\.)+))([a-zA-Z]{2,4}|[0-9]{1,3})(\]?)$/;
return filter.test(sEmail);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<form action="https://go.pardot.com/l/43312/2017-10-24/7dnr3n"
method="post"
novalidate>
<input class="one-field-pardot-form-handler"
maxlength="80"
name="email"
size="20"
type="email"
placeholder="Enter Email Address"
required>
<div style="position:absolute; left:-9999px; top: -9999px;">
<label for="pardot_extra_field">Comments</label>
<input type="text" id="pardot_extra_field" name="pardot_extra_field">
</div>
<button type="submit" name="submit">Submit</button>
</form>
<form action="https://go.pardot.com/l/43312/2017-10-24/7dnr3n"
method="post"
novalidate>
<input class="one-field-pardot-form-handler"
maxlength="80"
name="email"
size="20"
type="email"
placeholder="Enter Email Address"
required>
<div style="position:absolute; left:-9999px; top: -9999px;">
<label for="pardot_extra_field">Comments</label>
<input type="text" id="pardot_extra_field" name="pardot_extra_field">
</div>
<button type="submit" name="submit">Submit</button>
</form>
<form action="https://go.pardot.com/l/43312/2017-10-24/7dnr3n"
method="post"
novalidate>
<input class="one-field-pardot-form-handler"
maxlength="80"
name="email"
size="20"
type="email"
placeholder="Enter Email Address"
required>
<div style="position:absolute; left:-9999px; top: -9999px;">
<label for="pardot_extra_field">Comments</label>
<input type="text" id="pardot_extra_field" name="pardot_extra_field">
</div>
<button type="submit" name="submit">Submit</button>
</form>
So a combination of #paul and #ScottMarcus' answers above ultimately got me to where I needed to go. Below is what I ended up with and it works as intended. As others have pointed out, I'm definitely a n00b and just learning javascript so certainly may not be perfect:
<script>
$('form.pardot-email-form-handler').submit(function(event) {
var theForm = $(this);
var theEmailInput = theForm.find('.one-field-pardot-form-handler');
var theEmailValue = theEmailInput.val();
function validateEmail(theEmailValue) {
var filter = /^([\w-\.]+)#((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.)|(([\w-]+\.)+))([a-zA-Z]{2,4}|[0-9]{1,3})(\]?)$/;
if (filter.test(theEmailValue)) {
return true;
} else {
return false;
}
}
if (!validateEmail(theEmailValue)) {
event.preventDefault();
alert('Invalid Email Address. Please try again.');
} else {
return true;
}
});
</script>
<div class="nav-email-form">
<form action="https://go.pardot.com/l/43312/2017-10-24/7dnr3n" method="post" class="pardot-email-form-handler" novalidate>
<input class="one-field-pardot-form-handler" maxlength="80" name="email" size="20" type="email" placeholder="Enter Email Address" required="required" />
<div style="position:absolute; left:-9999px; top: -9999px;">
<label for="pardot_extra_field">Comments</label>
<input type="text" id="pardot_extra_field" name="pardot_extra_field">
</div>
<button type="submit" name="submit">Submit</button>
</form>
</div>

How do I show/hide a div on field validation with parsley.js

So I guess for context, here is an example from the parsley.js documentation.
<form id="demo-form" data-parsley-validate>
<div class="first">
<label for="firstname">Firstname:</label>
<input type="text" name="firstname" data-parsley-range="[4, 20]" data-parsley-group="block1" />
<label for="lastname">Lastname:</label>
<input type="text" name="lastname" data-parsley-range="[4, 20]" data-parsley-group="block1" />
</div>
<hr></hr>
<div class="second">
<label for="fullname">Fullname:</label>
<input type="text" name="fullname" data-parsley-range="[8, 40]" data-parsley-group="block2" />
</div>
<div class="invalid-form-error-message"></div>
<input type="submit" class="btn btn-default validate" />
</form>
<script type="text/javascript">
$(document).ready(function () {
$('#demo-form').parsley().subscribe('parsley:form:validate', function (formInstance) {
// if one of these blocks is not failing do not prevent submission
// we use here group validation with option force (validate even non required fields)
if (formInstance.isValid('block1', true) || formInstance.isValid('block2', true)) {
$('.invalid-form-error-message').html('');
return;
}
// else stop form submission
formInstance.submitEvent.preventDefault();
// and display a gentle message
$('.invalid-form-error-message')
.html("You must correctly fill the fields of at least one of these two blocks!")
.addClass("filled");
return;
});
});
</script>
Let's say I have a hidden div called "checkmark". How would I show this div upon validation of the firstname field?
I should also clarify that I have read the documentation, but still don't understand how to accomplish what I'm trying to do here, so posting a link to the documentation is not really going to be helpful unless you are using it in your answer.
You should use Parsley's Events. Since you want to display or hide something based on a field validation, you should use parsley:field:success and parsley:field:error.
Working example (with jsfiddle):
<form id="demo-form" data-parsley-validate>
<div class="first">
<label for="firstname">Firstname:</label>
<input type="text" name="firstname" data-parsley-range="[4, 20]" data-parsley-group="block1" required />
<div class="hidden" id="checkmark">This message will be shown when the firstname is not valid </div>
<label for="lastname">Lastname:</label>
<input type="text" name="lastname" data-parsley-range="[4, 20]" data-parsley-group="block1" />
</div>
<hr></hr>
<div class="second">
<label for="fullname">Fullname:</label>
<input type="text" name="fullname" data-parsley-range="[8, 40]" data-parsley-group="block2" />
</div>
<div class="invalid-form-error-message"></div>
<input type="submit" class="btn btn-default validate" />
</form>
<script>
$(document).ready(function () {
$('#demo-form').parsley().subscribe('parsley:form:validate', function (formInstance) {
// if one of these blocks is not failing do not prevent submission
// we use here group validation with option force (validate even non required fields)
if (formInstance.isValid('block1', true) || formInstance.isValid('block2', true)) {
$('.invalid-form-error-message').html('');
return;
}
// else stop form submission
formInstance.submitEvent.preventDefault();
// and display a gentle message
$('.invalid-form-error-message')
.html("You must correctly fill the fields of at least one of these two blocks!")
.addClass("filled");
return;
});
$.listen('parsley:field:error', function(ParsleyField) {
if(ParsleyField.$element.attr('name') === 'firstname') {
$("div#checkmark").addClass('show').removeClass('hidden');
}
});
$.listen('parsley:field:success', function(ParsleyField) {
if(ParsleyField.$element.attr('name') === 'firstname') {
$("div#checkmark").addClass('hidden').removeClass('show');
}
});
});
</script>
And here's what I did:
Added a div with ìd=checkmark after the firstname field (with a hidden class, since you're using Bootstrap).
Added this block of javascript:
$.listen('parsley:field:error', function(ParsleyField) {
if(ParsleyField.$element.attr('name') === 'firstname') {
$("div#checkmark").addClass('show').removeClass('hidden');
}
});
$.listen('parsley:field:success', function(ParsleyField) {
if(ParsleyField.$element.attr('name') === 'firstname') {
$("div#checkmark").addClass('hidden').removeClass('show');
}
});
This code will listen to the validation of every input validated by Parsley. This means that when the field lastname fails, the code inside $.listen('parsley:field:error', function(ParsleyField) { will be executed. This is why I used an if to check if the attr name is firstname.
Then you show or hide the div based on the validation result.
Added required to the field, so the message is displayed when you click on the button.

Categories