0

Having trouble getting an #ajax callback to work, initially user clicks on a date on the calendar and an ajax request is made to get the time slots, the time slots form have an ajax callback attached so when time slot is selected the final form will render but it's not.

This is the code I am using.

/**
 * @file
 * A module for scheduling visits with a calendar and form.
 */

/**
 * Implements hook_menu().
 */
function visit_scheduler_menu() {
  $items['schedule-visit'] = array(
    'title' => 'Schedule a visit',
    'page callback' => 'visit_scheduler_page',
    'access callback' => TRUE,
  );
  $items['ajax/visit-scheduler/get-time-slots'] = array(
    'page callback' => 'visit_scheduler_ajax_get_time_slots',
    'access callback' => TRUE,
    'type' => MENU_CALLBACK,
  );
  
  return $items;
}

/**
 * Page callback for the visit scheduler page.
 */
function visit_scheduler_page() {
  drupal_add_library('system', 'ui.datepicker');
  drupal_add_library('system', 'drupal.ajax');
  drupal_add_js(drupal_get_path('module', 'visit_scheduler') . '/js/visit_scheduler.js');
  drupal_add_css(drupal_get_path('module', 'visit_scheduler') . '/css/visit_scheduler.css');

  $output = '<div id="visit-calendar"></div>';
  $output .= '<div id="time-slots"></div>';
  //$output .= '<div id="visit-form"></div>';

  return $output;
}

/**
 * AJAX callback to get available time slots.
 */
function visit_scheduler_ajax_get_time_slots() {
  $slots = array(
    '10:30-11:30' => t('10:30 - 11:30'),
    '13:00-14:00' => t('13:00 - 14:00'),
    '15:00-16:00' => t('15:00 - 16:00'),
  );

  $form = drupal_get_form('visit_scheduler_time_slot_form', $slots);
  $output = drupal_render($form);

  drupal_json_output(array('html' => $output));
}

/**
 * Form constructor for the time slot selection form.
 */
function visit_scheduler_time_slot_form($form, &$form_state, $slots) {
  $form['time_slot'] = array(
    '#type' => 'radios',
    '#title' => t('Available time slots'),
    '#options' => $slots,
    '#ajax' => array(
      'callback' => 'visit_scheduler_ajax_get_form',
      'wrapper' => 'visit-form',
    ),
  );

  $form['visit_form_container'] = array(
    '#type' => 'container',
    '#prefix' => '<div id="visit-form">',
    '#suffix' => '</div>',
  );

  if (!empty($form_state['values']['time_slot'])) {
    $form['visit_form_container']['visit_form'] = drupal_get_form('visit_scheduler_form');
  } else {
    $form['visit_form_container']['visit_form'] = array(
      '#markup' => t('No time slot selected.'),
    );
  }

  return $form;
}


/**
 * AJAX callback to get the visit scheduler form.
 */
function visit_scheduler_ajax_get_form($form, &$form_state) {
  watchdog('visit_scheduler', 'AJAX callback triggered. Form state: @state', array('@state' => print_r($form_state, TRUE)), WATCHDOG_DEBUG);

  if (!empty($form_state['values']['time_slot'])) {
    $form['visit_form_container']['visit_form'] = drupal_get_form('visit_scheduler_form');
  } else {
    $form['visit_form_container']['visit_form'] = array(
      '#markup' => t('No time slot selected.'),
    );
  }

  return $form['visit_form_container'];
}


/**
 * Form constructor for the visit scheduler form.
 */
function visit_scheduler_form($form, &$form_state) {
  $form['name'] = array(
    '#type' => 'textfield',
    '#title' => t('Name and Surname / Institution'),
    '#required' => TRUE,
  );

  $form['email'] = array(
    '#type' => 'textfield',
    '#title' => t('Email Address'),
    '#required' => TRUE,
  );

  $form['phone'] = array(
    '#type' => 'textfield',
    '#title' => t('Phone'),
    '#required' => TRUE,
  );

  $form['visitors'] = array(
    '#type' => 'textfield',
    '#title' => t('Number of visitors'),
    '#required' => TRUE,
    '#element_validate' => array('element_validate_integer_positive'),
  );

  $form['age'] = array(
    '#type' => 'textfield',
    '#title' => t('For students, indicate age'),
  );

  $form['participants'] = array(
    '#type' => 'textarea',
    '#title' => t('List of participants (group minimum 5 and maximum 35 people)'),
    '#required' => TRUE,
  );

  $form['submit'] = array(
    '#type' => 'submit',
    '#value' => t('Schedule visit'),
  );

  return $form;
}

/**
 * Form validation handler for visit_scheduler_form().
 */
function visit_scheduler_form_validate($form, &$form_state) {
  if ($form_state['values']['visitors'] < 5 || $form_state['values']['visitors'] > 35) {
    form_set_error('visitors', t('Number of visitors must be between 5 and 35.'));
  }
}

/**
 * Form submission handler for visit_scheduler_form().
 */
function visit_scheduler_form_submit($form, &$form_state) {
  drupal_set_message(t('The visit has been successfully scheduled.'));
}

And the js code that does the initial ajax request

  Drupal.behaviors.visitScheduler = {
    attach: function (context, settings) {
      $('#visit-calendar', context).once('visit-scheduler', function () {
        $(this).datepicker({
          dateFormat: 'dd-mm-yy',
          minDate: 0,
          maxDate: '+1Y',
          beforeShowDay: function (date) {
            var day = date.getDay();
            return [(day === 4), '']; // Only allow Thursdays
          },
          onSelect: function (dateText, inst) {
            console.log('Date selected:', dateText);
            $.ajax({
              url: Drupal.settings.basePath + 'ajax/visit-scheduler/get-time-slots',
              type: 'POST',
              data: { date: dateText },
              dataType: 'json',
              success: function (response) {
                console.log('Time slots loaded');
                $('#time-slots').html(response.html);
                Drupal.attachBehaviors();
              },
            });
          },
        });
      });
    },
  };

})(jQuery);

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Browse other questions tagged or ask your own question.