-1

I have a select form element that fires an ajax callback function everytime its value changes.

$form['template_options'] = array(
  '#type' => 'select',        
  '#options' => array(
     1 => t("Student"),
     2 => t("Employee"),         
  ),
  '#default_value' => 1,
  '#title' => t('Select'),                  
  '#ajax' => array(
    'callback' => 'myid_select_template',
    'wrapper' => 'myid_dynamic_input_information',
  ),                             
  '#suffix' => '<div id="myid_dynamic_input_information"></div>',
);

The function myid_select_template is a callback function triggered when the select form element changes it's value.

 function myid_select_template($form, &$form_state){
     $form = array();

     $form['form']['birthdate'] = array(   
         '#title' => t('Date of Birth'), 
         '#type' => 'date_popup',    
         '#timepicker' => 'timepicker', 
         '#date_format' => 'd/m/Y',
         '#date_year_range' => '-100:+0',
         '#default_value' => date("Y-m-d H:i:s", time()),  
    );
    return $form;
 }

I already enabled Date API, Date Pop-up and Date Picker module. I notice that the date_popup form element doesn't show when I place it in a form not rendered in ajax callback function.

The HTML below is an output of an ajax callback function:

<div class="container-inline-date">
    <div class="form-item form-type-date-popup">
        <label>Date of Birth </label>
        <div id="" class="date-padding clearfix"></div>
    </div>
</div>

The HTML output below is the output of a working Date Picker not rendered by ajax function:

<div class="container-inline-date">
    <div class="form-item form-type-date-popup form-item-birthdate">
        <div id="edit-birthdate" class="date-padding">
            <div class="form-item form-type-textfield form-item-birthdate-date">
                <label for="edit-birthdate-datepicker-popup-0">Date </label>
                <input type="text" id="edit-birthdate-datepicker-popup-0" name="birthdate[date]" value="27/07/2015" size="20" maxlength="30" class="form-text">
                <div class="description"> E.g., 27/07/2015</div>
            </div>
         </div>
     </div>
</div>

I notice it is rendered incompletely. Why?

  • As side note: Remove the line initializing $form, which is already an argument of the form builder. – kiamlaluno Jul 27 '15 at 4:59
  • There is a reason why the function is declared as myid_select_template($form, &$form_state).Also, see the example given in Ajax framework. – kiamlaluno Jul 27 '15 at 5:29
1

You are confusing what an AJAX callback does in Drupal with what a form builder does. See ajax_example_autocheckboxes() that adds a number of checkboxes basing on the number selected in a select field.

  // Since the form builder is called after every AJAX request, we rebuild
  // the form based on $form_state.
  $num_checkboxes = !empty($form_state['values']['howmany_select']) ? $form_state['values']['howmany_select'] : 1;

  // Omissis...

  for ($i = 1; $i <= $num_checkboxes; $i++) {
    $form['checkboxes_fieldset']["checkbox$i"] = array(
      '#type' => 'checkbox',
      '#title' => "Checkbox $i",
    );
  }

The AJAX callback is pretty simple. (ajax_example_autocheckboxes_callback())

function ajax_example_autocheckboxes_callback($form, $form_state) {
  return $form['checkboxes_fieldset'];
}

Its description says what an AJAX callback does when used with a form builder.

Callback element needs only select the portion of the form to be updated. Since #ajax['callback'] return can be HTML or a renderable array (or an array of commands), we can just return a piece of the form.

As side note, if you just want to show a form element, or also hide it, basing on the value selected for another form element, there is the #states form API property.

$form['toggle_me'] = array(
  '#type' => 'checkbox',
  '#title' => t('Tick this box to type'),
);
$form['settings'] = array(
  '#type' => 'textfield',
  '#states' => array(
    // Only show this field when the 'toggle_me' checkbox is enabled.
    'visible' => array(
      ':input[name="toggle_me"]' => array('checked' => TRUE),
    ),
  ),
);

Your Answer

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