Autocomplete several fields with values based on the selected value of an user reference field UPDATE: the code is now cleaner and shorter. An autocomplete field triggers the ajax callback which reloads a field. The whole thing works for one field but not so well for multiple fields.

function my_module_form_alter(&amp;$form, &amp;$form_state, $form_id) {
  if ($form_id == 'form_id_form') {
$form['triggering_field_id'][LANGUAGE_NONE][0]['value'] += array(
    '#autocomplete_path' =&gt; 'my_auto_path',
    '#ajax' =&gt; array(
        'callback' =&gt; 'my_ajax_callback',
            'wrapper' =&gt; 'my_ajax_wrapper',
            'method' =&gt; 'replace',
            'effect' =&gt; 'fade',
        ),
    );

    $form['dependant_field1'] += array(
        '#prefix' =&gt; '&lt;div id="my_ajax_wrapper"&gt;',
    );
    $form['dependant_field2'] += array(
        '#suffix' =&gt; '&lt;/div&gt;',
    );
  }
}

function my_module_menu() {
    $items = array();

    $items['my_auto_path'] = array(
        'title' =&gt; '',
        'page callback' =&gt; '_my_auto_path',
        'access arguments' =&gt; array('access content'),
        'type' =&gt; MENU_CALLBACK,
    );

    return $items;
}

function _my_auto_path($string) {
  $string = array(':s' =&gt; $string . '%');

  if ($string) {
    $results = db_query("SELECT name FROM {users} WHERE name LIKE :s", $string);

    $items = array();
    foreach ($results as $result) {
        $items[$result-&gt;name] = $result-&gt;name;
    }
    print drupal_json_encode($items);
  }
}

function my_ajax_callback(&amp;$form, &amp;$form_state) {
    if (user_load_by_name($form_state['values']['triggering_field_id'][LANGUAGE_NONE][0]['value']) != FALSE) {
        $user_obj = user_load_by_name($form_state['values']['triggering_field_id'][LANGUAGE_NONE][0]['value']);
        $user_id = $user_obj-&gt;uid;
        //let's get another field from user's object:
        //$user_whatever_userfield = $user_obj-&gt;whatever;

        $form['dependant_field1'][LANGUAGE_NONE][0]['value']['#value'] = $user_id;
        //Do the same for the 2nd field but need to return both fields at the same time...
        //$form['dependant_field2'][LANGUAGE_NONE][0]['value']['#value'] = $user_whatever_userfield;
        return $form['dependant_field1'];

        //another way, with ajax commands:
        //but I can only replace the whole &lt;input&gt; instead of just the val() of each field.
        //$commands = array();
        //$commands[] = ajax_command_replace("#dependant_field1_id", $user_id);
        //$commands[] = ajax_command_replace("#dependant_field2_id", $user_whatever_userfield);
        //return array('#type' =&gt; 'ajax', '#commands' =&gt; $commands);
    }
}
I just found the solution to my problem: Every AJAX command runs and replaces the defined element. The trick is to predefine the values for all fields I need to update, within the callback. Then, these values remain in tact within the array of the newly rendered fields using the AJAX commands. Here is my updated callback:

function my_ajax_callback(&amp;$form, &amp;$form_state) {
    if (user_load_by_name($form_state['values']['triggering_field_id'][LANGUAGE_NONE][0]['value']) != FALSE) {
        $user_obj = user_load_by_name($form_state['values']['triggering_field_id'][LANGUAGE_NONE][0]['value']);
        $user_id = $user_obj-&gt;uid;
        // and another user attribute:
        $user_whatever_userfield = $user_obj-&gt;whatever;

        $form['dependant_field1'][LANGUAGE_NONE][0]['value']['#value'] = $user_id;
        $form['dependant_field2'][LANGUAGE_NONE][0]['value']['#value'] = $user_whatever_userfield;

        $commands = array();
        $commands[] = ajax_command_replace("#dependant_field1_wrapper", render($form['dependant_field1']));
        $commands[] = ajax_command_replace("#dependant_field2_wrapper", render($form['dependant_field2']));
        return array('#type' =&gt; 'ajax', '#commands' =&gt; $commands);
    }
}


Also, I changed the position of my wrapper to have a wider range, in order to include all the fields I want to ajax-update. As every AJAX command will be recreating each form element, if the form element lives within a wrapper (added in form_alter), the wrapper will also be rendered and that causes an HTML mess. So having one hidden field above &amp; another hidden field below my fields makes life easy. The new wrapper encloses these hidden fields and leaves all other fields clean when regenerated from the callback.