Ajax callback does not replace the form but add a new field I use his code to populate a select after giving à zipcode.

$form['responsible']['zipcode'] = array(
      '#type'               =&gt; 'textfield',
      '#title'              =&gt; t('Zipcode'),
      '#default_value'      =&gt; empty($account-&gt;Dossier-&gt;responsable-&gt;adresse-&gt;codePostal) ? Null : $account-&gt;Dossier-&gt;responsable-&gt;adresse-&gt;codePostal,
      '#required'           =&gt; True,
      '#maxlength'          =&gt; 5,
      '#ajax' =&gt; array(
        'callback' =&gt; 'ajax_get_cities_callback',
        'wrapper' =&gt; 'edit-city',
        'method' =&gt; 'replace',
      ),
    );

    $form['responsible']['city'] = array(
      '#type'               =&gt; 'select',
      '#title'              =&gt; t('City'),
      '#options'            =&gt; array(),
      '#required'           =&gt; True,
    );


My callback

function ajax_get_cities_callback($form, $form_state){
  $client = new SoapClient('myWebservice',array("trace" =&gt; true,  "exceptions" =&gt; true,));
  $requestParams = array(
    'parameters' =&gt; array (
      'numSite' =&gt; 1058,
      'typeListes' =&gt; array(
        'RechercheTypeListe' =&gt; array(
          'typeListe' =&gt; 'LST_VILLE',
          'param1' =&gt; $form_state['values']['zipcode']
          )
        )
    )
  );
  $dataresponse-&gt;requestParams = $requestParams;
  $response = "";
  try {
      $response = $client-&gt;__Call('GetListes',$requestParams);
  }
  catch (Exception $e) {
    var_dump($e);
    return False;
  }

  $form['responsible']['city']['#options'] = array(
    0 =&gt; "aaaa",
    1 =&gt; "test2",
    2 =&gt; "test3"
  );

  return $form['responsible']['city'];

}


When I give a zipcode, a new select is created behind the first one.( picture here: https://www.uploady.com/#!/download/zjKvglzRTSe/ZIMYkjSAAaLrUFUq)
I tried to return only $form['responsible']['city']['#options'] but it does not fixe.

Any idea ?

Thank you
You have to setup a wrapper on the field you want to update :

$form['responsible']['zipcode'] = array(
      '#type'               =&gt; 'textfield',
      '#title'              =&gt; t('Zipcode'),
      '#default_value'      =&gt; empty($account-&gt;Dossier-&gt;responsable-&gt;adresse-&gt;codePostal) 
                                    ? Null 
                                    : $account-&gt;Dossier-&gt;responsable-&gt;adresse-&gt;codePostal,
      '#required'           =&gt; True,
      '#maxlength'          =&gt; 5,
      '#ajax' =&gt; array(
        'callback' =&gt; 'ajax_get_cities_callback',
        'wrapper' =&gt; 'div_city_wrapper', // Changed here
        'method' =&gt; 'replace',
      ),
    );

    $form['responsible']['city'] = array(
      '#type'               =&gt; 'select',
      '#title'              =&gt; t('City'),
      '#options'            =&gt; array(),
      '#required'           =&gt; True,
      '#prefix'           =&gt; '&lt;div id="div_city_wrapper"&gt;', // Added this
      '#suffix'           =&gt; '&lt;/div&gt;', // Added this
    );


The callback function seems to be fine as it returns the wrapped form element ($form['responsible']['city'])