Have function called based on default dropdown selection - javascript

I am trying to redirect a customer to another page using Javascript, if a country other than the US is chosen in a dropdown field. I got it to work, but registered guests have their country default in the dropdown and the function doesn't get called unless the user switches it.
This is the code as it stands now
$(document).ready(function(){
var una = "ok";
$("#shipping-country").change(function(event){
if(($("#shipping-country").val() != "US") &&(una=="ok")){
iCheckout.insertForm();
$("#iCheckoutForm").submit();
}
});
});
How can I rewrite this to have it redirect if a country other than the US is already chosen by default?

It seems you want to check whether their default value is not the US on page load as well as when the value of the dropdown changes?
I'd refactor it a bit:
$(document).ready(function(){
var una = "ok";
var checkIfUS = function() {
if(($("#shipping-country").val() != "US") &&(una=="ok")){
iCheckout.insertForm();
$("#iCheckoutForm").submit();
}
};
checkIfUS(); // check if it should redirect after dom load
$("#shipping-country").change(function(event){
checkIfUS(); // check if it should redirect on form change
});
});
Alternatively, if you're populating the dropdown with javascript, you can add checkIfUS() as a callback to whatever populates the dropdown.

like this
$(document).ready(function(){
var una = "ok";
$("#shipping-country").change(function(event){
if(($("#shipping-country").val() != "US") &&(una=="ok")){
iCheckout.insertForm();
$("#iCheckoutForm").submit();
}
});
if ($("#shipping-country").val() != 'US') {
// your redirect code here
window.location.replace("http://stackoverflow.com");
}
});

Related

Multiple Javascript Event Listener Issues

Background info: I'm using WooCommerce and Gravity Forms, and trying to make it so the Add to Cart button is inactive according to two conditions - either there are no attendees registered, or the date hasn't been selected from the product variation dropdown. The user should only be able to move forward if both sections are completed.
The Gravity Forms component of this has a popup module to sign up those attendees, but the summary is displayed outside the module and on the main product page. The class .gpnf-no-entries lives on the "outside" of the Gravity Forms module, since it's always visible on the page. .gpnf-nested-entries and .gpnf-row-actions are also outside the module, but rely on information from within the module. .tingle-btn is a class used on multiple buttons inside the module - to add an attendee, cancel editing, or delete that attendee (unsure if I need a loop on here - alerts were working without one, and it seems like there's something else causing issues regardless).
Issues: It was working at one point, but only after the second click (anywhere on the page). There's also a second issue - on this form, if you've added an attendee but not added the product to the cart, the page retains any info you've put in. So what happens is, if you refresh the page and have old attendee info already there, the Add to Cart never gets clickable after selecting a date, even though both areas are filled out.
Screenshots:
I'm still somewhat of a beginner here so it's quite possibly something silly.
<script>
var modalButtons = document.querySelectorAll('.tingle-btn');
var noEntries = document.querySelector('.gform_body .gpnf-no-entries');
var entryField = document.querySelectorAll(".gpnf-nested-entries .entry-field[style='display: block;']");
var nestedEntriesDelete = document.querySelector('.gpnf-row-actions .delete');
var addToCart = document.querySelector('.single_add_to_cart_button');
var wcVariation = document.querySelector('.woocommerce-variation-add-to-cart');
var selectCheck = document.querySelector('#select-date-option');
//When date selection dropdown is changed, check value and check for "no entries" message
document.addEventListener('change', function (event) {
if (!event.target.matches('selectCheck')) {
if ((noEntries.style.display !== 'none') || (selectCheck.value === '')) {
addToCart.classList.add('disabled');
wcVariation.classList.remove('woocommerce-variation-add-to-cart-enabled');
wcVariation.classList.add('woocommerce-variation-add-to-cart-disabled');
}
else {
addToCart.classList.remove('disabled');
wcVariation.classList.add('woocommerce-variation-add-to-cart-enabled');
wcVariation.classList.remove('woocommerce-variation-add-to-cart-disabled');
}
}
}, false);
// When attendee is deleted, check to see if there are any entry fields left
document.addEventListener('click', function (event) {
if (!event.target.matches('nestedEntriesDelete')) {
if (entryField.length <= 3) {
addToCart.classList.add('disabled');
wcVariation.classList.remove('woocommerce-variation-add-to-cart-enabled');
wcVariation.classList.add('woocommerce-variation-add-to-cart-disabled');
}
}
}, false);
// Check for "no entries" and no date selection value when buttons to add or remove attendees are clicked
document.addEventListener('click', function (event) {
if (!event.target.matches('modalButtons')) {
if ((noEntries.style.display !== 'none') || (selectCheck.value === '')) {
addToCart.classList.add('disabled');
wcVariation.classList.remove('woocommerce-variation-add-to-cart-enabled');
wcVariation.classList.add('woocommerce-variation-add-to-cart-disabled');
}
else {
addToCart.classList.remove('disabled');
wcVariation.classList.add('woocommerce-variation-add-to-cart-enabled');
wcVariation.classList.remove('woocommerce-variation-add-to-cart-disabled');
}
}
}, false);
</script>
I ended up doing this a much simpler way by adding classes:
<script>
var noEntries = document.querySelector('.gform_body .gpnf-no-entries');
var entriesContainer = document.querySelector('.gpnf-nested-entries-container');
var addToCart = document.querySelector('.single_add_to_cart_button');
//When page is fully loaded, check for cached entries
window.addEventListener('load', function () {
//if there are entries, show the add to cart button
if (noEntries.style.display === 'none'){
entriesContainer.classList.add('has-entries');
addToCart.classList.add('do-add');
addToCart.classList.remove('dont-add');
}
//if there are no entries, disable the add to cart button
else if (noEntries.style.display === ''){
entriesContainer.classList.remove('has-entries');
addToCart.classList.add('dont-add');
addToCart.classList.remove('do-add');
}
//if the form isn't present, don't do any of this
else if (noEntries = 'null'){
//do nothing
}
});
//When the container with the form and the entries is clicked, check for entries
document.addEventListener('click', function (event) {
if (!event.target.matches('#gform_wrapper_41')) {
setInterval(function() {
//if an entry is added, show the add to cart button
if (noEntries.style.display === 'none'){
entriesContainer.classList.add('has-entries');
addToCart.classList.add('do-add');
addToCart.classList.remove('dont-add');
}
//if all entries are removed, disable the add to cart button
else if (noEntries.style.display === ''){
entriesContainer.classList.remove('has-entries');
addToCart.classList.add('dont-add');
addToCart.classList.remove('do-add');
}
},2000);
}
}, false);
</script>

Prevent Select from changing selected option if condition is not met

I have a select box. Currently, this select box make an ajax call on change.
Now, I want to make call only when a condition is met.
So, here is my code:
$('#buildingSelect').on('change', function(){
var result = checkDirtyStatus();
//this checkDirtyStatus alert message if there is some changes on the form.
//if cancel return false, if confirm return true.
if(result === false) {
return;
}
//make ajax call
});
This prevents from making ajax call, however, this change the selected option of the select i.e, if option1 is selected at the begining and if I try to select next option then it will change the selected option to option2 then only check the status.
On searching on the internet, I got the option of focusin.
$('#buildingSelect').on('focusin', function(){
// console.log("Saving value " + $(this).val());
var result = checkDirtyStatus();
if(result === false) {
return;
}
}).on('change', function(){
g_building_id = $(this).val();
getAmenitiesDetails(g_building_id);
});
However, using this focusin options makes the alert box to appear everytime no matter either I click cancel or ok. This might be because, it call focusin again whenevr I click Ok or Cancel.
What would be the best option to check this status, and if result is false, I don't want to change the selected option as well.
Update
Answer from marked as duplicate not preventing from changing the selected option. Its making ajax call on click i.e. before checking condition.
CodePen Link
function checkDirtyStatus(){
dirtyStatus = true;
if(dirtyStatus === true){
if (confirm("Changes you made may not be saved.")) {
return true;
}else{
return false;
}
}
}
Finally, by mixing the link from Rory and idea of organizing code from some. I have find a solution for my problem. So, if anyone got stuck on the similar problem here is my solution.
$(function(){
var lastSel;
$('#buildingSelect').on('focusin', function(){
lastSel = $("#buildingSelect option:selected");
}).on('change', function(){
if(!checkDirtyStatus()) {
lastSel.prop("selected", true);
return;
}else{
//made ajax call
//$.ajax({})
}
});
});
function checkDirtyStatus(){
let dirtyStatus = getDirtyStatus();
if(dirtyStatus){
return confirm("Changes you made may not be saved.");
}
return true;
}
Let us look at your function:
function checkDirtyStatus(){
dirtyStatus = true; // I assume this is only for testing
if(dirtyStatus === true){ // This can be simplified.
if (confirm("Changes you made may not be saved.")) {
return true;
}else{
return false;
}
}
}
confirm returns a Boolean that is either true or false, so you can simplify your function like this:
function checkDirtyStatus(){
dirtyStatus = true;
if(dirtyStatus){
return confirm("Changes you made may not be saved.");
}
// Notice that you do not return anything here. That means that
// the function will return undefined.
}
Your other function can be simplified like this:
$('#buildingSelect').on('change', function(){
if(!checkDirtyStatus()){
// Here you probably want to set the value of the select-element to the
// last valid state. I don't know if you have saved it somewhere.
return;
}
//make ajax call
});
I played with your codepen and you have some errors in your selectors. As I get confused by your explanation I will try to explain what you could update and how to use it in your code and I hope this is what you need to solve your problem.
First I would change your js to this:
var lastSel = $("#buildingSelect").val();
$("#buildingSelect").on("change", function(){
if ($(this).val()==="2") {
$(this).val(lastSel);
return false;
}
});
The proper way to get the value of a select box in jquery is with the .val(). In your case you selected the entire selected option element.
I store this value in the lastSel variable. Then in the change function the new value of the select list is $(this).val(). I check against this value and if it equals 2 I revert it to the value stored in the lastSel variable with this $(this).val(lastSel).
Keep in mind that the value of a select list is always a string, if you want to check against a number you must first cast it to a numeric value e.g. by using parseInt.
If you want to use the checkDirtyStatus for the check then you should only call this function in the change and pass as parameters the lastSel and the newSel like this:
$("#buildingSelect").on("change", function(){
checkDirtyStatus(lastSel, $(this).val());
});
Then you can transfer the logic from the change function into the checkDirtyStatus function and do your checks there. In this case if you wish to revert the select value instead of $(this).val(lastSel) you will do a $("#buildingSelect").val(lastSel).
I hope this helps.

jquery code working but not the first time

I'm trying to build a small login system using jquery (since it is for testing purposes only and the user and password won't change) So i made a form and when you click the button i test whether the details are correct. if so you will get send to the next page. If not i give an alert.
It's working but i have something weird. The first time you visit the site and fill in the details it does nothing. The second time (after submitting) it works like it should.
Does someone know why?
Here is the code:
function controllogin() {
event.preventDefault();
var username = $("#gebruikersnaam").val()
var password = $("#wachtwoord").val()
if (username=="leerkrachten" && password=="leerkrachten") {
alert("welkom leerkrachten");
goToUrl();
}
else if (username=="leerling" && password=="leerling") {
alert("welkom leerling");
}
else {
alert("verkeerde gegevens ingevuld");
}
};
function goToUrl() {
alert("zoeken naar pagina");
window.location = 'leerkrachten/vakken.html';
};
Instead of onclick="controllogin();" try something like this:
$('document').ready(function() {
$('#submit').click(function(event) {
event.preventDefault();
var username = $("#gebruikersnaam").val()
var password = $("#wachtwoord").val()
if (username==="leerkrachten" && password==="leerkrachten") {
alert("welkom leerkrachten");
goToUrl();
}
else if (username==="leerling" && password==="leerling") {
alert("welkom leerling");
}
else {
alert("verkeerde gegevens ingevuld");
}
});
});
Also use === instead of == as operators to compare the strings, it prevents you from some weird results when comparing different types. Maybe that's why it doesn't work the first time, but does the second time. Otherwise I don't know why this happens.
But actually I'd have to say: NEVER do client-side login validation and NEVER do login validation with an unencrypted password (not even server-side)!

Using Blur and Submit events on the same form

I am still confused about this. Started learning JQuery about a week now and this is what I have:
var IsValidUserName = false;
$(document).ready(function () {
$('#txtUserName').blur(function () {
if ($('#txtUserName').val().match(isNumberLetter) &&
($('#txtUserName').val().length >= 8)) {
$('#userNameError').removeClass("error").addClass("default");
$('#txtUserName').removeClass("alert");
$('#txtUserName + label').removeAttr("id", "lblUserName");
IsValidUserName = true;
}
else {
$('#userNameError').removeClass("default").addClass("error");
$('#txtUserName').addClass("alert");
$('#txtUserName + label').attr("id", "lblUserName");
}
});
});
Lets say I have another function like above, lets say FirstName:
How do I call this on the submit event? The code works as I need it to when the user leaves a field. Not sure how I can also call this code and also use the variable above to prevent submit if the data entered is invalid.
I need to call the validation above if the user clicks the submit button and stop the submission if the IsValidUserName variable is false.
Somethings just need a little push.
Thanks my friends.
Guy
You could always extract it into a function instead of an anonymous function and pass the reference to the object you want to check. This would give you the added benefit of reusing it for other elements.
function validate(ele) {
var valid;
if (ele.val().match(isNumberLetter)) && (ele.val().length >= 8)) {
valid = true;
// update user here.
} else {
valid = false;
// update user here.
}
return valid;
}
$(function(){
$('#firstName').blur(function(){ validate($(this)); });
$('#lastName').blur(function(){ validate($(this)); });
$("yourFrom").submit(function(){
var firstNameIsValid = validate($('#firstName'));
var lastNameIsValid = validate($('#lastName'));
if (!nameIsValid) && (!lastNameIsValid) {
return false;
// User has already been updated
}
});
});
Also, since you are already heavily using javascript for your validation (hope this is convenience and not the only security), you can also disable the submit button entirely until the form meets the proper requirements.

How to Listen for Upload Finished with jQuery in WordPress Thickbox Upload Window?

I'm injecting some jQuery to make the Alt Text field required in WordPress upload thick box.
It intercepts the Insert into Post button click and checks if the field has been filled or not.
It works ok for the Gallery and Media Library tabs, but the From Computer tab needs a needs a "listener" when an upload finishes to alter the behavior of the Insert into Post button.
I was trying with setInterval, but don't know how to kill or recreate it, but maybe someone is aware if a listener exists, or even how to make this code work because I suspect my logic here is fuzzy...
Here's the code, commented.
add_action('admin_head-media-upload-popup','so_11149675_required_alt_text');
function so_11149675_required_alt_text()
{
// Detect current tab ("From Computer" == "type")
$tab = isset($_GET['tab']) ? $_GET['tab'] : "type";
// ( 'From Computer' or ( 'Gallery' and 'Library' ) )
$jquery = ('type' == $tab) ? 'var refreshUpload = setInterval(function(){$(".savesend input").each(checkAltTextPermanent);},500);' : '$(".savesend input").each(checkAltTextOnce);';
echo <<<HTML
<script language="javascript" type="text/javascript">
// var refreshUpload; /* testing */
// Function called by From Computer tab
// should run only once -> when the upload table and fields are created
function checkAltTextPermanent() {
// Create the required asterisk symbol
// setInterval creates a loop here
jQuery('.image_alt th label').each(function(i,e) {
jQuery('<span class="alignright"><abbr title="required" class="required">*</abbr></span>').prependTo(this);
});
// Alter button behavior
// Another loop in the alert box
jQuery(this).click(function(e) {
// clearInterval(refreshUpload);
var value = jQuery(this).parent().parent().parent().find('.image_alt input').val();
if('' != value)
return true;
alert ('Please fill the Alt text');
return false;
});
}
// Function called by Gallery and Library tabs
function checkAltTextOnce() {
jQuery(this).click(function(e) {
var value = jQuery(this).parent().parent().parent().find('.image_alt input').val();
if('' != value)
return true;
alert ('Please fill the Alt text');
return false;
});
}
jQuery(document).ready(function($) {
// Defined in PHP, calls checkAltTextOnce or checkAltTextPermanent
{$jquery}
// Used in Gallery and Libray tabs
$('.image_alt th label').each(function(i,e) {
$('<span class="alignright"><abbr title="required" class="required">*</abbr></span>').prependTo(this);
});
});
</script>
HTML;
}
Try this:
jQuery(".savesend input").live("click", validateAltText);
function validateAltText() {
var value = $(".image_alt input").val();
if (value)
return true;
alert('Please fill the Alt text');
return false;
}

Categories