Ajax callback values not saved on submit 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(&amp;$form, &amp;$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' =&gt; 'vts_commerce_liberte_addtocart',
     ); 
    //wrapping $form['product_id']
    $form['product_id']['#prefix']='&lt;div id="liberte_pid"&gt;';   
    $form['product_id']['#suffix']='&lt;/div&gt;';

    // ... SOME CODE setting $options

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


Ajax callback

function vts_commerce_liberte_addtocart($form, &amp;$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' =&gt; 'select',
    '#options' =&gt; array(
       $pid =&gt; 'product title: '.$pid, // TODO retrieve product title    
    ),
    '#default_value' =&gt; $pid,
    '#weight' =&gt; 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' =&gt; 'ajax', '#commands' =&gt; $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 ?
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']='&lt;div id="liberte_pid"&gt;';   
  $form['product_id']['#suffix']='&lt;/div&gt;';
  //...


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 :)