Steps to Reproduce:

1. Install:
Address Field 7.x-1.0-beta2
Chaos tool suite (ctools) 7.x-1.0-rc1
Drupal Commerce 7.x-1.0
Entity API 7.x-1.0-beta10
Rules 7.x-2.0-rc2
Views 7.x-3.0-rc1

2. Create a product

3. Create a product display:
machine name = product_display
Add a product reference field

5. Create a product display:
Add the word monkey to the body
Add the product in the reference field

6. Run cron to index the body in product display

7. Import the view below.

8. Visit the path: test

9. Search for the word monkey

10. Click Add to Cart after AJAX completes search

Instead of adding the product to the shopping cart, the user is taken to /views/ajax.

$view = new view;
$view->name = 'test';
$view->description = '';
$view->tag = 'default';
$view->base_table = 'node';
$view->human_name = 'Test';
$view->core = 7;
$view->api_version = '3.0-alpha1';
$view->disabled = FALSE; /* Edit this to true to make a default view disabled initially */

/* Display: Master */
$handler = $view->new_display('default', 'Master', 'default');
$handler->display->display_options['title'] = 'Test';
$handler->display->display_options['use_ajax'] = TRUE;
$handler->display->display_options['access']['type'] = 'perm';
$handler->display->display_options['cache']['type'] = 'none';
$handler->display->display_options['query']['type'] = 'views_query';
$handler->display->display_options['query']['options']['query_comment'] = FALSE;
$handler->display->display_options['exposed_form']['type'] = 'basic';
$handler->display->display_options['pager']['type'] = 'full';
$handler->display->display_options['pager']['options']['items_per_page'] = '10';
$handler->display->display_options['style_plugin'] = 'default';
$handler->display->display_options['row_plugin'] = 'node';
/* Field: Content: Title */
$handler->display->display_options['fields']['title']['id'] = 'title';
$handler->display->display_options['fields']['title']['table'] = 'node';
$handler->display->display_options['fields']['title']['field'] = 'title';
$handler->display->display_options['fields']['title']['label'] = '';
$handler->display->display_options['fields']['title']['alter']['alter_text'] = 0;
$handler->display->display_options['fields']['title']['alter']['make_link'] = 0;
$handler->display->display_options['fields']['title']['alter']['absolute'] = 0;
$handler->display->display_options['fields']['title']['alter']['word_boundary'] = 0;
$handler->display->display_options['fields']['title']['alter']['ellipsis'] = 0;
$handler->display->display_options['fields']['title']['alter']['strip_tags'] = 0;
$handler->display->display_options['fields']['title']['alter']['trim'] = 0;
$handler->display->display_options['fields']['title']['alter']['html'] = 0;
$handler->display->display_options['fields']['title']['hide_empty'] = 0;
$handler->display->display_options['fields']['title']['empty_zero'] = 0;
$handler->display->display_options['fields']['title']['link_to_node'] = 1;
/* Sort criterion: Content: Post date */
$handler->display->display_options['sorts']['created']['id'] = 'created';
$handler->display->display_options['sorts']['created']['table'] = 'node';
$handler->display->display_options['sorts']['created']['field'] = 'created';
$handler->display->display_options['sorts']['created']['order'] = 'DESC';
/* Filter criterion: Content: Published */
$handler->display->display_options['filters']['status']['id'] = 'status';
$handler->display->display_options['filters']['status']['table'] = 'node';
$handler->display->display_options['filters']['status']['field'] = 'status';
$handler->display->display_options['filters']['status']['value'] = 1;
$handler->display->display_options['filters']['status']['group'] = 0;
$handler->display->display_options['filters']['status']['expose']['operator'] = FALSE;
/* Filter criterion: Content: Type */
$handler->display->display_options['filters']['type']['id'] = 'type';
$handler->display->display_options['filters']['type']['table'] = 'node';
$handler->display->display_options['filters']['type']['field'] = 'type';
$handler->display->display_options['filters']['type']['value'] = array(
  'product_display' => 'product_display',
);
/* Filter criterion: Search: Search Terms */
$handler->display->display_options['filters']['keys']['id'] = 'keys';
$handler->display->display_options['filters']['keys']['table'] = 'search_index';
$handler->display->display_options['filters']['keys']['field'] = 'keys';
$handler->display->display_options['filters']['keys']['exposed'] = TRUE;
$handler->display->display_options['filters']['keys']['expose']['operator_id'] = 'keys_op';
$handler->display->display_options['filters']['keys']['expose']['label'] = 'Search Terms';
$handler->display->display_options['filters']['keys']['expose']['operator'] = 'keys_op';
$handler->display->display_options['filters']['keys']['expose']['identifier'] = 'keys';
$handler->display->display_options['filters']['keys']['expose']['multiple'] = FALSE;

/* Display: Page */
$handler = $view->new_display('page', 'Page', 'page');
$handler->display->display_options['path'] = 'test';

Comments

bojanz’s picture

Status: Active » Postponed (maintainer needs more info)

Can you retest with Views 7.x-3.x-dev, and report back if this is still a problem?
I remember a patch going in that fixed the same issue with views forms (like vbo or the commerce cart), but this case might need further work.

pnigro’s picture

Hello bojanz,

I get the same issue with Views 7.x-3.x-dev (2011-Sep-28).

bojanz’s picture

Status: Postponed (maintainer needs more info) » Active

Okay, thanks for checking.

sined79’s picture

Same problem :'(
Did you find a solution?
Thanks ;-)

cangeceiro’s picture

I am also running into this issue with out much luck to finding a resolution. Where you able to find a fix?

terbs’s picture

Hey guys,

I encountered this bug with views 7.x-3.0-rc3 and Commerce 7.x-1.1

The problem is that when the view refreshed via ajax, it changed the form "action" of the add to cart form to /views/ajax
I suppose a proper fix should be done within the views module itself.

Here's what I did to fix it.
This is a temporary band-aid style fix, but it'll do the trick if you need to get this up and running. The solution was to set up an AJAX listener in my theme's script file, and change the form action back to the correct one once the view finished doing its AJAX call. My code is attached below for reference. You should be able to just drop it in, but it's untested in IE

$(".view").ajaxComplete(function(event, XMLHttpRequest, ajaxOptions){
	
	response = XMLHttpRequest.responseText;
	result = response.search(/"status": false/i);

	if(result == -1){
		$("form.commerce-add-to-cart").each(function(){
			$(this).attr("action",window.location.pathname);
		});
	}
	else{
		//console.log("failure binding on ajax complete");
	}
});

dpolant’s picture

I think this is the same views issue as http://drupal.org/node/1191928. This general problem has been known about for a while in various forms. I thought it had been fixed, but evidently the case brought up by the ajax-search/add-to-cart view still needs work.

rszrama’s picture

Looks like there's a patch to review there perhaps?

dpolant’s picture

http://drupal.org/files/issues/1191928-followup.patch did not fix the problem. Is it worth reopening that issue? On second inspection this issue might be slightly different than the one reported there.

davery’s picture

Status: Closed (duplicate) » Active

The workaround in #6 worked for me, but i had to enclose it as follows:

(function($) {
Drupal.behaviors.mymodule = {
attach: function(context, settings)
{
(stuff from #6)
}
};
})(jQuery);

and it goes inside function mytheme_process_page(&$variables), with
drupal_add_js(drupal_get_path('theme', 'mytheme') . '/scripts.js', 'file', 'header', 'JS_THEME');

where scripts.js contains the script code.

dianikol’s picture

#10 and #6 works for me

rszrama’s picture

Status: Active » Closed (duplicate)

Is this not simply a duplicate issue of the appropriate issue in the Views queue? I didn't catch the original context when this first came through the queue, but it shouldn't be our problem to correct rewritten form action URLs when the AJAX pager is used. I don't think using JS to rewrite the URLs like the method in #6 / #10 is really a good way to go or even anything that Drupal Commerce should be doing as opposed to Views.

The issue bojanz linked was apparently resolved and then followed up with another issue. Do we need to leave this one open here?

neighborhoodsix’s picture

Status: Active » Closed (duplicate)

#10 and #6 get rid of the error message but nothing gets added to the cart (the page just reloads). Any ideas?

bloomt’s picture

Anyone have a fix? --- Every post that has this issue in it gets closed and pointed at another issue which eventually gets closed and pointed at another issue. This is really frustrating.

bloomt’s picture

Priority: Normal » Major
Status: Closed (duplicate) » Active

Why did this issue get closed?

bloomt’s picture

rszrama’s picture

Status: Active » Closed (duplicate)

This was closed as a duplicate of the Views issue linked in #7 above, and I don't have any reason to believe there's an issue with the form provided by the Cart module itself. Some things just can't be done through AJAX enabled Views, and submitting forms rendered in Views fields is often one of them.

I don't know what your actual problem is, but to begin to diagnose it, we'll need you to post a Question at http://www.drupalcommerce.org/questions with step-by-step instructions to reproduce whatever error it is you're experiencing on a clean installation of Commerce Kickstart 1.x.

kpicaza’s picture

#6 & #10 works correctly in my case. Thx davery & aiquandol

a.milkovsky’s picture

As I can see there is no solution in both issue threads.
My solution might help somebody:
I've got that fixed by changing "Add to cart" to ajax button.
More info (in RUSSIAN): http://www.drupal.ru/node/98386#comment-566026, http://xandeadx.ru/blog/drupal/645

Ericmaster’s picture

#19 was just what I was looking for, and it was clean and simple :)

thanks a.milkovsky

kratos91’s picture

I have the same problem, have anyone found a complete solution ? which doesn`t send to ajax page and add the product to the cart , in my case jquery updade module isn'tinstalled so I don't know if this error is caused by another module o configuration.

I'll apreciate your reply

kratos91’s picture

Issue summary: View changes
Status: Closed (duplicate) » Needs review
rszrama’s picture

Category: Bug report » Support request
Priority: Major » Normal
Status: Needs review » Closed (duplicate)

Please see comment #17 - some things just aren't possible with Views AJAX.

bloomt’s picture

Did anyone ever find the solution to this problem?

wesleymusgrove’s picture

I'm experiencing the same as #13.

#10 and #6 get rid of the error message but nothing gets added to the cart (the page just reloads). Any ideas?

@aiquandol, @dianikol, @kpicaza and those of you who said #10 and #6 work, can you confirm it's actually adding a product to the cart?

Is there a way to alter $.ajax's xhr.responseText before it gets inserted into the DOM and replace all occurrences of action="/views/ajax" with action="' + window.location.pathname + '"?

wesleymusgrove’s picture

I sorta found a workaround for this by hooking into hook_views_ajax_data_alter to do a str_replace on the $command['data'] to change the add-to-cart form actions in the actual markup.

In my case, (using Better Exposed Filters to print out filter options as links instead of radio buttons) selecting each exposed filter option re-renders several product teasers each with add-to-cart forms, so there are several places in the $command['data'] markup that this str_replace takes place.

This does successfully change the add-to-cart forms' #action from 'action="views/ajax"' to 'action="[current page url]"'.

However when you try to actually add an item to your cart, this seemingly correct form action still only refreshes the page and does not add the item to your cart.

Through trial and error, I discovered that if the new form action contains the exposed filter identifier and filter id number (taxonomy term name and term id, respectively, in my case) in the querystring like this: http://www.example.com/view-with-exposed-filter?filter-identifier=123; then and only then will it actually add the item to the cart.

However (as form actions do) this posts the form to that page with the querystring and subsequent exposed filter selections and view re-renderings (via AJAX) will not change the url to use the currently selected filter id number in the querysting, so when the add-to-cart form posts again, the item will not be added to the cart unless the item you're adding belongs to the filter id (taxonomy term) in the url.

FWIW, here's my code. Maybe someone can help me better understand why the AJAX rendered add-to-cart forms must supply the correct exposed form filter identifier in the form action to actually add the item to the cart instead of just refreshing the page... while this isn't the case on the initial (non-AJAX) load of a view with exposed form filters where add-to-cart forms work without the filter id specified in the form action.

<?php
/**
 * Implements hook_views_ajax_data_alter()
 */
function hook_views_ajax_data_alter(&$commands, $view) {
  // Get the variable options from the view object.
  $options = $view->query->pager->display->display_options;

  // Make sure this view is using ajax and BEF exposed filters
  $use_exposed = (isset($options['use_ajax']) && isset($options['exposed_form']) && $options['exposed_form']['type'] == 'better_exposed_filters') ? TRUE : FALSE;

  // In the command's data replace 'action="/views/ajax"' to 'action="[current page url]"'
  // See: views_ajax_fade contrib module
  if ($use_exposed) {
    foreach ($commands as &$command) {
      if (isset($command['method']) && $command['method'] == 'replaceWith') {
        $path_alias = url(drupal_lookup_path('alias', current_path()));
        //$path_alias = 'http://www.example.com/view-with-exposed-filter?filter-identifier=123';
        $command['data'] = str_replace('action="/views/ajax"', 'action="'.$path_alias.'"', $command['data']);
      }
    }
  }
}
?>

References:

kevster’s picture

Many thanks @a.milkovsky - #19 fixed an issue we had where anonymous users could not add to cart in category view using product teaser mode - button would not do anything and form action was blank. We are using authcache and memcache with ajax loading the prods so not sure if this affected anything.

cheers!

minff’s picture

Actually it seems to me that the issue is actually about drupal_html_id() still not generating unique IDs on Ajax calls. Form items get the same IDs, breaking the functionality because Ajax is not applied to them any more (search for missing "ajax-processed" classes on submit buttons loaded by Ajax). Thus the (ugly) workaround is to tweak the unique ID generation process to make sure that form items loaded via Ajax truly have unique IDs. Once that's done, add to cart buttons should work fine.

P.S. drupal_html_id() problems are well-known, see for discussion: https://www.drupal.org/node/1305882

Mitch Boulter’s picture

Thanks to wesleymusgrove - #26 was a solid solution, and illuminated for me why the submission wasn't working. In addition to the code provided, I generated the query string on the fly based on the view query. Adding the correct query string to the form action allows me to add to cart and enter the purchase process every time, even when using an AJAX enabled view. Cheers!

function hook_views_ajax_data_alter(&$commands, $view) {
  $query_string = http_build_query($view->exposed_input);

  foreach ($commands as &$command) {
    if (isset($command['method']) && $command['method'] == 'replaceWith') {
      $path_alias = url(drupal_lookup_path('alias', current_path()));
      //$path_alias = 'http://www.example.com/view-with-exposed-filter?filter-identifier=123';
      $command['data'] = str_replace('action="/views/ajax"', 'action="'.$path_alias.'?' . $query_string . '"', $command['data']);
    }
  }
}