i'm struggling with the remove/add class when there is no digit in the address field. When there is no digit in the field the class: 'ok-form' has te be removed and the class : 'error-form' has to be added.
If i just add $(this).removeClass('ok-form').addClass('error-form'); after this part (line12): if (!$(this).val().match(/\d+/)) { it is not working.
Does anyone has an idea?
$('input[name="shipping_address[address1]"], input[name="payment_address[address1]"]').on('blur', function() {
$(this).removeClass('ok-form error-form');
if ($(this).siblings('.supercheckout-required').css('display') == "none" && $(this).val() == '') {
$(this).removeClass('ok-form error-form');
} else if ($(this).val() == '') {
$(this).removeClass('ok-form').addClass('error-form');
$(this).parent().append('<span class="errorsmall">' + required_error + '</span>');
} else if (!validateAddress($(this).val())) {
$(this).removeClass('ok-form').addClass('error-form');
$(this).parent().append('<span class="errorsmall">' + invalid_address + '</span>');
} else if (validateAddress($(this).val())) {
if (!$(this).val().match(/\d+/)) {
if (!$(this).parent().find('.warningsmall').length)
$(this).parent().append('<span class="warningsmall">' + street_number_warning + '</span>');
} else {
$(this).parent().find('.warningsmall').remove();
}
$(this).removeClass('error-form').addClass('ok-form');
}
});
Your final line in that block removes the error form class and adds the OK form class back, making the line you're trying to add essentially a no-op:
else if (validateAddress($(this).val())) {
if (!$(this).val().match(/\d+/)) {
// we try swapping classes
$(this).removeClass('ok-form').addClass('error-form');
if (!$(this).parent().find('.warningsmall').length)
$(this).parent().append('<span class="warningsmall">' + street_number_warning + '</span>');
} else {
$(this).parent().find('.warningsmall').remove();
}
// this line undoes the class changes
$(this).removeClass('error-form').addClass('ok-form');
}
In fact, if you step through your code in the debugger, you'll see the class switches, and then switches back when it reaches the end of the block.
If you're not familiar using the debugger, I highly recommend looking into it, as it can be a great help when facing problems such as this one:
Chrome Debugger guide: https://developers.google.com/web/tools/chrome-devtools/javascript (specifically, look into the "Pause in Debugger" section)
There are many ways you could solve this. One way would be to keep a boolean around in that block, and then set the classes according to its value at the end:
else if (validateAddress($(this).val())) {
let isErrorState = false;
if (!$(this).val().match(/\d+/)) {
isErrorState = true;
if (!$(this).parent().find('.warningsmall').length)
$(this).parent().append('<span class="warningsmall">' + street_number_warning + '</span>');
} else {
$(this).parent().find('.warningsmall').remove();
}
// swap classes
if (isErrorState) {
$(this).removeClass('ok-form').addClass('error-form');
}
else {
$(this).removeClass('error-form').addClass('ok-form');
}
}
Related
I'm trying to find a better way to write a piece of jQuery but I couldn't figure it out on my own.
$('.ajaxButton').click(function(event) {
event.preventDefault();
var button = $(this).data('button');
var action = $(this).data('buttonaction');
var target = $(this).data('buttontarget');
// The following code needs a rewrite
if (action === 'fadeIn') {
$(target).fadeIn();
} else if (action === 'slideDown') {
$(target).slideDown();
} else if (action === 'fadeToggle') {
$(target).fadeToggle();
} else if (action === 'slideToggle') {
$(target).slideToggle();
} else {
console.log('Action not found for ' + button + ' button.');
}
});
In order to avoid having to write the same code over and over again, I wrote the above JS for buttons I create in my web application. The above code works with the following anchor:
<a href="#"
class="button ajaxButton"
data-button="showForm"
data-buttonaction="slideToggle"
data-buttontarget=".showForm" >...</a>
What I have been trying to figure out is if there is a better way to write the following piece of code:
if (action === 'fadeIn') {
$(target).fadeIn();
} else if (action === 'slideDown') {
$(target).slideDown();
} else if (action === 'fadeToggle') {
$(target).fadeToggle();
} else if (action === 'slideToggle') {
$(target).slideToggle();
} else {
console.log('Action not found for ' + button + ' button.');
}
I would like to avoid the use of if: else statements. My first instinct was to have some sort of array that contains all possible actions. From there, I conduct a simple if action is in array do....
var actionArray = new Array('fadeIn', 'slideDown'...);
if ($.inArray(action, actionArray)) {
$(target).action();
}
But I have no idea how to create the function. Can I call functions based on array values? Or can I convert strings to functions? I think the closest I could find was to use the eval() function.
Is there a better way to do this? Or will I have to use if else statements?
You can target a property within an object using bracket notation (obj['prop']) instead of dot notation (obj.prop). So you can do something like this:
const validActions = ['fadeIn', 'slideDown'];
function doSomethingWithTarget(target, something) {
if (validActions.includes(something)) {
target[something]();
}
}
doSomethingWithTarget($('#element'), 'slideDown'); // $('#element').slideDown();
More info:
Working with objects #MDN, Property accessors #MDN
Here's my attempt :
$('.ajaxButton').click(event => {
event.preventDefault();
let $this = $(this),
button = $this.data('button'),
action = $this.data('buttonaction'),
$target = $($this.data('buttontarget'));
try {
$target[action]();
} catch (error) {
console.log('Action not found for ' + button + ' button.');
}
});
target.fadeIn can also be written target["fadeIn"]. If it is a function, you can then call it the same way : target.fadeIn() or target["fadeIn"](). Then the argument can be dynamic (variable) : target[action]()
What you can do is check of the function excist for the target, and if so execute it.
$('.ajaxButton').click(function(event) {
event.preventDefault();
var button = $(this).data('button');
var action = $(this).data('buttonaction');
var target = $(this).data('buttontarget');
//check if the function excist for target object
if (typeof $(target)[action] === 'function') {
//if so execute it.
$(target)[action]();
} else {
console.log('function: ' + action + ' not found for target: ' + target);
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
testbutton
<div class="showForm">test toggle div</div>
I have two passwords input, i want my validate button to be clickable when the two inputs are the same.
reset.pug
block content
div#content.center-align
p
span#main.bold=trad.mainTitle
br
input#pass(type='password',placeholder='' + trad.textplaceholder)
input#pass(type='password',placeholder='' + trad.validpass)
button#validate(value=token) #{trad.button}
this is my ajax function
$('#validate').bind( 'click', function(e) {
let token = e.target.value
// let pass1 = $('#pass1').val()
let pass = $('#pass').val()
if (pass !== '') {
$.post('/reset-password', {'pass': pass, 'token': token}, function (res) {
console.log(res)
if (res.err) {
$('#hiddenErr').removeClass('hide')
} else {
$('#hiddenSuccess').removeClass('hide')
setTimeout(function () {
window.location = '/'
}, 10000)
}
})
} else {
console.log('wrong password')
}
})
It's not strictly speaking an error, but you're using the same id on two html elements on the same page which can lead to strange behavior. It's better to use a class when you have two elements that are similar, or use two separate id's.
With classes do this:
block content
div#content.center-align
span#main.bold=trad.mainTitle
br
input.pass(type='password',placeholder='' + trad.textplaceholder)
input.pass(type='password',placeholder='' + trad.validpass)
button#validate(value=token) #{trad.button}
script.
function isMatchingPassword(){
var passwords = [];
$('.pass').each(function(index, element){
passwords.push( $(element).val() );
});
if( passwords[0] === passwords[1] ){
return true;
} else {
return false;
}
}
With id's do this:
block content
div#content.center-align
span#main.bold=trad.mainTitle
br
input#pass1(type='password',placeholder='' + trad.textplaceholder)
input#pass2(type='password',placeholder='' + trad.validpass)
button#validate(value=token) #{trad.button}
script.
function isMatchingPassword(){
if( $('#pass1').val() === $('#pass2').val() ){
return true;
} else {
return false;
}
}
The id solution is easier of course, but it doesn't scale very well past two or three elements.
You can subsribe to the 'input' event for the two input boxes, like this:
$('#pass, #pass1').on('input', function()
{
$('#validate').prop('disabled') = $('#pass').val() != $('#pass1').val();
});
Now , when user types in either of the boxes, the '#validate' button will be disabled, if the two values differ.
My fiddle
I have this fiddle. I want to use if else inside the filter function like this. The one I have works but the loop doesn't seem to break. Since it doesn't break, the else part is printed for all the not filtered conditions. How to break this loop? Or any better idea for this?
I have two textboxes and a button, when I enter caption and qty and hit add, I want to check if it already exists on the table. If it exists I want to replace the qty to new value. If it doesn't exists I want to add new row with new caption and qty. The checking of existence is mystery for me doesn't work at all.
$('#btnAdd').click(function () {
debugger;
UOMCaption = $('#UOMCaption').val();
UOMQty = $('#UOMQuantity').val();
$("#tbluom tr td:first-child").filter(function () {
if ($(this).text().indexOf(UOMCaption) > -1) {
$(this).next("td").text("found it");
}
else {
$('#tbluom >tbody').append('<tr><td>' + UOMCaption + '</td><td>' + UOMQty + '</td></tr>');
}
});
$('#UOMCaption,#UOMQuantity').val("");
});
If you want the looping to break after first match then use
$("#tbluom tr td:first-child").each(function () {
if ($(this).text().indexOf(UOMCaption) > -1) {
$(this).next("td").text("found it");
return false;
} else {
$('#tbluom >tbody').append('<tr><td>' + UOMCaption + '</td><td>' + UOMQty + '</td></tr>');
}
});
I am trying to use the jQuery Credit Card Validator to validate credit cards.
The basic usage is given as
$('#cc_number').validateCreditCard(function(result)
{
alert('CC type: ' + result.card_type.name
+ '\nLength validation: ' + result.length_valid
+ '\nLuhn validation: + result.luhn_valid');
});
I looked on the demo JS file included on that site and couldn't make head nor tail.
What I am trying to achieve is onkeyup of input, do something depending on what card type is caught:
//on key up of input
if (card == valid)
{
if (card == visa)
{
//do something
}
else if (card == mastercard)
{
//do something
}
// repeat for rest of card types
}
else
{
//Just print an error
}
I know it's fairly basic stuff, but can anybody help me with how to achieve?
my HTML:
<input type="text" id="cc_number" />
Developer of jQuery Credit Card Validator here.
jCCV binds the keyup event so you don’t need to do it. (actually it’s a little more complicated than that — all you need to know is that every time the value of the field changes, your callback function is executed).
$('#cc_number').validateCreditCard(function(result)
{
// this will execute everytime the value of the `#cc_number` field changes
if (result.length_valid && result.luhn_valid) {
if (result.card_type.name == 'visa') {
// do something
} else if (result.card_type.name == 'mastercard') {
// do something
}
// repeat for rest of card types
} else {
// just print an error
}
});
try something like this:
$("#cc_number").on("keyup", function() {
$(this).validateCreditCard(function(result) {
alert('CC type: ' + result.card_type.name
+ '\nLength validation: ' + result.length_valid
+ '\nLuhn validation: ' + result.luhn_valid);
});
if (result.card_type.name) {
if (result.card_type.name == visa)
{
//do something
}
else if (result.card_type.name == mastercard)
{
//do something
}
// repeat for rest of card types
}
else {
//Just print an error
}
});
Use this one by Stripe: https://github.com/stripe/jquery.payment
Much better.
I have listview with two checkboxes in itemtemplate.
I want to validate that user can only select only one checkbox in each row.
The behaviour you're describing is accomplished using standard HTML radiobuttons. If you change your design to use these you'll get the benefit that
The user can only select a single item, no extra javascript needed
Users expect to be able to choose multiple checkboxes but only a single radiobutton IE you're working with their expectations
If you're still sure you want to use jQuery then something like this should do it.
$(':checkbox').change(function(){
if($(this).attr('checked')) {
$(this).siblings(':checkbox').attr('checked',false);
}
});
#vinit,
just a little change, you forgot the else part,
$('input:checkbox[id*=EmailCheckBox]').click(uncheckOthercheckbox);
$('input:checkbox[id*=SMSCheckBox]').click(uncheckOthercheckbox);
function uncheckOthercheckbox() {
if (this.id.indexOf("EmailCheckBox") != -1) {
var otherCheckBoxId = this.id.substring(0, this.id.indexOf("EmailCheckBox")) + "SMSCheckBox";
}
else {
var otherCheckBoxId = this.id.substring(0, this.id.indexOf("SMSCheckBox")) + "EmailCheckBox";
}
var i = "#" + otherCheckBoxId;
if (this.checked) {
$(i).removeAttr('checked');
}
else {
if ($(i).attr('checked') === false) {
$(i).attr('checked', 'checked');
}
}
}
Thanks for the reply. had also asked one of my friend and he gave me the following solution which is working fine. Posting it, if anybody needs it.-
say ur checkboxes in the 2 clumns are named EmailCheckBox and SMSCheckBox
then use this code to toggle the checkboxes in each single row:
$('input:checkbox[id*=EmailCheckBox]').click(uncheckOthercheckbox);
$('input:checkbox[id*=SMSCheckBox]').click(uncheckOthercheckbox);
function uncheckOthercheckbox() {
if (this.id.indexOf("EmailCheckBox") != -1) {
var otherCheckBoxId = this.id.substring(0, this.id.indexOf("EmailCheckBox")) + "SMSCheckBox";
}
else {
var otherCheckBoxId = this.id.substring(0, this.id.indexOf("SMSCheckBox")) + "EmailCheckBox";
}
var i = "#" + otherCheckBoxId;
if (this.checked) {
$(i).removeAttr('checked');
}
}