Validation using jQuery-plugin doesn't work after an AJAX call - javascript

I'm trying validate a form using jQuery-plugin. I have three usual select boxes on a form, country, state and city. As usual, the country select box is populated on page load. The two successive select boxes are populated on the onchange event of respective select boxes using Ajax.
<div>
<label> Country<span style="color: Red;">*</span></label>
<select id="cmb_country" name="cmb_country" validation="required" class="inputText" onchange="fillState(this.value,0);">
<option value=''>Select</option>
<?php $combo->combo("select country_id, country_name from country", 0);?>
</select>
</div>
<div class="clear"> </div>
<div>
<label> State<span style="color: Red;">*</span></label>
<span id="stateList">
<select id="cmb_state" name="cmb_state" validation="required" class="inputText" onchange="fillCity(this.value, 0);">
<option value=''>Select</option>
</select>
</span>
</div>
<div class="clear"> </div>
<div>
<label> City<span style="color: Red;">*</span></label>
<span id="cityList">
<select id="cmb_city" name="cmb_city" validation="required" class="inputText">
<option value=''>Select</option>
</select>
</span>
</div>
<div class="clear"> </div>
The following jQuery code always returns false after the Ajax call that prevents the form from being submitted.
var Form = function(form) {
var fields = [];
form.find("[validation]").each(function() {
var field = $(this);
if (field.attr('validation') !== undefined) {
fields.push(new Field(field));
}
});
this.fields = fields;
}
Form.prototype = {
validate: function() {
for (field in this.fields) {
this.fields[field].validate();
}
},
isValid: function() {
for (field in this.fields) {
if (!this.fields[field].valid) {
this.fields[field].field.focus();
return false;
}
}
return true;
}
}
Without using Ajax, it goes well so how to make it work after populating all the select boxes using Ajax?

Related

Bootstrap website payments with Stripe

I'm completely new to using Stripe for payments, and as it's a Bootstrap site & I'm using Stripe.js v2.
From my understanding of how Stripe works, my HTML form needs to initially communicate with Stripe with the credit card num, cvc & expirary using Javascript, which will return a token (or an error) - and I then submit this token, and other payment information like the amount etc.. to the PHP script on my Server (which then sends this Stripe).
My problem is, my JavaScript is never executed first - and instead my page tries to run submit.php first.
What should I do to correct this - and have my JavaScript create the token, and then have the token passed to my submit.php code?
*Note - my HTML form does contain more than what's listed here (such as asking the user for Name, Address, State, Phone, Amount etc), but i shortened it, so it was easier to read.
HTML Code:
<form action="/PHP/submit.php" method="POST" class="contact-form" id="payment-form">
<div id="creditcard">
<span class="payment-errors"></span>
<div class="form-group has-feedback row">
<label for="cardnumber" class="col-sm-2 form-control-sm">Card Number:</label>
<div class="col-sm-5">
<!--<input type="text" autocomplete="off" class="form-control form-control-sm card-number" value="" pattern="[0-9]{10}" data-stripe="number">-->
<input type="text" autocomplete="off" class="form-control form-control-sm card-number" data-stripe="number">
</div>
<label for="cvc" class="col-sm-1 form-control-sm">CVC:</label>
<div class="col-sm-4">
<!--<input type="text" autocomplete="off" class="form-control form-control-sm card-cvc" maxlength="3" value="" pattern="[0-9]{3}" data-stripe="cvc">-->
<input type="text" autocomplete="off" class="form-control form-control-sm card-cvc" data-stripe="cvc">
</div>
</div>
<div class="form-group has-feedback row">
<label for="expiration" class="col-sm-2 form-control-sm">Expiration Date </label>
<div class="col-sm-2">
<select class="card-expiry-month form-control form-control-sm" data-stripe="exp-month">
<option value="01" selected>01</option>
<option value="02">02</option>
<option value="03">03</option>
<option value="04">04</option>
<option value="05">05</option>
<option value="06">06</option>
<option value="07">07</option>
<option value="08">08</option>
<option value="09">09</option>
<option value="10">10</option>
<option value="11">11</option>
<option value="12">12</option>
</select>
</div>
<div class="col-sm-2">
<select class="card-expiry-year form-control form-control-sm" data-stripe="exp-year">
<option value="2018" selected>2018</option>
<option value="2019">2019</option>
<option value="2020">2020</option>
<option value="2021">2021</option>
<option value="2022">2022</option>
<option value="2023">2023</option>
<option value="2024">2024</option>
<option value="2025">2025</option>
</select>
</div>
</div>
<div class="form-group row">
<label for="cardname" class="col-sm-2 form-control-sm">Name on Card:</label>
<div class="col-sm-10">
<input type="text" class="form-control form-control-sm" autocomplete="off" name="cardname" id="cardname">
</div>
</div>
<div class="form-row form-submit">
<button type="submit" class="btn btn-default submit-button">Submit Donation</button>
</div>
</div>
</form>
And my Javascript:
<script src="https://js.stripe.com/v2/"></script>
<script>
(function() {
Stripe.setPublishableKey('pk_test_xxxxx');
})();
</script>
<script>
$(document).ready(function() {
$('#payment-form').on('submit', generateToken);
var generateToken = function(e) {
var form = $(this);
//No pressing the buy now button more than Once
form.find('button').prop('disabled', true);
//Create the token, based on the form object
Stripe.create(form, stripeResponseHandler);
//Prevent the form from submitting
e.preventDefault();
});
});
var stripeResponseHandler = function(status, response) {
var form = $('#payment-form');
//Any validation errors?
if (response.error) {
form.find('.payment-errors').text(response.error.message);
alert(result.error.message);
//Make the submit button clickable again
form.find('button').prop('disabled', false);
} else {
//Otherwise, we're good to go! Submit the form.
//Insert the unique token into the form
$('<input>', {
'type': 'hidden',
'name': 'stripeToken',
'value': response.id
}).appendTo(form);
alert(result.token.id);
//Call tge native submit method on the form
//to keep the submission from being cancelled
form.get(0).submit();
}
};
</script>
You should define the generateToken function before the $('#payment-form').on('submit', generateToken);. Otherwise the submit event has no handler, and e.preventDefault(); is never reached.
$(document).ready(function() {
$('#payment-form').on('submit', generateToken);
var generateToken = function(e) {
var form = $(this);
//No pressing the buy now button more than Once
form.find('button').prop('disabled', true);
//Create the token, based on the form object
Stripe.create(form, stripeResponseHandler);
//Prevent the form from submitting
e.preventDefault();
});
});
Demo: https://www.codeply.com/go/wRcqjxfVmf
I ended up going a slightly different direction, using an 'onsubmit' event on the form, to trigger the javascript before the PHP;
<form action="/PHP/submit.php" method="POST" class="contact-form" id="payment-form" onsubmit="return onSubmitDo()">
I also completely changed the Javascript so it looked like this:
Stripe.setPublishableKey('pk_test_******');
function onSubmitDo () {
Stripe.card.createToken( document.getElementById('payment-form'), myStripeResponseHandler );
return false;
};
function myStripeResponseHandler ( status, response ) {
console.log( status );
console.log( response );
if ( response.error ) {
document.getElementById('payment-error').innerHTML = response.error.message;
} else {
var tokenInput = document.createElement("input");
tokenInput.type = "hidden";
tokenInput.name = "stripeToken";
tokenInput.value = response.id;
var paymentForm = document.getElementById('payment-form');
paymentForm.appendChild(tokenInput);
paymentForm.submit();
}
};
The actual javascript code I used here, i found on this github account which has some Stripe payment samples;
https://github.com/wsmoak/stripe/blob/master/php/test-custom-form.html
Now the form just needs to integrate jquery.payment (to format & validate card details), and it should all be complete.
https://github.com/stripe/jquery.payment

Vue.js 2.0 Vee Validate plugin not clearing errors after ajax call

I am working on a vue.js 2.0 project. I am using the Vee-Validate plugin. I have a form and when it submits, it makes an ajax call to my api. After the api call returns successfully, I am trying to clear my vee-validation so that I can invite another user with the same form, but it's not working at all.
I tried the method this.errors.clear() as suggested in their documentation
I have also thought that maybe its happening too fast, so I added a set timeout function for a couple seconds, but it still doesn't clear the errors.
Here is my Vue file with all related code:
<template>
<div v-if="user.first_time_login == 0 && user.stripe_check == 1">
<div class="viv-modal-overlay">
<div class="container">
<div class="viv-modal green">
<span class="modal-title" id="setup-team-top">Now let’s set up your team.</span>
<p>Your plan allows up to {{this.user.company.max_users}} users. Would you like to shoot out some team invites before we send you to the dashboard?</p>
<div class="invited-users" v-bind:class="{ show: show_invites }" v-if="show_invites">
<p>You can invite up to 4 more team members. Upgrade to add more.</p>
<ul>
<li v-for="invite in invites">
<img src="/img/icons/checkmark.svg" width="20" height="20" alt="success">
You invited {{invite.email}}.
<span class="clearfix"></span>
</li>
</ul>
<div class="team-done-adding">
I'm done adding team members.
</div>
</div>
<div class="modal-form">
<form id="setup-stripe-form">
<div class="row">
<div class="col-md-12">
<div class="form-group">
<label>Team Member's Email<span>*</span></label>
<input type="text" name="email" v-model="newUser.email" v-validate data-vv-rules="required" class="form-control" :placeholder="'user#'+user.company.company_name.replace(/[^A-Z0-9]+/ig, '').toLowerCase()+'.com'">
<span v-show="errors.has('email')" class="error">{{ errors.first('email') }}</span>
</div>
<div class="form-group">
<label>Access to Leads and Contacts<span>*</span></label>
<select name="access_leads" v-model="newUser.access_leads" v-validate data-vv-rules="required" class="form-control">
<option value="1">they can see leads and contacts they created</option>
<option value="2">they can see all leads and contacts</option>
<option value="0">no access to leads and contacts</option>
</select>
<span v-show="errors.has('access_leads')" class="error">{{ errors.first('access_leads') }}</span>
</div>
<div class="form-group">
<label>Access to Proposals<span>*</span></label>
<select name="access_proposals" v-model="newUser.access_proposals" v-validate data-vv-rules="required" class="form-control">
<option value="1">they can see proposals they created</option>
<option value="2">they can see all proposals</option>
<option value="0">no access to proposals</option>
</select>
<span v-show="errors.has('access_proposals')" class="error">{{ errors.first('access_proposals') }}</span>
</div>
<div class="form-group">
<label>Access to Invoices<span>*</span></label>
<select name="access_invoices" v-model="newUser.access_invoices" v-validate data-vv-rules="required" class="form-control">
<option value="1">they can see invoices they created</option>
<option value="2">they can see all invoices</option>
<option value="0">no access to invoices</option>
</select>
<span v-show="errors.has('access_invoices')" class="error">{{ errors.first('access_invoices') }}</span>
</div>
<div class="form-group">
<label>Access to Projects<span>*</span></label>
<select name="access_projects" v-model="newUser.access_projects" v-validate data-vv-rules="required" class="form-control">
<option value="1">they can see projects they created</option>
<option value="2">they can see all projects</option>
<option value="0">no access to projects</option>
</select>
<span v-show="errors.has('access_projects')" class="error">{{ errors.first('access_projects') }}</span>
</div>
</div>
<div class="col-md-12 text-center">
<div class="modal-btn-pad">
<button type="submit" v-bind:class="{ disabled: adding_team_member }" class="btn btn-lg btn-green" #click="submitInviteForm">
<span class="sending-invite" v-if="adding_team_member">Sending Invite <img src="/img/preloader.svg" width="20" height="20"></span>
<span v-else>Continue</span>
</button><br>
<a class="light-link" href="#" #click="skipInviteForm">Skip this for now.</a>
</div>
</div>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
</template>
<script>
import { mapState } from 'vuex'
export default {
data() {
return {
newUser: {
email: '',
access_leads: 1,
access_proposals: 1,
access_invoices: 1,
access_projects: 1
},
users_invited: 0,
invites: [],
show_invites: false,
adding_team_member: false
}
},
computed: mapState({
appLoading: state => state.appLoading,
user: state => state.user
}),
methods: {
submitInviteForm: function(e) {
e.preventDefault()
this.$validator.validateAll()
if (!this.errors.any()) {
//There are no errors, move forward...
//Add the team member to the database...
//Grab the authorized user
const authUser = JSON.parse(window.localStorage.getItem('authUser'))
//Create the payload...
var newTeamMember = this.newUser
//Were adding a team member now so show the loader!
this.adding_team_member = true
//Create the new company and add the owner...
this.$http.post('/api/team',
{
newTeamMember: JSON.stringify(newTeamMember)
},
{
headers: {
Authorization: 'Bearer ' + authUser.access_token
}
}).then((response) => {
if(response.status === 200) {
//Assign the user to a variable
var invitedUser = response.body
//Add the user to the list of invited users
this.invites.push({email: invitedUser.email })
//Show the invite list...
this.show_invites = true
//Jump to top
location.hash = '#setup-team-top'
//reset the new user
this.newUser.email = ''
this.newUser.access_leads = 1
this.newUser.access_proposals = 1
this.newUser.access_invoices = 1
this.newUser.access_projects = 1
//Were done adding a team member so hide the loader!
this.adding_team_member = false
//Clear the validation errors
this.errors.clear()
}
}).catch(function(error){
console.log(error);
})
}
},
skipInviteForm: function(e) {
e.preventDefault()
alert('skip invite!')
}
}
}
</script>
Try to have a look at this fiddle which was extracted from this issue.
Basically, you have to call this.$validator.clean(); after you have reset the input fields of your form.

Using jQuery validate on select list

I have the following javascript:
var $step = $(".wizard-step:visible:last"); // get current step
var validator = $("#WizardForm").validate(); // obtain validator
var anyError = false;
$step.find("input").each(function ()
{
if (!validator.element(this)) { // validate every input element inside this step
anyError = true;
}
});
This is successfully validating all my input fields but upon trying to apply a similar method to the select type using code:
$step.find("select").each(function () {
if (!validator.element(this)) { // validate every input element inside this step
anyError = true;
}
});
My HTML is as follows:
<div class="wizard-step" id="step1" visibility="hidden" style="display: block;">
<div class="row">
<div class="col-md-6 column ui-sortable">
<div class="form-group">
<label class="control-label col-md-4" for="Tariff_Type">Tariff Type</label>
<div class="col-md-8">
<select style="width:100%;height:35px;border-radius:4px;padding-left:10px;" id="TariffType" name="TariffType" class="form-control input required">
<option value="">Please Select Tariff Type</option>
<option value="keypad account">Say Hello To Budget Extra Discount</option>
<option value="bill pay account">Standard 24H</option>
</select>
<span class="field-validation-valid text-danger" data-valmsg-for="TariffType" data-valmsg-replace="true"></span>
</div>
</div>
</div>
</div>
</div>
How can I ensure that a TariffType value is selected using this method?
Try the .valid() method instead...
if (! $(this).valid()) { ...

Save input values in reactive variables (Meteor)

I am using reactive vars to manage visibility of my input fields depenging on user's choice select. But when I choose one option, write anything in shown input, then go to the second option, and finally when I come back to the firs one, the input value disappears. Is there any way to keep that data untill confirm button pressing to confirm once all the fields values under all the options?
Here are two input groups that are displayed, when option is set:
<template name="addTour">
<label class="control-label col-xs-4" for="tour-dropdown">Программа</label>
<div class="dropdown col-xs-8 form-group form-horisontal">
<select class="form-control" id="tour-dropdown">
<option value="a">A</option>
<option value="b">B</option>
</select>
</div>
{{#if a}}
<div class="container-fluid">
{{> textfield label='a option' id='transfer-city-from'}}
{{> confirm add='a option'}}
</div>
{{/if}}
{{#if b}}
<div class="container-fluid">
{{> textfield label='b option' id='transfer-city-from'}}
{{> confirm add='b option'}}
</div>
{{/if}}
And some JS here that manages reactive variables to do all that job:
Template.addTour.onCreated( function () {
this.a = new ReactiveVar( false );
this.b = new ReactiveVar( false );
Template.addTour.helpers( {
a: function () {
return Template.instance().a.get();
},
b: function () {
return Template.instance().b.get();
}
}
});
Template.addTour.events( {
'change select': function ( event, template ) {
if ( $( event.target ).val() === "a" ) {
template.a.set( true );
} else {
template.a.set( false );
};
if ( $( event.target ).val() === "b" ) {
template.b.set( true );
} else {
template.b.set( false );
};
}
});
Or I shoud better use display:block and display:none ?
Thanks in advance for any suggestions.
So, I managed to resolve my problem with jQuery and it's hide() / show() options.
Here is the code:
<template name="addTour">
<label class="control-label col-xs-4" for="tour-dropdown">Программа</label>
<div class="dropdown col-xs-8 form-group form-horisontal">
<select class="form-control" id="tour-dropdown" >
<option value="a">A</option>
<option value="b">B</option>
</select>
</div>
<div class="container-fluid" id="a">
<div class="row">
<div class="col-sm-4">
<form class='form-horizontal'>
<div class="form-group">
<h1>A option</h1>
{{> timepicker label='время прибытия' id='transfer-time-a'}}
</div>
</form>
</div>
</div>
</div>
<div class="container-fluid" id="b">
<div class="row">
<div class="col-sm-4">
<form class='form-horizontal'>
<div class="form-group">
<h1>B option</h1>
{{> timepicker label='время прибытия' id='transfer-time-b'}}
</div>
</form>
</div>
</div>
</div>
And jQuery works for me in this view:
Dropdown = $('#tour-dropdown');
$('#a').hide();
$('#b').hide();
select = this.value;
Dropdown.change(function() {
if ($(this).val() === 'a') {
$('#a').show();
console.log('A option');
} else $('#a').hide();
if ($(this).val() === 'b') {
$('#b').show();
console.log('B option');
} else $('#b').hide();// hide div if value is not "custom"
});
It works fine and keep values inside all the hidden inputs, so I can submit all of them once.

ajax form is not working how it should

hello i been working on a form using ajax but when it comes down to validating a select box
problem 1) every time i leave the job_est value empty the form is still submitted as if it was validated
problem 2) can i use async in ajax
sorry for my writing skills
<script type="text/javascript" src="http://code.jquery.com/jquery-latest.js"></script>
<script type="text/javascript">
$(document).ready(function() {
//if submit button is clicked
$('#submit').click(function () {
//Get the data from all the fields
var name = $('input[name=name]');
var l_name = $('input[name=l_name]');
var phone = $('input[name=phone]');
var email = $('input[name=email]');
var postcode = $('input[name=postcode]');
var house_number = $('input[name=house_number]');
var street = $('input[name=street]');
var job_est = $('select[name=job_est]');
var comment = $('textarea[name=comment]');
//Simple validation to make sure user entered something
//If error found, add hightlight class to the text field
if (name.val()=='') {
name.addClass('hightlight');
return false;
} else name.removeClass('hightlight');
if (l_name.val()=='') {
l_name.addClass('hightlight');
return false;
} else l_name.removeClass('hightlight');
if (phone.val()=='') {
phone.addClass('hightlight');
return false;
} else phone.removeClass('hightlight');
if (email.val()=='') {
email.addClass('hightlight');
return false;
} else email.removeClass('hightlight');
if (postcode.val()=='') {
postcode.addClass('hightlight');
return false;
} else postcode.removeClass('hightlight');
if (house_number.val()=='') {
house_number.addClass('hightlight');
return false;
} else house_number.removeClass('hightlight');
if (street.val()=='') {
street.addClass('hightlight');
return false;
} else street.removeClass('hightlight');
if (job_est.val()=='') {
job_est.addClass('hightlight');
return false;
} else job_est.removeClass('hightlight');
if (comment.val()=='') {
comment.addClass('hightlight');
return false;
} else comment.removeClass('hightlight');
//organize the data properly
var data = 'name=' + name.val() + '&email=' + email.val() + '&phone=' +
phone.val() + '&comment=' + encodeURIComponent(comment.val());
//disabled all the text fields
$('.text').attr('disabled','true');
//show the loading sign
$('.loading').show();
//start the ajax
$.ajax({
//this is the php file that processes the data and send mail
url: "process.php",
//GET method is used
type: "GET",
//pass the data
data: data,
//Do not cache the page
cache: false,
//success
success: function (html) {
//if process.php returned 1/true (send mail success)
if (html==1) {
//hide the form
$('.form').fadeOut('slow');
//show the success message
$('.done').fadeIn('slow');
//if process.php returned 0/false (send mail failed)
} else alert('Sorry, unexpected error. Please try again later.');
}
});
//cancel the submit button default behaviours
return false;
});
});
</script>
<body>
<div class="block">
<div class="done">
<b>Thank you !</b> We have received your message.
</div>
<div class="form">
<form method="post" action="process.php">
<h4><u>Basic Contact Details</u></h4>
<div style="display: inline-block;" class="element">
<label>Name</label><input type="text" name="name"/>
</div>
<div style="display: inline-block;" class="element">
<label>Last Name: </label><input type="text" name="l_name"/>
</div>
<div class="element">
<label>Phone Number</label>
<input type="text" name="phone"/>
</div>
<div class="element">
<label>Email</label>
<input type="text" name="email"/>
</div>
<div style="display: inline-block;" class="element">
<label>Postcode: </label><input type="text" name="postcode" size="10" maxlength="10">
</div>
<div style="display: inline-block;" class="element">
<label>House Number: </label><input type="text" name="house_number" size="3">
</div>
<div style="display: inline-block;" class="element">
<label>Street Name: </label><input type="text" name="street">
</div>
<div style="display: inline-block;" class="element">
<label>County:</label>
<select>
<option name="select">--SELECT--</option>
<option name="bedford">Bedford</option>
<option name="dunstable">Dunstable</option>
<option name="luton">Luton</option>
</select>
</div>
<h4><u>Job Details</u></h4>
<div class="element">
<label>You Would Like To Book A:</label>
<select name="job_est">
<option name="select">--SELECT--</options>
<option name="job">Job</option>
<option name="est">Estimation</option>
</select>
</div>
<br/>
<div class="element">
<label>Service Your Booking:</label>
<select>
<option name="select">--SELECT--</option>
<option name="gardening">Gardening</option>
<option name="landscaping">Landscaping</option>
<option name="painting">Painting & Decorating</option>
<option name="decking">Decking & Fencing</option>
</select>
</div>
<br/>
<div class="element">
<label>Any Additional Information </label>
<textarea name="comment" class="text textarea" /></textarea>
</div>
<div class="element">
<input type="submit" id="submit"/>
<div class="loading"></div>
</div>
</form>
</div>
</div>
<div class="clear"></div>
You should change selectbox's name attribute with value
<select name="job_est">
<option value="select">--SELECT--</options>
<option value="job">Job</option>
<option value="est">Estimation</option>
</select>
and in your javascript, it should be
if (job_est.val() == 'select') {
job_est.addClass('hightlight');
return false;
}

Categories

Resources