Bootstrap form doesn't cancel submission when validation failed - javascript

I'm trying to create a form which will send an email to the user on submit.
The thing is that I used Bootstrap's form template and when I submit it with phone and mail wrong values (phone number even empty), the email is sent anyway (with 200 ok) and a success alert is showing.
Here is my HTML code:
<form class="needs-validation" novalidate id="paymentForm">
<div class="row">
<div class="col-md-6 mb-3">
<label for="firstName">First Name</label>
<input type="text" class="form-control" name="firstName" id="firstName" placeholder="" value="" required>
<div class="invalid-feedback">
required Feild
</div>
</div>
<div class="col-md-6 mb-3">
<label for="lastName">Lasr Name</label>
<input type="text" class="form-control" name="lastName" id="lastName" placeholder="" value="" required>
<div class="invalid-feedback">
required Feild
</div>
</div>
</div>
<div class="mb-3">
<label for="email">Email</label>
<input type="email" class="form-control" value="" name="email" id="email" placeholder="you#example.com" required>
<div class="invalid-feedback">
please enter a valid mail address
</div>
</div>
<div class="mb-3">
<label for="phone">Phone Number</label>
<input type="tel" class="form-control" value="" name="phone" placeholder="example: 050-1111111" pattern="[0]{1}[5]{1}[0-9]{8}" id="phone" required>
<div class="invalid-feedback">
please provide a valid phone number
</div>
</div>
<div class="mb-3">
<label for="address"> address</label>
<input type="text" class="form-control" name="address" id="address" placeholder="" required>
<div class="invalid-feedback">
please provide your address
</div>
</div>
<hr class="mb-4">
<h4 class="mb-3">payment method</h4>
<div class="d-block my-3">
<div class="custom-control custom-radio">
<input id="cash" value="cash" value="cash" name="paymentMethod" type="radio" class="custom-control-input" required checked>
<label class="custom-control-label" for="cash">cash</label>
</div>
<div class="custom-control custom-radio">
<input id="bit" value="bit" value="bit" name="paymentMethod" type="radio" class="custom-control-input" required>
<label class="custom-control-label" for="bit">Bit</label>
</div>
</div>
<div class="invalid-feedback">
please choose method
</div>
<hr class="mb-4">
<button class="btn btn-primary btn-lg btn-block" type="submit">continue to checkout</button>
</form>
and here is my js:
(function() {
'use strict'
window.addEventListener('load', function() {
var forms = document.getElementsByClassName('needs-validation')
Array.prototype.filter.call(forms, function(form) {
form.addEventListener('submit', function(event) {
var radioValue = $('#paymentForm input:radio:checked').val()
if (form.checkValidity() === false) {
event.preventDefault();
event.stopPropagation();
}
form.classList.add('was-validated')
var orderNumber = generateId();
var cName = $('#firstName').val() + " " + $('#lastName').val()
var cEmail = $('#email').val()
var cPhone = $('#phone').val()
var cAddress = $('#address').val()
var cSumToPay = parseInt(localStorage.getItem("totalPrice"));
var cProducts = JSON.parse(localStorage.getItem("products") || "[]");
cProducts = cProducts.map(Object.values);
cProducts = cProducts.join(' ');
console.log(cProducts);
var templateParams = {
order_number: orderNumber,
customer_name: cName,
products: cProducts,
addres: cAddress,
phone: cPhone,
customer: cEmail,
payment_Methode: radioValue,
customer_sum: cSumToPay
};
emailjs.send('gmail', 'orderconfirmation', templateParams)
.then(function(response) {
console.log('SUCCESS!', response.status, response.text);
alert('Yey! Your email was sent :)');
}, function(error) {
console.log('error');
alert(error);
});
event.preventDefault();
}, false)
})
}, false)
}())
I would be thankful if you guys can help me!!!

This section appears to be your only check for validation:
if (form.checkValidity() === false) {
event.preventDefault();
event.stopPropagation();
}
However, event.preventDefault() and event.stopPropagation() are not going to prevent the code from falling through to the next section. You can do that by including a return at this point
if (form.checkValidity() === false) {
event.preventDefault();
event.stopPropagation();
return false;
}
or you can wrap the rest of your code in the else of your conditional
if (form.checkValidity() === false) {
event.preventDefault();
event.stopPropagation();
} else {
// your email handling code
}
Note: your event.preventDefault() is useful to stop the submit button from performing its default behavior of submitting the form and event.stopPropagation() will just keep the event from bubbling up to parent elements (which you likely don't need). See: https://developer.mozilla.org/en-US/docs/Web/API/Event/preventDefault and https://developer.mozilla.org/en-US/docs/Web/API/Event/stopPropagation
In any case, you do not need two event.preventDefault() calls if you place a single one at the top of your event listener, e.g.
form.addEventListener('submit', function(event) {
event.preventDefault();
...

Related

Ajax form submit does not stay on page

I've got this script that validates my form guestform (from bootstrap) then uses ajax to submit and it works fine and loads on the same page. However, when I added some code that when the radio button "true" is clicked it reveals a hidden part of the form (I was very proud of myself for that) this breaks my ajax submit and it goes to another page and spits out the results from my php file. How can I integrate the on clicks better?
$(document).ready(function() {
var forms = document.querySelectorAll('.needs-validation')
Array.prototype.slice.call(forms)
.forEach(function(form) {
form.addEventListener('submit', function(event) {
if (!form.checkValidity()) {
event.preventDefault()
event.stopPropagation()
}
$("#btnsub").click(function(event) {
event.preventDefault();
$.ajax({
type: "POST",
url: $('#guestForm').attr('action'),
data: $('#guestForm').serialize(),
success: function(response) {
$('#output').text(response);
}
});
});
form.classList.add('was-validated')
}, false)
});
//breaks ajax submit
$('#true').click(function(event) {
document.getElementById("guests").style.display = "block";
});
$('#false').click(function(event) {
document.getElementById("guests").style.display = "none";
});
//breaks ajax submit code
});
<form method="POST" action="insert.php" id="guestForm" class="needs-validation" novalidate>
<div class="col-6">
<label for="party" class="form-label">Your Name</label>
<input type="text" class="form-control" id="party" name="party" minlength="4" maxlength="50" aria-describedby=inputGroup-sizing-default " required>
<div class="invalid-feedback ">Please Enter your full name.</div>
</div>
<div class="form-label ">Will you be joining us ?"</div>
<div class="form-check">
<input type="radio" class="form-check-input" id="true" name="att" required />
<label class="form-check-label" for="true">Joyfully accepts</label>
</div>
<div class="form-check">
<input type="radio" class="form-check-input" id="false" name="att" required />
<label class="form-check-label" for="false">Regretfully declines</label>
<div class="invalid-feedback">Please choose a response.</div>
</div>
<div class="col-6" id="guests" name="guests" style="display: none">
<p>If you are bringing a +1, please enter their name here.</p><br>
<label for="guest1" class="form-label">Guest Name</label>
<input type="text" class="form-control" id="guest1" name="guest1" placeholder="Optional" minlength="4" maxlength="50">
<div class="invalid-feedback">Please Enter their full name.</div>
</div>
<button type="submit" class="btn btn-primary" id="btnsub" name="btnsub">Submit</button>
<div id="output"></div>
</form>

Timeout function works for one form but ignores the other

I'm having a very specific problem. I have two forms on a page, bootstrap validator included and it works just fine, except that it doesn't have the RegEx check for email input. So I created a short RegEx validation, but when I try to handle error messages, they work as intended only for the second form. When I click submit button, error messages show up on both form, but timeout functions works nly for the latter one. Submit button for the top form keep creating new error messages whenever I click on it. Any advice? Please see my code below:
HTML:
Top form:
<form action="" method="POST">
<div class="form-group">
<input type="text" class="form-control" name="name" placeholder="Full Name:" required>
</div>
<div class="form-group">
<input type="email" class="form-control" name="email" placeholder="Email Address:" required>
</div>
<div class="form-group">
<input type="tel" class="form-control" name="phone" placeholder="Phone Number:" required>
</div>
<div class="form-group">
<input type="text" class="form-control" name="amount" placeholder="Investment Amount (£)">
</div>
<button class="btn btn-block btn-submit" type="submit" name="submit">Enquire Now</button>
Bottom form:
<form action="" method="POST" class="row form-find-more">
<div class="form-group col-lg-3 col-md-3">
<input type="text" name="name" placeholder="Full Name*:" required>
</div>
<div class="form-group col-lg-3 col-md-3">
<input type="email" name="email" placeholder="Email Address*:" required>
</div>
<div class="form-group col-lg-3 col-md-3">
<input type="text" name="phone" placeholder="Phone Number*:">
</div>
<div class="form-group col-lg-3 col-md-3">
<button class="btn" type="submit" name="submit">Submit Request</button>
</div>
</form>
My jQuery snippet:
<script>
var emailReg = /^(([^<>()\[\]\\.,;:\s#"]+(\.[^<>()\[\]\\.,;:\s#"]+)*)|
(".+"))#((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-
Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
var elm = $('<div class="help-block with-errors">Please enter a valid e-
mail</div>');
$(document).on('click', 'form button[type=submit]', function(e) {
var isValid = emailReg.test(jQuery.trim($(e.target).parents('form').find("input[type=email]").val()));
if(!isValid) {
e.preventDefault(); //prevent the default action
$('form').append(elm);
}
});
setTimeout(function() {
elm.detach();
}, 5000);
</script>
Managed to fix the problem by some code edits:
var emailReg = /^(([^<>()\[\]\\.,;:\s#"]+(\.[^<>()\[\]\\.,;:\s#"]+)*)|
(".+"))#((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-
9]+\.)+[a-zA-Z]{2,}))$/;
var elm = $('<div class="help-block with-errors">Please enter a valid e-mail</div>');
$(document).on('click', 'form button[type=submit]', function(e) {
var isValid = emailReg.test(jQuery.trim($(e.target).parents('form').find("input[type=email]").val()));
if(!isValid) {
e.preventDefault(); //prevent the default action
$('form').append(elm.prop('outerHTML'));
setTimeout(function() {
$('.help-block.with-errors').remove();
}, 3000);
}
});
Thank you everyone who helped.

How to send localstorage with form

I have html form and localstorage
I need send data from localstorage and form on email
Now I am sending two letter :(
When user submit form I get two letter. First letter from form and second letter from localstorage
So, I want get one letter with localstorage and form
My form:
<form action="/send.php" id="form-cart-send" onsubmit="return sendCartdata();" method="post" enctype="multipart/form-data" required>
<div class="form_fields" data-count="3">
<div class="form_field" data-type="name" data-is-required="true">
<label class="field_title">Имя<i>*</i></label>
<div class="form_field_text">
<input type="text" class="form_field_text_input" name="name" autocomplete="off" required>
</div>
</div>
<div class="form_field" data-type="phone" data-is-required="1">
<label class="field_title">Телефон<i>*</i></label>
<div class="form_field_text">
<input type="tel" class="form_field_text_input form_phone" id="phone" name="phone" data-check="phone" autocomplete="off" required>
</div>
</div>
<div class="form_field" data-type="email" data-is-required="0">
<label class="field_title">Ваш e-mail</label>
<div class="form_field_text">
<input type="text" class="form_field_text_input" name="email" data-check="email" autocomplete="off" required>
</div>
</div>
</div>
<div class="form_fields_advanced"></div>
<div class="form_submit">
<a class="component-button form_field_submit filled squared" id="checkout" data-modal-id="cart_done">
<div class="btn-content">
<div class="form_submit_text">Заказать</div>
</div>
</a>
</div>
</form>
Script for localstorage:
<script>
function sendCartdata() {
var phone = document.getElementById("phone").value;
if (phone === '') {
alert("Заполните, пожалуйста, обязательные поля.");
return false;
} else {
setTimeout(function() {
var value = localStorage.getItem('cart');
jQuery.post("/cart-send.php", {
cart: value
}, function(data) {
}).fail(function() {
alert("Damn, something broke");
});
}, 100);
return false;
}
}
</script>

Onsubmit not working

I have this form and I tried to make a "onsubmit" that when I click submit it checks if the "email" is = to "cemail" and if username was taken before or not i got this so far
<form class="form-horizontal" action="#" method="post" onsubmit="return ValidationEvent()">
<fieldset>
<legend>SIGN UP! <i class="fa fa-pencil pull-right"></i></legend>
<div class="form-group">
<div class="col-sm-6">
<input type="text" id="firstName" placeholder="First Name" class="form-control" name="firstname" autofocus required>
</div>
<div class="col-sm-6">
<input type="text" id="lastname" placeholder="Last Name" class="form-control" name="lastname" autofocus required>
</div>
</div>
<div class="form-group">
<div class="col-sm-12">
<input type="email" id="email" placeholder="Email" name="email" class="form-control" required>
</div>
</div>
<div class="form-group">
<div class="col-sm-12">
<input type="email" id="cemail" placeholder=" Re-enter Email" name="cemail" class="form-control" required>
</div>
</div>
<div class="form-group">
<div class="col-sm-12">
<input type="text" id="username" placeholder=" Username" name="username" class="form-control" required>
</div>
</div>
<div class="form-group">
<div class="col-sm-12">
<input type="password" id="password" placeholder="Password" name="password" class="form-control" required>
</div>
</div>
<div class="form-group">
<div class="col-sm-12">
<input type="text" id="datepicker" placeholder= "DOB" name="birthday" class="form-control" required>
</div>
</div>
<div class="form-group">
<label class="control-label col-sm-1"></label>
<div class="col-sm-8">
<div class="row">
<label class="radio-inline">
<input type="radio" id="radio" value="Female" name= "gender" required>Female
</label>
<label class="radio-inline">
<input type="radio" id="radio" value="Male" name= "gender">Male
</label>
</div>
</div>
</div> <!-- /.form-group -->
<div class="form-group">
<div class="col-sm-4 col-sm-offset-3">
<button type="submit" class="btn btn-primary btn-block">Register</button>
</div>
</div>
</form>
Javascript code:
<script>
function ValidationEvent() {
var email = document.getElementById("email").value;
var username = document.getElementById("username").value;
var cemail = document.getElementById("cemail").value;
// Conditions
if (email.match != cemail.match) {
alert("Your email doesn't match!");
}
if(mysqli_num_rows($result) != 0)
{
alert("Username already taken!");
}
else {
alert("Thank you");
}
}
</script>
Am I approaching the function in the wrong way is there another easier way and is it okay i put an sql statement in my java script ?
First, don't use inline HTML event handling attributes (like "onsubmit") as they create "spaghetti code", anonymous global event handling wrapper functions and don't conform to the modern W3C DOM Event handling standard.
Second, your .php results have to be gotten from somewhere. You'll need to put a call into that file for its results before you can use them.
Next, you were using the .match() string method incorrectly to compare the emails against each other. All you really need to do is compare the values entered into the email fields (it's also a good idea to call .trim() on form values to strip out any leading or trailing spaces that might have been inadvertently added).
Once you restructure your code to use standards, the JavaScript will change as follows (FYI: This won't work in the Stack Overflow snippet environment because form submissions are blocked, so you can see a working version here):
// When the DOM is loaded:
window.addEventListener("DOMContentLoaded", function(){
// Get references to the DOM elements you will need:
var frm = document.getElementById("frm");
// Don't set variables to the values of DOM elements,
// set them to the DOM elements themselves so you can
// go back and get whatever properties you like without
// having to scan the DOM for them again
var email = document.getElementById("email");
var username = document.getElementById("username");
var cemail = document.getElementById("cemail");
// Set up a submit event handler for the form
frm.addEventListener("submit", validationEvent);
// All DOM event handling funcitons receive an argument
// that references the event they are responding to.
// We need that reference if we want to cancel the event
function validationEvent(evt) {
// Conditions
if (email.value.trim() !== cemail.value.trim()) {
alert("Your email doesn't match!");
// Cancel the form submit event
evt.preventDefault();
evt.stopPropagation();
return;
}
// You need to have already gotten the "mysqli_num_rows($result)" value
// from your .php file and saved it to a variable that you can then check
// here against "!=0"
if(mysqli_num_rows($result) != 0) {
alert("Username already taken!");
// Cancel the form submit event
evt.preventDefault();
evt.stopPropagation();
} else {
alert("Thank you");
}
}
});
<form class="form-horizontal" id="frm" action="#" method="post">
<fieldset>
<legend>SIGN UP! <i class="fa fa-pencil pull-right"></i></legend>
<div class="form-group">
<div class="col-sm-6">
<input type="text" id="firstName" placeholder="First Name" class="form-control" name="firstname" autofocus required>
</div>
<div class="col-sm-6">
<input type="text" id="lastname" placeholder="Last Name" class="form-control" name="lastname" autofocus required>
</div>
</div>
<div class="form-group">
<div class="col-sm-12">
<input type="email" id="email" placeholder="Email" name="email" class="form-control" required>
</div>
</div>
<div class="form-group">
<div class="col-sm-12">
<input type="email" id="cemail" placeholder=" Re-enter Email" name="cemail" class="form-control" required>
</div>
</div>
<div class="form-group">
<div class="col-sm-12">
<input type="text" id="username" placeholder=" Username" name="username" class="form-control" required>
</div>
</div>
<div class="form-group">
<div class="col-sm-12">
<input type="password" id="password" placeholder="Password" name="password" class="form-control" required>
</div>
</div>
<div class="form-group">
<div class="col-sm-12">
<input type="text" id="datepicker" placeholder= "DOB" name="birthday" class="form-control" required>
</div>
</div>
<div class="form-group">
<label class="control-label col-sm-1"></label>
<div class="col-sm-8">
<div class="row">
<label class="radio-inline">
<input type="radio" id="radio" value="Female" name= "gender" required>Female
</label>
<label class="radio-inline">
<input type="radio" id="radio" value="Male" name= "gender">Male
</label>
</div>
</div>
</div> <!-- /.form-group -->
<div class="form-group">
<div class="col-sm-4 col-sm-offset-3">
<button type="submit" class="btn btn-primary btn-block">Register</button>
</div>
</div>
</form>
For checking the emails with email & cemail use
email.localeCompare(cemail)
This will check the string comparison betwwen two emails
And for mysqli_num_rows , is not defined any where in javascript, so we will get the undefined error in console, so need to write a different funnction with that name.
First give a name and an action to your form
<form class="form-horizontal" id="myform" action="chkValues.php" method="post" >
....
<div class="form-group">
<div class="col-sm-12">
<input type="email" id="email" placeholder="Email" name="email" class="form-control" required>
</div>
</div>
<div class="form-group">
<div class="col-sm-12">
<input type="email" id="cemail" placeholder=" Re-enter Email" name="cemail" class="form-control" required>
</div>
</div>
....
</form>
Then put this script at the bottom
<script>
$('#myForm').on("sumbit", function(){
// cancel the original sending
event.preventDefault();
$.ajax({
var form = $(this);
var action = form.attr("action"),
method = form.attr("method"),
data = form.serialize();
})
.done: function(data) // is called wehn the call was okay
{
if( data.substr(0, 5) == "Error"){
alert(data); // sent the sting of the "error message" begining with "Error"
}else{
top.location.href = data; // sent the sting of the "success page" when all was okay and data are saved in the database
}
}
.fail(function() {
alert( "Error: Getting data from Server" );
})
});
</script>
in the php file check the values an return an error if something went wrong.
<?php
if(!isset($_POST['email']) || !isset($_POST['cemail'])){
die("Error: Please fill out both email fields.");
if($_POST['email'] != $_POST['cemail'] ){
die("Error: The Email adresses do not match.");
}
here do what you want to do with the data.
when finish just send the new url
echo "success.html";
}
?>

Form Validation with jQuery - Weird Redirect

Alright, so I'm trying to do form validation with jQuery. Not sure why but when you click submit it redirects you to the page you're at already.
The forms action is blank and I included the javascript file in the header.
I will put the code below. Let me know if you see whats wrong. I want it to validate with jQuery then send you to a php file with those values in the method POST.
Register.js:
$(document).ready(function() {
$('button[name=regsubmit]').click(function(){
var fname = $('input[name=regfirstname');
var lname = $('input[name=reglastnaame');
var email = $('input[name=regemail');
var password = $('input[name=regpassword');
var repeatpassword = $('input[name=regrepeatpassword');
var username = $('input[name=regusername');
var atpos = email.indexOf("#");
var dotpos = email.indexOf(".");
if (fname==null || fname=="")
{
alert('First name must be filled out!');
return false;
}
if (lname==null || lname=="")
{
alert('Last name must be filled out!');
return false;
}
if (atpos<1 || dotpos<atpos+2 || dotpos+2>=email.length)
{
alert('Not a valid e-mail address!');
return false;
}
if (username==null || username=="")
{
alert("Username field must be filled out!");
return false;
}
if (password==null || password=="")
{
alert("Subject field must be filled out!");
return false;
}
if (repeatpassword==null || repeatpassword=="")
{
alert("Repeat password field must be filled out!");
return false;
}
if (password != repeatpassword)
{
alert("The passwords do not match!");
return false;
}
else
{
location.href="register.php";
}
});
});
Form:
<form name="register" method="POST">
<fieldset>
<div class="form-container row-fluid">
<div class="span6">
<div class="control-group">
<label class="control-label" for="regfirstname">First Name</label>
<div class="controls">
<input id="regfirstname" tabindex="1" name="regfirstname" type="text" placeholder="First Name" class="input-large" required>
</div>
</div>
<div class="control-group">
<label class="control-label" for="regusername">Username</label>
<div class="controls">
<input id="regusername" tabindex="3" name="regusername" type="text" placeholder="Username" class="input-large" required>
</div>
</div>
<div class="control-group">
<label class="control-label" for="regpassword">Password</label>
<div class="controls">
<input id="regpassword" tabindex="5" name="regpassword" type="password" placeholder="Password" class="input-large">
</div>
</div>
<div class="controls">
<button id="regsubmit" tabindex="7" name="regsubmit" class="button background-asbestos">Submit</button>
</div>
</div><!-- .span6 -->
<div class="span6">
<div class="control-group">
<label class="control-label" for="reglastname">Lastname</label>
<div class="controls">
<input id="reglastname" tabindex="2" name="reglastname" type="text" placeholder="Lastname" class="input-large" required>
</div>
</div>
<div class="control-group">
<label class="control-label" for="regemail">Email</label>
<div class="controls">
<input id="regemail" name="regemail" tabindex="4" type="text" placeholder="example#example.com" class="input-large"</td>
</div>
</div>
<div class="control-group">
<label class="control-label" for="regrepeatpassword">Repeat Password</label>
<div class="controls">
<input id="regrepeatpassword" tabindex="6" name="regrepeatpassword" type="password" placeholder="Repeat Password" class="input-large" required>
</div>
</div>
<!-- .span6 -->
<!-- span6 -->
</div><!-- .row-fluid -->
</fieldset>
</form>
Alright your JS and HTML is a big mess of stuff, so I won't recreate it all, but basics:
Give your form an ID:
<form id="SomeForm" name="register" method="POST">
Then prevent default action, and submit if passes:
// reference the button by the ID you gave it
$('#regsubmit').click(function(e){
// stop original submission
e.preventDefault();
// all your checking stuff here, but if true, then:
document.getElementById('SomeForm').submit();
});
This ensures that you are referencing the button correctly, preventing submission correctly, and submitting only if valid.
prevent default action on submit
$('button[name=regsubmit]').click(function(e)
{
e.preventDefault();
//your code below
}

Categories

Resources