I am using some simple jquery to show view cart button if something has been added to the cart.
if ( $('.cartSummaryItem').text() != 'Shopping cart is empty.' ) {
$('.account').fadeIn(1000)
};
If the cart is empty it show this the text "Shopping cart is empty.", if something is added .account will fadeIn. The problem is I need to refresh the page for this to work, is there a way to do this without refreshing the page with ajax or similar?
Thanks
Nik
If the change event doesn't work. Another method is using an Interval.
<script type='text/javascript'>
$(document).ready(function()
{
setInterval(function () {
if ( $('.cartSummaryItem').text() != 'Shopping cart is empty.' ) {
$('.account').fadeIn(1000)
};
}, 10000);
});
</script>
Ofcourse, the interval should be changed to your desired amount. I would only use this if the change doesn't work.. The change event is prefered.
Well, I guess you have two choices
Call the javascript code after the user has changed the contents of the cart
Poll the server for cart changes
If you can, you should probably go for the first choice. Are you in control of the code that changes the contents of the cart?
Related
I am using Shopify "Streamline Theme" with quick product view and I recently added infinite scroll to products on each collection using Ajaxinate.js.
When I open a collection page it loads with some products which is supposed to do, The products already there work fine with quick view and quick add to cart and also.
The Infinite scroll works fine and it loads new product fine but the problem is raised when the new products loaded through AJAX call doesn't have work with the quick view function.
I have tried to create a callback function to activate the quick view with no success, using the theme initialisation code with no success.
function callBack(){
theme.init();
theme.initQuickShop();
};
document.addEventListener("DOMContentLoaded", function() {
var endlessClick = new Ajaxinate({
method: "scroll",
loadingText: 'Loading...',
callback: callBack
});
});
Edit -------
My problem, is that when the page is loaded only the initial loaded products quickview elements are loaded in the DOM. When the scroll more button is clicked, the newly loaded products are loaded without their respective quickview elements. Hence why the quickview does't work for them. The theme.js file comes with this initialisation code:
theme.reinitProductGridItem = function($scope) {
if (AOS) {
AOS.refreshHard();
}
if (theme.settings.currenciesEnabled) {
theme.currencySwitcher.ajaxrefresh();
}
// Reload quick shop buttons
theme.initQuickShop(true);
// Refresh reviews app
if (window.SPR) {
SPR.initDomEls();SPR.loadBadges();
}
// Re-register product templates in quick view modals.
// Will not double-register.
sections.register('product-template', theme.Product, $scope);
// Re-hook up collapsible box triggers
theme.collapsibles.init();
};
I have tried to integrate this into a callback but no success, the quickview modal doesn't seem to load for the newly loaded products:
function callBack(){
ReloadSmartWishlist();
var $container = $('#CollectionSection');
theme.reinitProductGridItem($container);
// I have tried the following init qith no success:
// theme.init();
// theme.initQuickShop(true);
// theme.initQuickShop();
// sections.register('product-template', theme.Product, $container);
// AOS.refreshHard();
};
document.addEventListener("DOMContentLoaded", function() {
var endlessClick = new Ajaxinate({
method: "click",
loadingText: 'Loading...',
offset: 0,
callback: callBack
});
});
I am missing something but what? :/
Note for other things like loading products images with the callback and the wishlist app, it works as intended...
When you load elements via AJAX and if the events are not attached to a parent element that is not removed from the DOM, those elements will not have an attached event to them.
The term used here is event delegation.
Here is an example of non-delegated event:
document.querySelectorAll('a').addEventListener('click', function(){
// Do something
})
Since you are attaching the event to the existing "a" elements if you add new 'a' via AJAX those elements will not have the event since Javascript already attached all the events and it will not reattach them if you don't specifically recall them again.
Here is an example of a delegated event:
document.querySelector('body').addEventListener('click', function(target){
let target = event.target;
if (target.tagName === 'A'){
// Do something here
}
})
Where we attach the event to the body tag ( where it's a better idea to attach it to a closer none-modified parent element of the ajax items ) and once we click we check if our target tag is an "a" and do something then.
So long story short, you will need to delegate the quick cart link so that it works after you load the items via AJAX.
Drip is correct you need to delegate your event, but for people like me it's hard to completely understand how to do that.
I'm not sure how your quickview is structured, but if you open it with a .click function and can use jquery use the [.on() function][1].
For example: I use a quickview that opens on a button click. My button is attached to my product-grid-item.liquid with this bit of code:
<div class="quick-view-button">
<a class="quick-view" data-handle="{{ product.handle }}" href="javascript:void(0);">Quick View</a>
</div>
My quickview function originally looked like this:
function quickView() {
$(".quick-view").click(function () {
//all of the quickview code
What happens is exactly like you described. The event listeners only loaded on the first product load but nothing after an AJAX load.
Using jquery's .on() binds the event listener to the element meaning when it's loaded in later it'll still have the event. Here's an example of what my code looks like after using .on()
function quickView() {
$('body').on('click','.quick-view',function(){
I really hope this helps you or someone else with this problem.
[1]: http://api.jquery.com/on/
Is there a way in prestashop to show a confirmation message before an item is removed from the cart in prestashop 1.7? I'd just like to be pointed to the file that contains this method so that I may be able to add a confirm dialog, since right now a user can just delete without confirmin
Yes, you can show confirm dialog before deleting item from cart. By default core.js and theme.js file handles all events and update cart accordingly on updateCart event. (Refer more on events here)
To overcome default behaviour adding js prior to theme.js will help us to prevent default click event. Follow below mentioned step by step guide to load you own js and add confirmation dialog on item delete.
1) Register your js in theme.yml (More details here) by adding below code under assets
themes/{your_theme}/config/theme.yml
assets:
js:
cart:
- id: cart-extra-lib
path: assets/js/cart-lib.js
priority: 30
2) Create file cart-lib.js under themes/{your_theme}/assets/js and add below code into it.
themes/{your_theme}/assets/js/cart-lib.js
function refreshDataLinkAction() {
$('[data-link-action="delete-from-cart"]').each(function(){
$(this).attr('data-link-action', 'confirm-remove-item');
});
}
$(document).on('click', '[data-link-action="confirm-remove-item"]', function(e) {
e.preventDefault();
if (confirm('Are you sure you want to remove product from cart?')) {
$(this).attr('data-link-action', 'delete-from-cart');
$(this).trigger('click');
}
return false;
});
$(document).ready(function () {
refreshDataLinkAction();
prestashop.on('updatedCart', function (event) {
refreshDataLinkAction();
});
});
3) Now, to load your js file you need to delete file config/themes/{your_theme}/shop1.json (Reference)
4) Add products to cart and check cart; delete items you will see confirmation message. Attaching image for reference.
I have made a custom theme on big cartel, and everything is perfect, except one thing.
I would like to have the cart update without going to the cart page when adding an item to your cart.
I have made my custom template over the "sexy" theme and have no idea how I go about implanting this
I know this can be done, because default themes like "Good Vibes" do this.
You can use the code below. I didn't include the code for the restoreButton function in the addItem callback but I'm sure you get the idea. You'll also need your own means of retrieving the product ID based on however you're displaying your product options. Make sure to also include a reference to Big Cartel's javascript api.
$('#add_to_bag').click(function(evt){
var productId;
if($('.options_select').length != 0)
productId = $( ".options_select option:selected" ).attr('value');
else
productId = $('.price_options input').attr('value');
var quantity = $('.quantity input').attr('value');
Cart.addItem(productId, quantity, function(cart) {
$('#add_to_bag').attr('value', 'Item Added');
setTimeout(restoreButton, 2000);
});
});
You'll want to take advantage of the javascript API: https://help.bigcartel.com/developers/themes/#javascript-api
With this, you can drop in the line of code to load the API into your theme and have access to add, update, and remove items from the cart using javascript.
In my woocommerce-based store, I have combined cart and checkout pages into one, it works well, but there is an issue when I try to remove a coupon. The coupon removes from the cart with AJAX processing, so when removal is complete - the page doesn't reload, and the coupon still displaying as applied (but actually it's removed).
So I need to disable AJAX for applying/removing coupon function.
I tried to add this code into my theme's functions.php:
function disable_checkout_script() {
wp_dequeue_script( 'wc-checkout' );
}
add_action( 'wp_enqueue_scripts', 'disable_checkout_script' );
It solves my problem, but this code disables ALL AJAX at the checkout page, and I would like to disable ajax only for applying/removing coupons and to save another ajax processing like verification for billing/shipping fields.
Please help, unfortunately, I'm not a JS expert.
Regards!
In your JS file you need to remove a couple of event handlers. There's an event fired when pressing the remove coupon button and also when the coupon form is submit.
The relevant lines are 381 - 383 of woocommerce/assets/js/frontend/checkout.js (WooCommerce loads a minified version of this file).
$( document.body ).on( 'click', 'a.showcoupon', this.show_coupon_form );
$( document.body ).on( 'click', '.woocommerce-remove-coupon', this.remove_coupon );
$( 'form.checkout_coupon' ).hide().submit( this.submit );
You need to remove 2 and 3.
Add the following code to your JS file:
$( document.body ).off( 'click', '.woocommerce-remove-coupon', wc_checkout_coupons.remove_coupon );
$( 'form.checkout_coupon' ).off( 'submit' );
For anyone else looking for a solution to disable AJAX and force a refresh of the checkout page and came across this post, here's what I found worked for me without having to edit any core function files within the WooCommerce plugin. Note, however it does not actually disable AJAX, but it successfully refreshes the full checkout page upon removal.
jQuery code: This forces a page refresh 400ms after clicking the remove button to ensure that the AJAX removal command goes through first.
jQuery(document).on('click', '.woocommerce-remove-coupon', function () {
setTimeout(
function () {
window.location.href = window.location.href;
}, 400);
});
Then hook the .js file to the checkout page (add to your theme's functions.php or create a plugin).
I did it this way:
add_action( 'woocommerce_after_checkout_form', 'remove_coupon');
function remove_coupon() {
wp_enqueue_script('remove-coupon', plugins_url('remove-coupon.js', __FILE__));
}
I have a click function on a button that adds an item to my cart using the Minicart.js library from minicartjs.com. When the button is clicked items are being added to the cart however, the cart is not popping up as expected. I've tested this on up to date versions of Chrome and IE (ie 11).
Some things I've noticed:
In the debugger if I execute the show cart function
paypal.minicart.view.show() the cart displays fine. Even with the
items I've added.
When my add button is clicked "class" is appended to the body with no
actual class assigned:
When the cart is showing a class "minicart-showing" is appended to
the body.
The following script is at the end of a MVC partial View:
<script src="~/Scripts/minicart.js"></script>
<script>
$(".showcart").click(function () {
var data = $(this).attr("data-id");
paypal.minicart.cart.add(JSON.parse(data));
// $("#body").toggleClass("minicart-showing"); <---doesn't work
// paypal.minicart.view.show() <---- doesn't work
});
paypal.minicart.render();
</script>
After further reviewing the minicartjs examples in the author's repository. I found that using e.stopPropagation() within the click function resolves the issue.
$(".showcart").click(function (e) { // <--- added the e function
var data = $(this).attr("data-id");
e.stopPropagation(); // <--- And this line.
paypal.minicart.cart.add(JSON.parse(data));
});
Code Example From Author's GitHub Repo