JavaScript to check for event without page refresh - javascript

I could use a point in the right direction. I have a product that I am showing on a cart page for charity donations. If someone adds the donation to their cart I have been able to remove the donation option since it is now already in the cart. This is done because when a donation button is clicked the page is refreshed and the donation added to the cart. The problem I am having is when someone removes the donation from the cart the page does not refresh and therefor the option to donate does not show up until I manually refresh the page. I would post some code but I dont have any because I am not sure how I go about the page looking at the cart basically in a loop to keep checking if that item in the cart or not.
This is the code I use to check and see if the donation is in the cart.
$(document).ready(function() {
var found = false;
$('.bd a').each(function(index, ele){
if($(ele).html().indexOf('Charity Bucks') > -1){
found = true;
}
})
if(found){
$('#divID').css('display','none');
}
});

from this stack
this is event listener for changes at element with class .bd
$("body").on('DOMSubtreeModified', ".bd", function() {
// code here
});
try add this code :
$("body").on('DOMSubtreeModified', ".bd", function() {
$('.bd a').each(function(index, ele){
if($(ele).html().indexOf('Charity Bucks') > -1){
$('#divID').css('display','none');//or inline-block; or block; as your default css for this element
}else{
$('#divID').css('display','inline');
}
})
});

I ended up using a callback to solve my problem
<script>
$(document).ready(function() {
var found = false;
$('.bd a').each(function(index, ele){
if($(ele).html().indexOf('Charity Bucks') > -1){
found = true;
var parent = $(ele).parent().parent();
var sibs = $(parent).siblings('.group4');
$(sibs).find('a').each(function(index2, ele2){
console.log(ele2);
if($(ele2).html().indexOf('remove') > -1){
console.log('found it');
$(ele2).on('click', function(){
$('#divID').show();
});
}
});
}
})
if(found){
$('#divID').hide();
}
});
</script>

The issue is due to a missing else statement. In your logic you only modify the #divID element if you find the charity entry, but not if you no-longer find the charity entry and have already hidden the element.
Additionally I would recomend showing/hiding the element via a css class rather than directly though css properties.
$(document).ready(function() {
$('#remove-donation-button').click(removeDonation());
var found = false;
$('.bd a').each(function(index, ele){
if($(ele).html().indexOf('Charity Bucks') > -1){
found = true;
}
})
if(found){
$('#divID').addClass("hide-charity");
}
});
function removeDonation(){
$('.hide-charity').removeClass('hide-charity');
/** Actually remove */
}

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>

Prefill checkbox via link and preserve form function

I currently have a form i built that is 3 large check boxes, when selected they toggle the continue button below them, https://staging-homecarepulse.kinsta.cloud/demo-select/ this is the link so you can check it out.
Currently im trying to add functionality to the form that when you click a link from another page, it preselects the checkbox depending on the link selected.
I was able to find a script that allows me to setup a link with a hash ( https://staging-homecarepulse.kinsta.cloud/demo-select/#checkbox1 ) but my issue is that I cannot get the continue button to trigger when the form is accessed this way.
here is my code
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script>
$(document).ready(function(){
var hash = location.hash;
if(hash=="#checkbox1"){
$("#checkbox1").prop("checked", !$("#checkbox1").prop("checked") ); // that toggles the checked state
}
});
</script>
<script>
$(document).on("change", ".mod-link", function() {
var arr = []
$(".mod-link:checked").each(function() {
arr.push($(this).val());
})
if (arr.length > 0) {
$('#picture').attr('src', '');
} else {
$('#picture').attr('src', 'https://staging-homecarepulse.kinsta.cloud/wp-content/uploads/2021/06/greyBTN.jpg');
}
var vals = arr.join(",")
var str = "/demo/?demo_request_type=" + vals;
var link = arr.length > 0 ? '<a class="dynabtn" href="'+str+'">Continue</a>': '' ;
$('.link-container').html(link);
});
</script>
anyone have any idea how i can use links like https://staging-homecarepulse.kinsta.cloud/demo-select/#checkbox1 to trigger that checkbox and still have the continue button toggle on?
Instead of trying to toggle the checked property, fire a click event on your checkbox.
$(document).ready(function() {
if (location.hash) {
let $checkbox = $(location.hash);
if ($checkbox.length) $checkbox.click();
}
});
Your Continue button will toggle as well.

why the array reinitialized on every click?

I'm trying to push some numbers to an array, and then I want to assign the array to a hidden input to posted with a form.
On each click I am pushing a value to the array, but the array seems to be reinitialized on each click, so it stores the last pushed value only.
The full scenario:
open a popup modal contains a form (form loaded by ajax).
select a category, then the category items will be loaded by ajax too. (the shared code below is in this page).
click an item to get the full item details by ajax and load them in a div, and push the item ID to the array.
the array that stored the chosen items IDs will be assigned to a hidden input element.
So if the user choose another category, the items page will be reloaded, and this is the reason why the array is reinitialized each time.
$(document).ready(function(){
var added_items = [];
$('.items-list .one-item').click(function(e){
e.preventDefault();
if(added_items.indexOf($(this).attr('href')) < 0){
ajaxLoad('<?=Yii::$app->urlManager->createUrl('bookings/item'); ?>', $('.added-items'), {item:$(this).attr('href')}, true);
added_items.push($(this).attr('href'));
$('#added-items-list').val(JSON.stringify(added_items));
}
else{
alert("item already exist");
}
});
});
So how I can save the items IDs and post them with the form.
Three possible reasons
1.) form reloads page
2). if(added_items.indexOf($(this).attr("href")) < 0) returns false
3). Single .one-item element having $(this).attr("href"), see 2)
Utiltizing localStorage ; note, untested
$(document).ready(function() {
var added_items = localStorage.getItem("items") || [] ;
$('.items-list .one-item').click(function(e) {
e.preventDefault();
if (typeof added_items === "string") {
added_items = JSON.parse(added_items);
}
if (added_items.indexOf($(this).attr('href')) < 0) {
added_items.push($(this).attr('href'));
localStorage.setItem("items", JSON.stringify(added_items));
// note, not certain if page reloads here ?
// should $('#added-items-list').val(localStorage.getItem("items"));
// be called before `ajaxLoad` ?
ajaxLoad('<?=Yii::$app->urlManager->createUrl('
bookings / item '); ?>', $('.added-items'), {
item: $(this).attr('href')
}, true);
$('#added-items-list').val(localStorage.getItem("items"));
} else {
alert("item already exist");
}
});
});
Your code:
$(document).ready(function(){
var added_items = [];
...
}
seems located inside ajax loaded content so this code run every ajax call.
Your should move at least var added_items = []; outside of ajax reloaded content.
what I did (tested and worked successfully):
the form page :
$(document).ready(function(){
localStorage.clear();
...
$('form').on('submit', function(){
$('#added-items-list').val(JSON.stringify(localStorage["added_items"]));
});
});
the items page:
$(document).ready(function(){
var added_items = [];
if(localStorage.getItem("added_items")===null){
localStorage["added_items"] = JSON.stringify(added_items);
}
else {
// Parse the serialized data back into an array of objects
added_items = JSON.parse(localStorage.getItem('added_items'));
}
$('.items-list .one-item').click(function(e){
e.preventDefault();
if(added_items.indexOf($(this).attr('href')) < 0){
added_items.push($(this).attr('href'));
localStorage.setItem('added_items', JSON.stringify(added_items));
}
else{
alert("item already exist");
}
});

IE click event span not triggered

I'm having this webpage
http://pocolocoadventures.be/reizen/
And it should filter (with isotope.js) the travelboxes on the page.It does in safari, chrome, firefox, opera, .. but in IE, the filter doesn't work. Even worse, JS doesn't react at all at a click event on te span.
This is the piece of js
// Travel Isotope
var container = $('#travel-wrap');
container.isotope({
animationEngine : 'best-available',
itemSelector: '.travel-box ',
animationOptions : {
duration : 200,
queue : false
},
});
$(".filters span").click(function(){
var elfilters = $(this).parents().eq(1);
if( (elfilters.attr("id") == "alleReizen") && elfilters.hasClass("non-active") )
{
$(".label").each(function(){
inActive( $(this) );
});
setActive(elfilters);
}
else{
//set label alleReizen inactive
inActive( $("#alleReizen") );
if( elfilters.hasClass("non-active") ){
setActive(elfilters);
}
else{
inActive(elfilters);
}
}
checkFilter();
var filters=[];
$(".search.filters").children().each(function(){
var filter = $(this).children().children().attr("data-filter");
if( $(this).hasClass("non-active") ){
filters = jQuery.grep(filters, function(value){
return value != filter;
});
}
else{
if(jQuery.inArray(filter,filters) == -1){
filters.push(filter);
}
}
});
filters = filters.join("");
filterItems(filters);
});
function filterItems(filters){
console.log("filter items with filters:" + filters);
container.isotope({
filter : filters,
}, function noResultsCheck(){
var numItems = $('.travel-box:not(.isotope-hidden)').length;
if (numItems == 0) {
$("#no-results").fadeIn();
$("#no-results").css("display", "block");
}
else{
$("#no-results").fadeOut();
$("#no-results").css("display", "none");
}
});
}
function setActive(el){
el.removeClass("non-active");
var span = el.find('i');
span.removeClass("fa-check-circle-o").addClass("fa-ban");
}
function inActive(el){
el.addClass("non-active");
var span = el.find('i');
span.removeClass("fa-ban").addClass("fa-check-circle-o")
}
function checkFilter(){
var filterdivs = $('.filters span').parent().parent();
if( filterdivs.not('.non-active').length == 0 ){
setActive( $("#alleReizen") );
}
var filterLabels = $(".filters .label");
if( filterLabels.not('.non-active').length == 0){
setActive( $("#alleReizen") );
}
}
function noResultsCheck() {
var numItems = $('.item:not(.isotope-hidden)').length;
if (numItems == 0) {
//do something here, like turn on a div, or insert a msg with jQuery's .html() function
alert("There are no results");
}
}
Probably something small and stupid; but I can't find it..
Thanks in advance!
On your website you've build the buttons like this:
<button>
<span>
</span>
</button>
Now the button element is designed to be a button. It differs from the input button. In the latter you'd set the caption using value. In the button element you set it as a text node. The button element can contain elements like a span. The spec isn't very clear about whether or not you should have event handlers on the children of the button element. It's a browser developers interpretation of allowing it or not.
This problem has been posted here before (a few times)
span inside button, is not clickable in ff
Missing click event for <span> inside <button> element on firefox
It seems that Firefox is allowing it, based upon your findings. IE isn't. So to be on the safe side: use the button the way it was intended.
Wrap the button inside a span (not really logical)
Put the click handler on the button.
$(".filters button").click(...);
played around in the console a bit, and this seemed to work well.
$(".filters").on('click', 'span', function(){
// foo here
console.log('foo');
});
Maybe the filters are manipulated by one of your js files after page load?
.on will allow you to select a container which listens on changes that happen inside it, passing the element you want the actual action to work on.
If it's ok for you, I'd suggest to use the <button> element, instead of the <span>.
Let me know if that works for you.

JS executing only once for first div

i have js which execute only for first div (#addcommentform), if i put more forms on one page = the problem
how to get js working for every form on page?
Thank you
$(function(){
var working = false;
$('#addCommentForm').submit(function(e){
e.preventDefault();
if(working) return false;
working = true;
$('#submit').val('Working..');
$('span.error').remove();
$.post('submit.php',$(this).serialize(),function(msg){
working = false;
$('#submit').val('Submit');
if(msg.status){
$(msg.html).hide().insertBefore('#addCommentContainer').slideDown();
$('#body').val('');
}
else {
$.each(msg.errors,function(k,v){
$('label[for='+k+']').append('<span class="error">'+v+'</span>');
});
}
},'json');
});
})
Instead of giving the divs IDs of "addCommentForm", set their classes to "addCommentForm". Then change your code to use the class selector .addCommentForm rather than the hashtag ID selector, i.e.:
$('.addCommentForm').submit(function(e){

Categories