Given this code:

/**
 * Implements hook_form_FORM_ID_alter().
 */
function store_form_uc_product_add_to_cart_form_alter(&$form, &$form_state, $form_id) {
  $form['actions']['submit']['#ajax'] = array(
    'callback' => 'store_ajax_cart_add',
    'progress' => FALSE,
  );
}

/**
 * Ajax Callback, Add a Product to the cart.
 */
function store_ajax_cart_add($form, &$form_state) {

  // Load the array of shopping cart items.
  $total_qty = uc_cart_get_total_qty();
  $items = uc_cart_get_contents();

  $commands = array();

  $build = array();

  // Display the empty cart page if there are no items in the cart.
  if (empty($items)) {
    $build['#theme'] = 'uc_empty_cart';
  }
  else {
    $build = drupal_get_form('uc_cart_view_form', $items) + array(
      '#prefix' => '<div id="cart-form-pane">',
      '#suffix' => '</div>',
    );      
  }

  unset($build['cart_form']['actions']['continue_shopping']);

  $commands[] = ajax_command_html('.block-uc-cart .content', '');
  $commands[] = ajax_command_html('.block-uc-cart .content', drupal_render($build));

  $commands[] = ajax_command_before('#'.$form['#id'], '<div class="ajax-hidden remove-soon" style="display:none; opacity:0;">'.theme('status_messages').'</div>');
  $commands[] = ajax_command_invoke('div.ajax-hidden', 'ajaxSlide');    
  $commands[] = ajax_command_invoke('div.ajax-hidden', 'removeClass', array('ajax-hidden'));

  if (!empty($total_qty)) {
    $commands[] = ajax_command_after('.cart-block-icon-empty', ' <span class="cart-block-item-count"></span>');
    $commands[] = ajax_command_invoke('.cart-block-item-count', 'text', array(number_format($total_qty)));
    $commands[] = ajax_command_invoke('.cart-block-icon-empty', 'addClass', array('cart-block-icon-full'));
    $commands[] = ajax_command_invoke('.cart-block-icon-empty', 'removeClass', array('cart-block-icon-empty'));
  }

  return array('#type' => 'ajax', '#commands' => $commands);
}

Every time the form is submitted (with Ajax) I get this Javascript error:

TypeError: element_settings.url.replace is not a function
this.url = element_settings.url.replace(/\/nojs(\/|$|\?|&|#)/g, '/ajax$1');
ajax.js?v=7.14 (line 132)

I discovered that this has to do with the drupal_get_form in the ajax callback. When I remove the form get, the error disappears.

Also, if I go to misc/ajax.js and remove line 132 it also clears up the errors.

I'd like to not modify core (misc/ajax.js), and I'd also like to return the form with Ajax.

Am I doing something wrong is is this a Drupal bug?

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

davidwbarratt’s picture

First patch attempt. Simply checks to make sure that replace() is a valid function before moving forward.

davidwbarratt’s picture

Status: Active » Needs review
FileSize
743 bytes

Hmm, why is the tester ignoring the patch?

nod_’s picture

Status: Needs review » Needs work

You'd want to check that element_settings.url is a string instead. No need for the jQuery thing.

davidwbarratt’s picture

Status: Needs work » Needs review
FileSize
741 bytes

good call! #learnsoemthingneweveryday

try this patch.

aspilicious’s picture

I had this before I'm not sure this is the root of the problem.

davidwbarratt’s picture

I'm not sure if it is or not, but the patch fixes the problem.

thanks!

dgastudio’s picture

i have the same problem in d7, using custom views exposed filter.

patch solves it.

thank you.

osopolar’s picture

element_settings.url should always be a string, if this is not the case then it's an indication that something else went wrong.

Are you using webforms together with modal_forms? In my case element_settings.url was an object (with two different url's). The reason was a tiny bug introduced in #1326716: Webform module support (see #25 of quoted issue; ctools_modal_form_wrapper() was called twice so the form got build two times => this was the reason why there appeared two urls in element_settings).

ygerasimov’s picture

Status: Needs review » Reviewed & tested by the community

I have faced this bug as well (similar case with "Add to cart" commerce button using custom ajax callback) and patch fixes the problem.

Big thanks.

osopolar’s picture

@ygerasimov Did you check for the reason why element_settings.url was not a string in your case. This is a bit harder to track but seems to be the correct way. IMHO this patch only treats the symptoms but hides the cause instead of fixing it.

I am against this patch until its proven that element_settings.url is allowed to be something else than a string. See for example: #1326716: Webform module support #25.

ygerasimov’s picture

Status: Reviewed & tested by the community » Needs work

@osopolar no I haven't checked that. I agree that it will be better way to find out why element_settings.url is not a string. Lets keep this patch in "needs work" status. But I have no idea where to look at truly to say.

maciej.zgadzaj’s picture

Status: Needs review » Needs work
FileSize
612 bytes
154.22 KB

I have experienced this problem too, twice actually over the last few days, with slightly different messages, on different sites, but the general issue seems to be exactly the same.

The problem is that in JSON returned by ajax callback some Drupal.settings values are getting duplicated, and we're left with arrays instead of scalars. (Edit: In both cases it is "caused by" form elements added by custom Views field handlers with defined #ajax callbacks.)
See the attached response.png. Check the values of everything inside expanded settings.ajax.commerce_coupon_remove_2.
For example, url should be just "/system/ajax" (scalar), not ["/system/ajax", "/system/ajax"] (array).
The same applies to all other values.

For me this happens only with ajax calls, which for some reason re-add the same setting values turning them from scalars to arrays.
Attached patch to common.inc (against 7.x) helps here and gets rid of this problem - not sure though if it is really a proper solution to this...

maciej.zgadzaj’s picture

Status: Needs work » Needs review

Status change.

Status: Needs review » Needs work

The last submitted patch, common.inc_.patch, failed testing.

maciej.zgadzaj’s picture

Status: Needs work » Needs review
FileSize
620 bytes

Patch against 8.x.

maciej.zgadzaj’s picture

Status: Needs review » Closed (duplicate)

Closing as a duplicate of issues linked to in my previous comment, plus extra few linked from them.

khoomy’s picture

Patch from related issues as mentioned in #16 does not work.
TypeError: element_settings.url.replace is not a function
Appears when element_settings.url has array instead of string. When it appears as array then there are multiple key value pairs having same keys and values all the time, so in this case we have to pick first value.

Attached patch fixed my issue

RobLoach’s picture

Version: 8.0.x-dev » 7.x-dev
Status: Closed (duplicate) » Needs review
FileSize
837 bytes

The linked issues above don't really look like duplicates. Here's a patch that applies to the Drupal 7 root. Not sure of ajax.js's state in D8.

Status: Needs review » Needs work

The last submitted patch, 19: drupal-1715508-19-ajax_js_error.patch, failed testing.

RobLoach’s picture

The last submitted patch, 19: drupal-1715508-19-ajax_js_error.patch, failed testing.

RobLoach’s picture

Status: Needs work » Needs review
FileSize
2.11 KB
stefan.r’s picture

D8 still has that snippet -- is this still an issue there?