javascript ajax post form function and validation - javascript

This is my code so far:
$(function () {
$('.contact-form').submit(function (event) {
$(this).find("input , textarea").each(function () {
var input = $(this);
if (input.val() == "") {
event.preventDefault();
$("label, p").addClass("error");
input.addClass("error").one("keydown", function () {
$("label").removeClass("error");
self.removeClass("error");
});
}
});
});
});
What it does:
It prevents the form from redirecting to the php script, it turns all fields red (the error class) if they are not filled, and gives the labels an error class.
What I need help with:
Fix so if one field is getting filled remove the error class as it doesn't right now.
Fix so that the label error class gets removed on the specific field when filled (right now it removes the class on all labels over all fields)
And run this code when every field / textarea is validated to be filled:
var form = $(this);
$.ajax({
type: form.attr('method'),
url: form.attr('action'),
data: form.serialize()
}).done(function () {
// Optionally alert the user of success here...
console.log("jag lyckades!");
}).fail(function () {
// Optionally alert the user of an error here...
console.log("jag lyckades INTE");
});
event.preventDefault(); // Prevent the form from submitting via the browser.
My html:
<form class="contact-form" action="<?= path(" postform.php "); ?>" method="post" validate>
<div class="row">
<div class="col-sm-6">
<label for="firstname">Förnamn*</label>
<input type="text" class="required" name="firstname" />
</div>
<div class="col-sm-6">
<label for="lastname">Efternamn</label>
<input type="text" name="lastname" />
</div>
</div>
<div class="row">
<div class="col-sm-6">
<label for="email">E-post*</label>
<input type="text" name="email" />
</div>
<div class="col-sm-6">
<label for="number">Telefon*</label>
<input type="text" name="number" />
</div>
</div>
<div class="row">
<div class="col-sm-12">
<label for="message">Meddelande*</label>
<textarea name="message"></textarea>
</div>
</div>
<div class="row">
<div class="col-sm-12">
<p>Fält markerade med * är obligatoriska</p>
<input class="btn-form" type="submit" value="Skicka">
</div>
</div>
</form>
Thanks... I really appreciate your time guys
EDIT:
This is my code at the moment:
http://jsfiddle.net/dmyhd90d/
My problems now:
Having the ajax call run when there's no more form errors ( it runs even if none is filled now )
The label error class is getting the error class removed now instantly when you fill the fields, but the fields stay error classed till I hit the send button, then it revalidates.

Lets post it all in one place because comments are not the place for this anymore
First:
with form submissions, you can often let the error field just clear when you re-validate so by adding
$('.contact-form').submit(function (event) {
$('.error').removeClass("error"); // This
you can clear the errors out and re-validate the whole form from scratch.
second, you're trying to bind an event so that when you edit the input it clear the error from that input and it's label but right now you're clearing all labels errors so you can change it like this
if (input.val() == "") {
event.preventDefault();
$("label, p").addClass("error");
input.addClass("error").one("keydown", function () {
// $("label").removeClass("error");
$("label[for='" + $(this).attr('name') + "']").removeClass("error"); // becomes this
self.removeClass("error");
});
}
To associate the input you're looking at, with it's label. BTW just so you know it's good to put input id="something" and label for="something" as that'll link the label to the input in html, when you click the label. Remember to keep your names for submitting though.
Additionally I think that
$("label, p").addClass("error");
will add an error to all your labels at once. You might want to change it also to add errors only to the fields that have errors
$("label[for='" + $(this).attr('name') + "'], p").addClass("error");
Edit to answer the comment
$('.contact-form').submit(function (event) {
$('.error').removeClass("error"); // This
$(this).find("input , textarea").each(function () {
var input = $(this);
if (input.val() == "") {
event.preventDefault();
$("label[for='" + $(this).attr('name') + "'], p").addClass("error");
input.addClass("error").one("keydown", function () {
$("label[for='" + $(this).attr('name') + "']").removeClass("error");
self.removeClass("error");
});
}
});
if ($(".errors").length <= 0) { // If there are no more error classes
// Do $.ajax() here
// http://api.jquery.com/jquery.ajax/ <- you need to read this and other similar SO posts about ajax
}
});

Related

Form submits multiple times

I am using a Wordpress theme that unfortunately is duplicating the header HTML for desktop, mobile and tablet. As a result, a login form I have appears to be submitting multiple times even though "Login" is only clicked once.
Here is the HTML for the form:
<div id="user-login">
<div class="com_row">
<div class="com_panel_body">
<div id="error_message91" class="com_alert com_alert_danger" style="display: none;">
</div>
<form method="post" id="validation_form83">
<input type="hidden" name="login_form_flag" value="1">
<div class="login-username">
<label for="email" class="main_label">Email Address</label>
<input id="email68" type="email" name="email" required="required">
</div>
<div class="login-password">
<label for="password" class="main_label">Password:</label>
<input id="password82" type="password" name="password" required="required">
</div>
<ul class="login-links" style="margin-top:-30px"><li>Forgot Password?</li></ul>
<div class="login-submit" style="margin-top:-20px">
<input type="submit" value="Login"></div>
<div style="padding-top:20px"><a class="button green small borderd-bot" href="/client_account">Register</a></div>
</form>
</div>
</div>
</div>
Here is the relevant JS:
$("[id^='validation_form']").each(function(i) {
//necessary because there are 3 form duplicates on the page, so this button works on all
jQuery(document).on("submit", this, SubmitValidationForm);
});
function($) {
SubmitValidationForm = function (event) {
event.preventDefault();
var formk = "#"+event.target.id;
var k = $(formk).serialize();
k += "&action=wcap_requests&what=validate_login";
jQuery("input[type=email]",formk).prop("disabled", true);
jQuery("input[type=password]",formk).prop("disabled", true);
jQuery("input[type=submit]",formk).prop("disabled", true).val(WCAP_Working_text);
var childf = $(formk).closest('div','.com_alert').children( ".com_alert");
$(childf).hide();
var login_form_flag = jQuery("input[name=login_form_flag]",formk).val();
jQuery.post(wcap_ajaxurl, k, function (data) {
data = JSON.parse(data);
console.log(data);
if (data.status === "OK") {
//== if client login through wcap login form
if (login_form_flag === '1'){
window.location.href = client_area_url;
}
else {
if (redirect_login !== "0") {
window.location.href = redirect_login;
} else {
window.location.reload();
}
}
}
else {
jQuery("input[type=email]",formk).prop("disabled", false);
jQuery("input[type=password]",formk).prop("disabled", false);
jQuery("input[type=submit]",formk).prop("disabled", false).val('Login');
$(childf).html(data.message).show();
}
});
};
};
The problem is because there are 3 duplicate forms on the page HTML (with only 1 visible to the user), the SubmitValidationForm function is called 3 times every time. The issue is pronounced when there is a valid login submitted, but the error box still appears saying invalid email after a few seconds (even though the login is actually correct and the user gets automatically redirected properly to the client area ). This error seems caused by the fact the SubmitValidationForm function is called 2 subsequent times after the first 'valid' submission which makes it think it's invalid, when it's not... the interesting thing is it doesn't seem caused by the other duplicate forms in the HTML, as the form ID attribute that I display in browser console shows only the 'valid' form being submitted (albeit multiple times -- perhaps because of the jquery.on() for each function).
Any ideas how to fix?
Thanks!
I figured out the issue. If anyone else is looking at this in future the issue was with respect to the 'on' function, it was referencing the 'document' before instead of 'this'. So it should be changed to:
$("[id^='validation_form']").each(function(i) {
jQuery(this).on("submit", this, SubmitValidationForm);
});

Submitting a form after validating with jquery validator on a button not in form tag

I have been battling with what is wrong on this code since. It so happens that the form is not submitting on this button. The button is of type button and not in the form tag.
$("#step1Btn").click(function () {
var userForm = $("form[name='step1Form']");
if (userForm.valid()) {
userForm.submit(function () {
console.log('submitted o!')
$("#spin1").show();
$("form[name='step1Form'] > span").remove();
$('input[name="emailInput"]').prop('name', "id")
$('input[name="fullNameInput"]').prop('name', "full-name")
$('input[name="phoneInput"]').prop('name', "phone-number")
$.ajax({
type: 'POST',
url: "api/v1/user?" + $(this).serialize(),
success: (result) => {
localStorage.setItem('user', JSON.stringify(result))
localStorage.setItem('authToken', result.authToken);
$("form[name='step1Form'] > span").remove()
$('#step1, #step2').toggle();
$('#step1Title, #step2Title').toggle();
},
error: function (request, exception, errorThrown) {
$("form[name='step1Form'] > span").remove();
$("form[name='step1Form']").prepend('<span class=\'error\'><p>' + request.responseJSON.message + '</p></span>')
},
})
});
} else {
return false;
}
});
Below is the complete form
<div id="step1" class="col-12 col-md-6">
<form name="step1Form">
<div class="home-icon d-flex justify-content-center align-items-center flex-column">
<img src="images/new-icons/user.png" alt="User Registration logo" height="80" />
<p class="my-3">User Registration</p>
</div>
<div class="form-group">
<label for="fullNameInput">Contact full name</label>
<input name="fullNameInput" class="form-control custom-input" placeholder="First name Last name" id="fullNameInput">
</div>
<div class="form-group">
<label for="emailInput">Contact email address</label>
<input name="emailInput" type="email" placeholder="example#email.com" class="form-control custom-input" id="emailInput">
</div>
<div class="form-group">
<label for="confirmEmailInput">Confirm contact email address</label>
<input name="confirmEmailInput" type="email" placeholder="example#email.com" class="form-control custom-input"
id="confirmEmailInput">
</div>
<div class="form-group">
<label for="phone">Contact phone number</label>
<input name="phoneInput" placeholder="08012345678" class="form-control custom-input" id="phone">
</div>
</form>
<button type="button" class="btn red-btn user-btn custom-btn" id="step1Btn">Next<i id="spin1" class="fa fa-spinner fa-spin"></i></button>
</div>
So I would like to see where I went wrong. I am able to log and see output whenever i place a console.log in between the if(userForm.valid) and the userForm.submit().
But as soon as i place it in the userform.submit() I do not get any value back. Like, the form is totally not submitting. I dont know if its because of how I made my Ajax call.. Please Help
You're putting Ajax inside of a submit....
$("#step1Btn").click(function () {
....
if (userForm.valid()) {
userForm.submit(function () {
....
$.ajax({ ....
Which makes no sense since Ajax replaces the actual submit. By doing this you are effectively sending it through validation again; I can't see the .validate() method, but suspect that you are simply using the default option, which would be yet another regular submit... you're probably stuck in a loop going nowhere.
The best place for your Ajax would be inside the submitHandler of the .validate() method.
If your button is outside of the form, you capture the click and manually trigger a submit, which then lets the validation plugin take over the rest.
$("#step1Btn").click(function () { // click of external button
$("form[name='step1Form']").submit(); // trigger validation & submission
});
$("form[name='step1Form']").validate({ // initialize plugin
submitHandler: function(form) { // fires when valid
// YOUR AJAX GOES INSIDE HERE
return false;
},
// other options, rules, etc.
});
Read the documentation for the submitHandler.

php $POST[] empty after Ajax call from jquery

Form :
<form method="post" id="loginForm">
<div class="form-group">
<label for="email-signin">Email address:</label>
<input type="email" class="form-control" id="email-signin" name="email-signin">
</div>
<div class="form-group">
<label for="pwd-signin">Password:</label>
<input type="password" class="form-control" id="pwd-signin" name="pwd-signin">
</div>
<div class="checkbox">
<label>
<input type="checkbox"> Remember me</label>
</div>
<button type="submit" class="btn btn-default" id="signIn" name="signIn">Sign In</button>
<div id="error">
<!-- error will be shown here ! -->
</div>
</form>
jquery :
$("#signIn").on("click", function(e) {
e.preventDefault();
var values = $("#loginForm").serialize();
console.log( values );
$.ajax({
type: "POST",
url: "../php/BusinessLayer/User.php",
data: values,
beforeSend: function() { $("#error").fadeOut() },
success : function(response)
{
console.log("Success");
if(response=="ok"){
}
else{
$("#error").fadeIn(1000, function(){
$("#error").html('<div class="alert alert-danger"> <span class="glyphicon glyphicon-info-sign"></span> '+response+' !</div>');
});
}
}
});
php:
<?php
session_start();
include ("../DataLayer/VO/UserVO.php");
include ("../DataLayer/DAO/UserDAO.php");
// Database Execution for User Related Request
$userDAO = new UserDAO();
print_r($_POST);
if(isset($_POST['signIn']))
{
echo 'test2';
$user = new UserVO();
$user->setEmail(trim($_POST['email-signin']));
$user->setPassword(trim($_POST['pwd-signin']));
// Request signin
$userDAO->signIn($user);
}
Using this code, my if(isset($_REQUEST['signIn'])) in my php file never returns true. I have tried multiple things, and nothing seems to work.
PS : I am using Jquery 1.12.4
Also, my print_r($_POST); returns an empty Array.
jQuery's serialize function does not encode the values of buttons. Taken from here
NOTE: This answer was originally posted by slashingweapon
jQuery's serialize() is pretty explicit about NOT encoding buttons or submit inputs, because they aren't considered to be "successful controls". This is because the serialize() method has no way of knowing what button (if any!) was clicked.
I managed to get around the problem by catching the button click, serializing the form, and then tacking on the encoded name and value of the clicked button to the result.
$("button.positive").click(function (evt) {
evt.preventDefault();
var button = $(evt.target);
var result = button.parents('form').serialize()
+ '&'
+ encodeURIComponent(button.attr('name'))
+ '='
+ encodeURIComponent(button.attr('value'))
;
console.log(result);
});
As far as the var dump being empty on the PHP side, try using jQuery's .click instead of the .on event.
$('#signIn').click(function(){});
Also, remove the method from your form. It looks like the form may be submitting as soon as you click the button. Also, remove
e.preventDefault();
and place
return false;
at the VERY END of the on click function. return false does 3 things
e.preventDefault()
e.stopPropigation();
return immdediatly

Submit 2 forms with 1 button, form1 after form 2 is complete

I have the following problem:
2 forms that need to be submitted with one button. I will explain how it should work.
And of course my code so far.
#frmOne contains a url field where I need to copy the data from to my #frmTwo, this works.
(it forces the visitor to use www. and not http:// etc)
When I press 1 submit button
Verify fields #frmOne (only url works now, help needed on the others)
Call #frmTwo and show result in iframe. result shows progress bar (works)
But Div, modal or any other solution besides iframe are welcome.
Close #frmOne (does not work)
Finally process (submit) #frmOne if #frmTwo is done (does not work)
Process completed code of #frmTwo in iframe =
<div style='width' id='information'>Process completed</div>
<ol class="forms">
<iframe width="100%" height="50" name="formprogress" frameborder="0" scrolling="no" allowtransparency="true"></iframe>
<div id="txtMessage"></div>
</ol>
<div id="hide-on-submit">
<form id="frmOne" method="post">
<input type="text" name="company" id="company" >
<input type="text" name="url" id="url" >
<input type="text" name="phone" id="phone" >
<input type="text" name="occupation" id="occupation" >
<textarea rows="20" cols="30" name="summary" id="summary" >
<button type="submit" class="btn btn-danger">Submit</button>
</form>
</div>
<form id="frmTwo" method="post" target="formprogress"></form>
<script>
jQuery(document).ready(function(){
//Cache variables
var $frmOne = $('#frmOne'),
$frmTwo = $('#frmTwo'),
$txtMessage = $('#txtMessage'),
frmTwoAction = 'http://www.mydomainname.com/form.php?url=';
//Form 1 sumbit event
$frmOne.on('submit', function(event){
event.preventDefault();
var strUrl = $frmOne.find('#url').val();
//validation
if(strUrl === ''){
$txtMessage.html('<b>Missing Information: </b> Please enter a URL.');
}
else if(strUrl.substring(0,7) === 'http://'){
//Clear field
$frmOne.find('#url').val('');
$txtMessage.html('<b>http://</b> is not supported!');
}
else if(strUrl.substring(0,4) !== 'www.'){
//Clear field
$frmOne.find('#url').val('');
$txtMessage.html('<b>Invalid URL</b> Please enter a valid URL!');
}
else{
//set form action and submit form
$frmTwo.attr('action', frmTwoAction + strUrl).submit();
$('#hide-on-submit').hide(0).fadeIn(1000);
$('form#frmOne').submit(function(e) {
$(this).hide(1000);
return true; // let form one submit now!
}
return false;
});
});
</script>
read here https://api.jquery.com/jQuery.ajax/. basically you need to submit the first one with $.ajax and then, when you get the server response (in the success() function ) you need to send the second form, again width ajax().
Something like:
$form1.on('submit', function(e) {
e.preventDefault(); //don't send the form yet
$.ajax(
url: $(this).attr('action'),
type: $(this).attr('method'),
data: $(this).serialize()
).success(function(data) {
alert('form one sent');
$.ajax(
url: $('#form2').attr('action'),
type: $('#form2').attr('method'),
data: $('#form2').serialize()
).success(function(data) {
alert('form two sent');
})
});
});
This code isn't ready to be copy/pasted, it's just to give you a guideline of how I would solve it. It's a big question, try going with this solution and come back with smaller question if you find yourself blocked.

jQuery submit a form

html code
<div id="signup">
<form id="suform" method="POST" action="roma/roma">
<p>
<label>Frist Name</label>
<input type="text" id="sufName"/>
<span class="errorMessage"></span>
</p>
<p>
<label>Last Name</label>
<input type="text" id="sulName"/>
<span class="errorMessage"></span>
</p>
<p>
<label>Email</label>
<input type="text" id="suEmail"/>
<span class="errorMessage"></span>
</p>
<p>
<label>Mobile Number</label>
<input type="text" id="suMNumber"/>
<span class="errorMessage"></span>
</p>
<p>
<label>Password</label>
<input type="password" id="suPassword"/>
<span class="errorMessage"></span>
</p>
<p>
<label>Re Password</label>
<input type="password" id="suRePassword"/>
<span class="errorMessage"></span>
</p>
<p>
<input type="submit" class="button" value="sign up"/>
</p>
</form>
</div>
it is just six input fields to make a sign up page
and this is the jQuery code to ensure that there is no input field empty, and if there is no input field empty I want to submit the form.
jQuery code
$(document).ready(function(){
$('#suform').on('submit', function(e){
e.preventDefault();
var errorCount = 0;
$('span.errorMessage').text(''); // reset all error mesaage
$('input').each(function(){
var $this = $(this);
if($this.val() === ''){
var error = 'Please fill ' + $this.prev('label').text(); // take the input field from label
$this.next('span').text(error);
errorCount = errorCount + 1;
}
});
if(errorCount === 0){
$(this).submit(); // submit form if no error
}
});
});
The code ensure that there is no input field empty, it found an empty one then an error message will appear, else should submit, but the submit doesn't work.
code
Try using $(this)[0].submit();. Using $(this) refers to the jQuery object reference to the form. I don't know what jQuery's submit() method actually does, but it clearly doesn't submit the form. Using $(this)[0] refers to the actual DOM element, which will use the standard DOM submit method, which is what you're looking for.
I'm sure you know this already, but you should use server and client side validation, because some users don't have JS and some users will purposely tamper with your form. Just a quick "Don't forget"!
Check out the jQuery validation plugin. For this you add a class = "required" for any input field that is required, and just call validation on it:
$('form').validation({
// any options you want
});
It will also do handy things like displaying error messages, doing conditional validation, etc.
You can remove e.preventDefault() and use return insead:
$('form').on('submit', function(e){
var errorCount = 0;
$('span.errorMessage').text('');
$('input').each(function(){
var $this = $(this);
if($this.val() === ''){
var error = 'Please fill ' + $this.prev('label').text();
$this.next('span').text(error);
errorCount = errorCount + 1;
}
});
return errorCount === 0;
});
DEMO: http://jsfiddle.net/h9njC/27/
$('form').on('submit',function(e){
var errorCount = 0;
$('span.errorMessage').text('');
$('input').each(function(){
var $this = $(this);
if($this.val() === ''){
var error = 'Please fill ' + $this.prev('label').text();
$this.next('span').text(error);
errorCount = errorCount + 1;
}
});
if(errorCount === 0){
alert('done'); // just an alert to notice when everything OK [remove it]
$this.submit(); // submit the form on success
} else e.preventDefault(); // halt the submission on default
});
DEMO

Categories