0

I added an Ajax callback to Add to cart form on two fields : quantity and a date line item field, because I need customers to choose the product id depending on these values (see study case if you wish more details).

Everything works fine... except that Ajax values, especially product_id, aren't saved in cart on form submit :(

Relevant parts of code

Add to cart form alter

/**
* Implements hook_form_alter().
*/
function vts_commerce_form_alter(&$form, &$form_state, $form_id) {

  if (strstr($form_id, 'commerce_cart_add_to_cart_form')) {
    //line item field callback
    $form['line_item_fields']['field_date_de_d_part_line_item']['und'][0]['#ajax'] = array(
      'callback' => 'vts_commerce_liberte_addtocart',
     ); 
    //wrapping $form['product_id']
    $form['product_id']['#prefix']='<div id="liberte_pid">';   
    $form['product_id']['#suffix']='</div>';

    // ... SOME CODE setting $options

    //overwriting native $form['quantity'] to have a select with specific options
    $form['quantity']= array(
      '#type' => 'select',
      '#title' => t('Number of participants'),
      '#default_value' =>  1,
      '#datatype'  => 'integer',
      '#size' =>  1,
      '#weight' => 45,
      '#prefix' => '<div id="qty">',
      '#suffix' => '</div>',
      '#options' => $options,
      '#ajax' => array(
        'callback' => 'vts_commerce_liberte_addtocart',
        'wrapper' => 'qty',
        'method' => 'replace',
      ),
    );
  }
}

Ajax callback

function vts_commerce_liberte_addtocart($form, &$form_state) {

  $commands = array();

  // ... SOME CODE setting $pid and other stuff, messages...

  //TRYING TO UPDATE PRODUCT ID with drupal_render
  $form['product_id'] = array(      
    '#type' => 'select',
    '#options' => array(
       $pid => 'product title: '.$pid, // TODO retrieve product title    
    ),
    '#default_value' => $pid,
    '#weight' => 0,
  );
  $commands[] = ajax_command_replace('#liberte_pid', drupal_render($form['product_id']));

  //TRYING TO UPDATE PRODUCT ID with $form_state['values']
  $form_state['values']['product_id'] = $pid;       
  $form_state['rebuild'] = TRUE;



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

Either $form['product_id'] and $form_state['values']['product_id'] are changed by the callback, but when I submit the form, it takes the product id selected on page load instead of the one passed through the callback.

With or without $form_state['rebuild'] = TRUE; in my callback doesn't changes anything...

As an alternative (or complement), I also noticed that product_id's callback is commerce_cart_attributes_refresh_alter(), which updates the values given to cart, but I don't know how/where to call or trigger it in the ajax process ?

0

So, product_id was rendered but its value not passed to the commerce_cart_add_to_cart_form. This is how I solved it.

Add to Cart Form Alter

if (strstr($form_id, 'commerce_cart_add_to_cart_form')) {

  $form['product_id']['#type']='hidden';  
  $form['product_id']['#prefix']='<div id="liberte_pid">';   
  $form['product_id']['#suffix']='</div>';
  //...

Ajax callback

$form['product_id']['#value'] = array( 
  $pid,     
);
$commands[] = ajax_command_replace('#liberte_pid', drupal_render($form['product_id']));

It's quite simple once you know it : before calling ajax_command_replace() you don't need to rebuild the full form element, just set the wanted attribute, and drupal_render($form['form_elt'])) will do the magic :)

  • Apart, I still don't know why rendering full $form['product_id'] via Ajax (with the code in the question) made it lose its name attribute, and so not updated in cart...? – Kojo Jun 10 '14 at 20:17

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.