Using jQuery validate on select list - javascript

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()) { ...

Related

JavaScript form onchange getting Nan

I am calling onchange event on form but when I checked in console values are coming in Nan
HTML
<form onchange="calculateHSA(event)">
<div class="col-sm-4">
<input type="number" name="claim-amnt" id="claim-amnt" required="">
</div>
<div class="col-sm-4">
<input type="number" name="admin-percent" id="admin-percent" required="">
</div>
<div class="col-sm-4">
<span class="dataText">Select your province
</span><br>
<select name="province" id="province">
<option value="abc">ABC</option>
</select>
</div>
</form>
JavaScript
function calculateHSA(e) {
e.preventDefault();
const claimAmount = parseInt($(e.target).find('#claim-amnt').val());
console.log(claimAmount);
const adminPercent = parseInt($(e.target).find('#admin-percent').val());
console.log(adminPercent);
const province = $(e.target).find('#province').val();
console.log(province);
displayTaxDetails(claimAmount, adminPercent, province);
}
Where I did wrong code?
Please use e.currentTarget instead of e.target because e.target can be your text fields but e.currentTarget will always be your form. This code is working fine.
<form onchange="calculateHSA(event)">
<div class="col-sm-4">
<input type="number" name="claim-amnt" id="claim-amnt" required="">
</div>
<div class="col-sm-4">
<input type="number" name="admin-percent" id="admin-percent" required="">
</div>
<div class="col-sm-4">
<span class="dataText">Select your province
</span><br>
<select name="province" id="province">
<option value="abc">ABC</option>
</select>
</div>
</form>
<script>
function calculateHSA(e) {
e.preventDefault();
const claimAmount = parseInt($(e.currentTarget).find('#claim-amnt').val());
console.log(claimAmount);
const adminPercent = parseInt($(e.currentTarget).find('#admin-percent').val());
console.log(adminPercent);
const province = $(e.currentTarget).find('#province').val();
console.log(province);
displayTaxDetails(claimAmount, adminPercent, province);
}
</script>
There's no need to use e.target in your example. You can just access the values from the selectors directly:
function calculateHSA(e) {
e.preventDefault();
const claimAmount = parseInt($('#claim-amnt').val());
console.log(claimAmount);
const adminPercent = parseInt($('#admin-percent').val());
console.log(adminPercent);
const province = parseInt($('#province').val());
console.log(province);
displayTaxDetails(claimAmount, adminPercent, province);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<form onchange="calculateHSA(event)">
<div class="col-sm-4">
<input type="number" name="claim-amnt" id="claim-amnt" required="">
</div>
<div class="col-sm-4">
<input type="number" name="admin-percent" id="admin-percent" required="">
</div>
<div class="col-sm-4">
<span class="dataText">Select your province
</span><br>
<select name="province" id="province">
<option value="abc">ABC</option>
</select>
</div>
</form>
Note that you will get NaN in the console for any field that doesn't have a value that can be parsed as an integer. So if you leave the field blank, you're still going to get NaN in the console.
You are getting NaN because your target element is pointing to the input tag instead of form element
I have made some changes in the function and added new line in the code
function calculateHSA(e) {
e.preventDefault();
var form = $(e.target).parent().parent(); // <-- get the form element
const claimAmount = form.find('#claim-amnt').val();
console.log(claimAmount);
const adminPercent = form.find('#admin-percent').val();
console.log(adminPercent);
const province = form.find('#province').val();
console.log(province);
displayTaxDetails(claimAmount, adminPercent, province);
}
have a look at this plunker https://plnkr.co/edit/BQ538zbYBk857zT1wAgT

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

Dropdowns not bound to ng-model in Angular

Something very basic I am missing but I am not able to figure out . I have three fields in a view , two of them are dropdowns.
<div class="form-group row">
<label for="GroupName" class="col-sm-4 form-control-label">Group Name : </label>
<div class="col-sm-8">
<input ng-model="referenceEdit.groupName" id="GroupName" class="form-control" type="text">
</div>
</div>
<div class="form-group row">
<label for="GroupType" class="col-sm-4 form-control-label">Group Type : </label>
<div class="col-sm-8">
<select name="selGroupType" id="selGroupType" class="form-control" ng-change="referenceEdit.populateGroupTypeDetails(selGroupType)" ng-options="groupType.value for groupType in referenceEdit.groupTypes track by groupType.id" ng-model="referenceEdit.groupType"></select>
</div>
</div>
<div class="form-group row">
<label for="GroupAssignmentMethod" class="col-sm-4 form-control-label">Group Assignment Method : </label>
<div class="col-sm-8">
<select name="selGroupAssignmentMethod" id="selGroupAssignmentMethod" class="form-control" ng-options="assignmentMethod.id for assignmentMethod in referenceEdit.assignmentMethods track by assignmentMethod.value" ng-model="referenceEdit.assignmentMethod"></select>
</div>
</div>
Now in controller , I am getting the results for these drop downs in this way :
var row_details = GroupMembershipReferenceServices.getReferenceDataRow();
referenceDataDropDownService.getDropDown(REFERENCE_DATA_CONSTANTS.GROUP_TYPE).success(function (result) {
$scope.referenceEdit.groupTypes = result;
$scope.referenceEdit.groupype = row_details.grp_typ;
}).error(function (result) {
alert("Unable to retrieve dropdown values");
});
referenceDataDropDownService.getDropDown(REFERENCE_DATA_CONSTANTS.GROUP_ASSIGNMENT_METHOD).success(function (result) {
$scope.referenceEdit.assignmentMethods = result;
$scope.referenceEdit.assignmentMethod = row_details.grp_assgnmnt_mthd;
}).error(function (result) {
alert("Unable to retrieve dropdown values");
});
Problem is values are getting populated , like
and we are displaying the values accordingly. The results are like
[0] {id:"1",value:"Chapter Non-Event"}
[1] {id:"2",value:"NHQ Campaign"}
But the row_details.grp_typ is "NHQ Campaign".
Even though I assign it , the drop down option is not selected accordingly .
Have I to assign it to the value property only ? What am I missing ?
use ng-repeat instead of ng-options
eg:
<select name="selGroupType" id="selGroupType" class="form-control" ng-change="referenceEdit.populateGroupTypeDetails(selGroupType)" ng-model="referenceEdit.groupType">
<option value="-1">---</option>
<option ng-repeat="groupType.value for groupType in referenceEdit.groupTypes track by groupType.id" value="{[{groupType.id}]}"> {[{groupType.value}]} </option></select>

How to remove models that are no longer bound to dom

I have a form that has a bunch of logic about which elements to show using ng-if. For example I might have a country drop down and if USA is selected it will show the state drop down which was conditioned upon an ng-if for country. Perhaps this was not the best way to do it so if there are recommendations for a different approach for the next project that will be appreciated but I need to finish this project with few major modifications.
The problem is if a user selects a country say USA and then a state, and then selects a different country. The state is still selected within the model. So how would I go about removing the state field. There are deeply nested ng-if's (think about 4-5 levels).
Example
<div ng-if="root.originCountry == 'PAK'">
<div ng-if="root.productType == 'Custom Football Jersey' || root.productType == 'Sublimated Football Jersey'">
<div class="control-group">
<label class="control-label" for="productTypeType">{{root.productType}} Type</label>
<div class="controls">
<select ng-model="root.productTypeType" ng-options="type for type in pakJerseyTypeList" bs-select required></select>
</div>
</div>
<div class="ordered-container">
<div ng-if="root.productTypeType">
<div class="control-group">
<label class="control-label" for="bodyColor">Body Color</label>
<div class="controls">
<select ng-model="root.bodyColor" ng-options="color for color in bodyColorList" bs-select required></select>
</div>
</div>
<div ng-if="root.bodyColor == 'Other'">
<div class="control-group no-count">
<label class="control-label" for="bodyColorPmsCode">Body Color PMS Code</label class="control-label no-count">
<div class="controls">
<input type="text" ng-model="root.bodyColorPmsCode" name='bodyColorPmsCode' required>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
You can utilize the ng-change directive to your advantage; set one on a parent select box and implement its handler to clear the values of any child select box depending on it.
Here's a quick snippet illustrating how to achieve this:
<select
ng-model="selectedCountry"
ng-options="country for country in countries"
ng-change="clearCity()">
</select>
<select
ng-model="selectedCity"
ng-if="isJapanSelected()"
ng-options="city for city in japanCities"
ng-change="setCity(selectedCity)">
</select>
var app = angular.module('myModule', []);
app.controller('MainCtrl', function($scope) {
$scope.countries = ['Japan', 'Brasil', 'England'];
$scope.selectedCountry = 'Brasil';
$scope.selectedCity = '';
$scope.japanCities = ['Tokyo', 'Yokohama', 'Osaka']
$scope.isJapanSelected = function() {
return $scope.selectedCountry == 'Japan';
};
$scope.getCity = function() {
return $scope.selectedCity;
};
$scope.setCity = function(city) {
$scope.selectedCity = city;
};
$scope.clearCity = function() {
if (!$scope.isJapanSelected()) {
$scope.selectedCity = '';
}
};
});
Live demonstration on plunker

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

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?

Categories

Resources