Support for Drupal 7 is ending on 5 January 2025—it’s time to migrate to Drupal 10! Learn about the many benefits of Drupal 10 and find migration tools in our resource center.
On AJAX enabled Views with exposed filters or pagers the "Add to Cart" button does not work properly.
After an AJAX call, the add-to-cart form action changes to views/ajax
, so if you press the button, only a JSON output will be displayed.
This is a Views AJAX issue. Any form being shown in a Views using AJAX will have it's action
path changed.
Steps to reproduce:
- Create a View that shows your Product Displays.
- Set the View to use a pager, display 1 item
- Ensure the "Add to Cart" form is being displayed. This can be done using rendered entity, or when using fields adding the add to cart form field element
- Under Advanced, set the View to use AJAX.
- Now when you view the View, and use the pager, and then click "Add to Cart", you will get the JSON views/ajax page.
Comments
Comment #1
rszrama CreditAttribution: rszrama commentedThis actually has nothing to do with Commerce and is really just a limitation of Views itself. When a form is built in Drupal, its action is always whatever URL generated the form. When you make the Ajax request, it POSTs to views/ajax, so if the View output has a form in it, that's going to be its action. The simplest workaround is to disable the Ajax functionality for the View; next is to theme a link to look like an Add to Cart button instead that takes you to the product page; if you're feeling up to it, you can also use the Rules link module to make that link an actual Add to Cart button. Making our Views field work with Ajax Views isn't in the cards at the moment.
Comment #2
eFeS CreditAttribution: eFeS commentedThe only problem, that I do not want to go to the product page, neither make a link to look like an Add to cart button. I want the selected product to add to the cart from the listing page.
OK, but I realized, that this is ponintless to cointinue this way. Is there any chance to solve this? Which module needs a patch, for example? I'm not a programming guru, but if there is no other solution, I could give a try to fix it myself. Or is it impossible?? :)
Comment #3
donutdan4114 CreditAttribution: donutdan4114 commentedOne solution to this, is a quick custom menu item that can handle adding a product to the cart.
This of course will not work with product variations, but if you know the product ID, do something like this:
In your custom module, implement hook_menu().
Create your callback function:
Now you can create your own add to cart link in a View that points to
custom/add-to-cart/PRODUCT_ID
.Comment #4
donutdan4114 CreditAttribution: donutdan4114 commentedComment #5
rszrama CreditAttribution: rszrama commentedYou could also use https://drupal.org/project/rules_link and manage it via Rules.
Comment #6
pixelula CreditAttribution: pixelula commentedThis was my workaround:
Comment #7
mstevetodd CreditAttribution: mstevetodd as a volunteer commentedFor the benefit of others finding this page, my problem turned out to be that I had HTML caching enabled on the view. See this: https://www.drupal.org/node/1926888
Comment #8
Vilgo CreditAttribution: Vilgo commented#6 works like a charm. Thank you Pixelula.
Comment #9
andyg8 CreditAttribution: andyg8 commentedThanks mstevetodd for pointing out the caching issue. That was causing our site's Add to cart button to fail if used on a 2nd product in a view (even a non-Ajax view). We found we could still cache if we used Views, caching > time based > cache raw query results (1 hour) but NOT cache rendered output.
Comment #10
joro78 CreditAttribution: joro78 as a volunteer and commentedConfirming that #6 works.
Just remember to change the name of the function,
matching your theme name (for ex. function mytheme_form_alter...),
and put it in template.php file.
Thanks also from me pixelula =)
I just want to inform that there might be a problem with multilingual sites.
A solution is to get the language prefix and add it after the base path in order not to switch to default
after adding the product into cart. My code in template.php looks like this:
function mytheme_form_alter(&$form, &$form_state, $form_id) {
global $language;
$curlang = $language->language;
if (strpos($form_id, 'commerce_cart_add_to_cart') !== FALSE) {
$query = drupal_http_build_query(drupal_get_query_parameters());
$form['#action'] = base_path() . ($curlang) . ('/') . current_path() . '?' . $query;
}
}
Discussion and solution concerning similar issue is found here:
https://drupal.stackexchange.com/questions/129819/print-current-base-lan...
Comment #11
ddhuri CreditAttribution: ddhuri commented#6 works for me, Thank you pixelula.
Comment #12
chandrahas.d CreditAttribution: chandrahas.d commentedHello guys,
I am facing the same issue in Drupal 8 and I am not able to find any solution.
I tried to convert the same Drupal 7 code to Drupal 8 but i am not able to make it work.
Any ideas or pointers would be useful.
Thanks.
Comment #13
Lovejit_singh CreditAttribution: Lovejit_singh as a volunteer commented#6 works well for me, though it returns only the next page products after product added to cart.
I found this solution for that.