694 lines
24 KiB
Plaintext
694 lines
24 KiB
Plaintext
<?php
|
|
|
|
/**
|
|
* @file
|
|
* AJAX Examples module file with basic examples.
|
|
*/
|
|
|
|
/**
|
|
* @defgroup ajax_example Example: AJAX
|
|
* @ingroup examples
|
|
* @{
|
|
* These examples show basic AJAX concepts.
|
|
*
|
|
* General documentation is available at
|
|
* @link ajax AJAX Framework documentation @endlink and at the
|
|
* @link http://drupal.org/node/752056 AJAX Forms handbook page @endlink.
|
|
*
|
|
* The several examples here demonstrate basic AJAX usage.
|
|
*/
|
|
|
|
// The Node Form Alter example needs to be in another file.
|
|
module_load_include('inc', 'ajax_example', 'ajax_example_node_form_alter');
|
|
|
|
/**
|
|
* Implements hook_menu().
|
|
*
|
|
* Sets up calls to drupal_get_form() for all our example cases.
|
|
*
|
|
* @see menu_example.module
|
|
* @see menu_example_menu()
|
|
*/
|
|
function ajax_example_menu() {
|
|
$items = array();
|
|
|
|
$items['examples/ajax_example'] = array(
|
|
'title' => 'AJAX Example',
|
|
'page callback' => 'ajax_example_intro',
|
|
'access callback' => TRUE,
|
|
'expanded' => TRUE,
|
|
);
|
|
|
|
// Change the description of a form element.
|
|
$items['examples/ajax_example/simplest'] = array(
|
|
'title' => 'Simplest AJAX Example',
|
|
'page callback' => 'drupal_get_form',
|
|
'page arguments' => array('ajax_example_simplest'),
|
|
'access callback' => TRUE,
|
|
'weight' => 0,
|
|
);
|
|
// Generate a changing number of checkboxes.
|
|
$items['examples/ajax_example/autocheckboxes'] = array(
|
|
'title' => 'Generate checkboxes',
|
|
'page callback' => 'drupal_get_form',
|
|
'page arguments' => array('ajax_example_autocheckboxes'),
|
|
'access callback' => TRUE,
|
|
'weight' => 1,
|
|
);
|
|
// Generate different textfields based on form state.
|
|
$items['examples/ajax_example/autotextfields'] = array(
|
|
'title' => 'Generate textfields',
|
|
'page callback' => 'drupal_get_form',
|
|
'page arguments' => array('ajax_example_autotextfields'),
|
|
'access callback' => TRUE,
|
|
'weight' => 2,
|
|
);
|
|
|
|
// Submit a form without a page reload.
|
|
$items['examples/ajax_example/submit_driven_ajax'] = array(
|
|
'title' => 'Submit-driven AJAX',
|
|
'page callback' => 'drupal_get_form',
|
|
'page arguments' => array('ajax_example_submit_driven_ajax'),
|
|
'access callback' => TRUE,
|
|
'weight' => 3,
|
|
);
|
|
|
|
// Repopulate a dropdown based on form state.
|
|
$items['examples/ajax_example/dependent_dropdown'] = array(
|
|
'title' => 'Dependent dropdown',
|
|
'page callback' => 'drupal_get_form',
|
|
'page arguments' => array('ajax_example_dependent_dropdown'),
|
|
'access callback' => TRUE,
|
|
'weight' => 4,
|
|
);
|
|
// Repopulate a dropdown, but this time with graceful degredation.
|
|
// See ajax_example_graceful_degradation.inc.
|
|
$items['examples/ajax_example/dependent_dropdown_degrades'] = array(
|
|
'title' => 'Dependent dropdown (with graceful degradation)',
|
|
'page callback' => 'drupal_get_form',
|
|
'page arguments' => array('ajax_example_dependent_dropdown_degrades'),
|
|
'access callback' => TRUE,
|
|
'weight' => 5,
|
|
'file' => 'ajax_example_graceful_degradation.inc',
|
|
);
|
|
// The above example as it appears to users with no javascript.
|
|
$items['examples/ajax_example/dependent_dropdown_degrades_no_js'] = array(
|
|
'title' => 'Dependent dropdown with javascript off',
|
|
'page callback' => 'drupal_get_form',
|
|
'page arguments' => array('ajax_example_dependent_dropdown_degrades', TRUE),
|
|
'access callback' => TRUE,
|
|
'file' => 'ajax_example_graceful_degradation.inc',
|
|
'weight' => 5,
|
|
);
|
|
|
|
// Populate a form section based on input in another element.
|
|
$items['examples/ajax_example/dynamic_sections'] = array(
|
|
'title' => 'Dynamic Sections (with graceful degradation)',
|
|
'page callback' => 'drupal_get_form',
|
|
'page arguments' => array('ajax_example_dynamic_sections'),
|
|
'access callback' => TRUE,
|
|
'weight' => 6,
|
|
'file' => 'ajax_example_graceful_degradation.inc',
|
|
);
|
|
// The above example as it appears to users with no javascript.
|
|
$items['examples/ajax_example/dynamic_sections_no_js'] = array(
|
|
'title' => 'Dynamic Sections w/JS turned off',
|
|
'page callback' => 'drupal_get_form',
|
|
'page arguments' => array('ajax_example_dynamic_sections', TRUE),
|
|
'access callback' => TRUE,
|
|
'weight' => 6,
|
|
'file' => 'ajax_example_graceful_degradation.inc',
|
|
);
|
|
|
|
// A classic multi-step wizard, but with no page reloads.
|
|
// See ajax_example_graceful_degradation.inc.
|
|
$items['examples/ajax_example/wizard'] = array(
|
|
'title' => 'Wizard (with graceful degradation)',
|
|
'page callback' => 'drupal_get_form',
|
|
'page arguments' => array('ajax_example_wizard'),
|
|
'access callback' => TRUE,
|
|
'file' => 'ajax_example_graceful_degradation.inc',
|
|
'weight' => 7,
|
|
);
|
|
// The above example as it appears to users with no javascript.
|
|
$items['examples/ajax_example/wizard_no_js'] = array(
|
|
'title' => 'Wizard w/JS turned off',
|
|
'page callback' => 'drupal_get_form',
|
|
'page arguments' => array('ajax_example_wizard', TRUE),
|
|
'access callback' => TRUE,
|
|
'file' => 'ajax_example_graceful_degradation.inc',
|
|
'weight' => 7,
|
|
);
|
|
|
|
// Add-more button that creates additional form elements.
|
|
// See ajax_example_graceful_degradation.inc.
|
|
$items['examples/ajax_example/add_more'] = array(
|
|
'title' => 'Add-more button (with graceful degradation)',
|
|
'page callback' => 'drupal_get_form',
|
|
'page arguments' => array('ajax_example_add_more'),
|
|
'access callback' => TRUE,
|
|
'file' => 'ajax_example_graceful_degradation.inc',
|
|
'weight' => 8,
|
|
);
|
|
// The above example as it appears to users with no javascript.
|
|
$items['examples/ajax_example/add_more_no_js'] = array(
|
|
'title' => 'Add-more button w/JS turned off',
|
|
'page callback' => 'drupal_get_form',
|
|
'page arguments' => array('ajax_example_add_more', TRUE),
|
|
'access callback' => TRUE,
|
|
'file' => 'ajax_example_graceful_degradation.inc',
|
|
'weight' => 8,
|
|
);
|
|
|
|
// Use the AJAX framework outside the context of a form using the use-ajax
|
|
// class. See ajax_example_misc.inc.
|
|
$items['examples/ajax_example/ajax_link'] = array(
|
|
'title' => 'Ajax Link ("use-ajax" class)',
|
|
'page callback' => 'ajax_example_render_link',
|
|
'access callback' => TRUE,
|
|
'file' => 'ajax_example_misc.inc',
|
|
'weight' => 9,
|
|
);
|
|
// Use the AJAX framework outside the context of a form using a renderable
|
|
// array of type link with the #ajax property. See ajax_example_misc.inc.
|
|
$items['examples/ajax_example/ajax_link_renderable'] = array(
|
|
'title' => 'Ajax Link (Renderable Array)',
|
|
'page callback' => 'ajax_example_render_link_ra',
|
|
'access callback' => TRUE,
|
|
'file' => 'ajax_example_misc.inc',
|
|
'weight' => 9,
|
|
);
|
|
// A menu callback is required when using ajax outside of the Form API.
|
|
$items['ajax_link_callback'] = array(
|
|
'page callback' => 'ajax_link_response',
|
|
'access callback' => 'user_access',
|
|
'access arguments' => array('access content'),
|
|
'type' => MENU_CALLBACK,
|
|
'file' => 'ajax_example_misc.inc',
|
|
);
|
|
|
|
// Use AJAX framework commands outside of the #ajax form property.
|
|
// See ajax_example_advanced.inc.
|
|
$items['examples/ajax_example/advanced_commands'] = array(
|
|
'title' => 'AJAX framework commands',
|
|
'page callback' => 'drupal_get_form',
|
|
'page arguments' => array('ajax_example_advanced_commands'),
|
|
'access callback' => TRUE,
|
|
'file' => 'ajax_example_advanced.inc',
|
|
'weight' => 100,
|
|
);
|
|
|
|
// Autocomplete examples.
|
|
$items['examples/ajax_example/simple_autocomplete'] = array(
|
|
'title' => 'Autocomplete (simple)',
|
|
'page callback' => 'drupal_get_form',
|
|
'page arguments' => array('ajax_example_simple_autocomplete'),
|
|
'access arguments' => array('access user profiles'),
|
|
'file' => 'ajax_example_autocomplete.inc',
|
|
'weight' => 10,
|
|
);
|
|
$items['examples/ajax_example/simple_user_autocomplete_callback'] = array(
|
|
'page callback' => 'ajax_example_simple_user_autocomplete_callback',
|
|
'file' => 'ajax_example_autocomplete.inc',
|
|
'type' => MENU_CALLBACK,
|
|
'access arguments' => array('access user profiles'),
|
|
);
|
|
$items['examples/ajax_example/node_autocomplete'] = array(
|
|
'title' => 'Autocomplete (node with nid)',
|
|
'page callback' => 'drupal_get_form',
|
|
'page arguments' => array('ajax_example_unique_autocomplete'),
|
|
'access arguments' => array('access content'),
|
|
'file' => 'ajax_example_autocomplete.inc',
|
|
'weight' => 11,
|
|
);
|
|
$items['examples/ajax_example/unique_node_autocomplete_callback'] = array(
|
|
'page callback' => 'ajax_example_unique_node_autocomplete_callback',
|
|
'file' => 'ajax_example_autocomplete.inc',
|
|
'type' => MENU_CALLBACK,
|
|
'access arguments' => array('access content'),
|
|
);
|
|
$items['examples/ajax_example/node_by_author'] = array(
|
|
'title' => 'Autocomplete (node limited by author)',
|
|
'page callback' => 'drupal_get_form',
|
|
'page arguments' => array('ajax_example_node_by_author_autocomplete'),
|
|
'access callback' => TRUE,
|
|
'file' => 'ajax_example_autocomplete.inc',
|
|
'weight' => 12,
|
|
);
|
|
$items['examples/ajax_example/node_by_author_autocomplete'] = array(
|
|
'page callback' => 'ajax_example_node_by_author_node_autocomplete_callback',
|
|
'file' => 'ajax_example_autocomplete.inc',
|
|
'type' => MENU_CALLBACK,
|
|
'access arguments' => array('access content'),
|
|
);
|
|
// This is the landing page for the progress bar example. It uses
|
|
// drupal_get_form() in order to build the form.
|
|
$items['examples/ajax_example/progressbar'] = array(
|
|
'title' => 'Progress bar example',
|
|
'page callback' => 'drupal_get_form',
|
|
'page arguments' => array('ajax_example_progressbar_form'),
|
|
'access arguments' => array('access content'),
|
|
'file' => 'ajax_example_progressbar.inc',
|
|
);
|
|
// This is the callback route for the AJAX-based progress bar.
|
|
$items['examples/ajax_example/progressbar/progress/%'] = array(
|
|
'title' => 'Progress bar progress',
|
|
'page callback' => 'ajax_example_progressbar_progress',
|
|
'page arguments' => array(4),
|
|
'type' => MENU_CALLBACK,
|
|
'access arguments' => array('access content'),
|
|
'file' => 'ajax_example_progressbar.inc',
|
|
);
|
|
|
|
return $items;
|
|
}
|
|
|
|
/**
|
|
* A basic introduction page for the ajax_example module.
|
|
*/
|
|
function ajax_example_intro() {
|
|
$markup = t('The AJAX example module provides many examples of AJAX including forms, links, and AJAX commands.');
|
|
|
|
$list[] = l(t('Simplest AJAX Example'), 'examples/ajax_example/simplest');
|
|
$list[] = l(t('Generate checkboxes'), 'examples/ajax_example/autocheckboxes');
|
|
$list[] = l(t('Generate textfields'), 'examples/ajax_example/autotextfields');
|
|
$list[] = l(t('Submit-driven AJAX'), 'examples/ajax_example/submit_driven_ajax');
|
|
$list[] = l(t('Dependent dropdown'), 'examples/ajax_example/dependent_dropdown');
|
|
$list[] = l(t('Dependent dropdown (with graceful degradation)'), 'examples/ajax_example/dependent_dropdown_degrades');
|
|
$list[] = l(t('Dynamic Sections w/JS turned off'), 'examples/ajax_example/dependent_dropdown_degrades_no_js');
|
|
$list[] = l(t('Wizard (with graceful degradation)'), 'examples/ajax_example/wizard');
|
|
$list[] = l(t('Wizard w/JS turned off'), 'examples/ajax_example/wizard_no_js');
|
|
$list[] = l(t('Add-more button (with graceful degradation)'), 'examples/ajax_example/add_more');
|
|
$list[] = l(t('Add-more button w/JS turned off'), 'examples/ajax_example/add_more_no_js');
|
|
$list[] = l(t('Ajax Link ("use-ajax" class)'), 'examples/ajax_example/ajax_link');
|
|
$list[] = l(t('Ajax Link (Renderable Array)'), 'examples/ajax_example/ajax_link_renderable');
|
|
$list[] = l(t('AJAX framework commands'), 'examples/ajax_example/advanced_commands');
|
|
$list[] = l(t('Autocomplete (simple)'), 'examples/ajax_example/simple_autocomplete');
|
|
$list[] = l(t('Autocomplete (node with nid)'), 'examples/ajax_example/node_autocomplete');
|
|
$list[] = l(t('Autocomplete (node limited by author)'), 'examples/ajax_example/node_by_author');
|
|
|
|
$variables['items'] = $list;
|
|
$variables['type'] = 'ul';
|
|
$markup .= theme('item_list', $variables);
|
|
|
|
return $markup;
|
|
}
|
|
|
|
/**
|
|
* Basic AJAX callback example.
|
|
*
|
|
* Simple form whose ajax-enabled 'changethis' member causes a text change
|
|
* in the description of the 'replace_textfield' member.
|
|
*
|
|
* See @link http://drupal.org/node/262422 Form API Tutorial @endlink
|
|
*/
|
|
function ajax_example_simplest($form, &$form_state) {
|
|
$form = array();
|
|
$form['changethis'] = array(
|
|
'#title' => t("Choose something and explain why"),
|
|
'#type' => 'select',
|
|
'#options' => array(
|
|
'one' => 'one',
|
|
'two' => 'two',
|
|
'three' => 'three',
|
|
),
|
|
'#ajax' => array(
|
|
// #ajax has two required keys: callback and wrapper.
|
|
// 'callback' is a function that will be called when this element changes.
|
|
'callback' => 'ajax_example_simplest_callback',
|
|
// 'wrapper' is the HTML id of the page element that will be replaced.
|
|
'wrapper' => 'replace_textfield_div',
|
|
// There are also several optional keys - see ajax_example_autocheckboxes
|
|
// below for details on 'method', 'effect' and 'speed' and
|
|
// ajax_example_dependent_dropdown for 'event'.
|
|
),
|
|
);
|
|
|
|
// This entire form element will be replaced whenever 'changethis' is updated.
|
|
$form['replace_textfield'] = array(
|
|
'#type' => 'textfield',
|
|
'#title' => t("Why"),
|
|
// The prefix/suffix provide the div that we're replacing, named by
|
|
// #ajax['wrapper'] above.
|
|
'#prefix' => '<div id="replace_textfield_div">',
|
|
'#suffix' => '</div>',
|
|
);
|
|
|
|
// An AJAX request calls the form builder function for every change.
|
|
// We can change how we build the form based on $form_state.
|
|
if (!empty($form_state['values']['changethis'])) {
|
|
$form['replace_textfield']['#description'] = t("Say why you chose '@value'", array('@value' => $form_state['values']['changethis']));
|
|
}
|
|
return $form;
|
|
}
|
|
|
|
/**
|
|
* Callback for ajax_example_simplest.
|
|
*
|
|
* On an ajax submit, the form builder function is called again, then the $form
|
|
* and $form_state are passed to this callback function so it can select which
|
|
* portion of the form to send on to the client.
|
|
*
|
|
* @return array
|
|
* Renderable array (the textfield element)
|
|
*/
|
|
function ajax_example_simplest_callback($form, $form_state) {
|
|
// The form has already been submitted and updated. We can return the replaced
|
|
// item as it is.
|
|
return $form['replace_textfield'];
|
|
}
|
|
|
|
/**
|
|
* Form manipulation through AJAX.
|
|
*
|
|
* AJAX-enabled select element causes replacement of a set of checkboxes
|
|
* based on the selection.
|
|
*/
|
|
function ajax_example_autocheckboxes($form, &$form_state) {
|
|
// 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;
|
|
|
|
$form['howmany_select'] = array(
|
|
'#title' => t('How many checkboxes do you want?'),
|
|
'#type' => 'select',
|
|
'#options' => array(1 => 1, 2 => 2, 3 => 3, 4 => 4),
|
|
'#default_value' => $num_checkboxes,
|
|
'#ajax' => array(
|
|
'callback' => 'ajax_example_autocheckboxes_callback',
|
|
'wrapper' => 'checkboxes-div',
|
|
// 'method' defaults to replaceWith, but valid values also include
|
|
// append, prepend, before and after.
|
|
// 'method' => 'replaceWith',
|
|
// 'effect' defaults to none. Other valid values are 'fade' and 'slide'.
|
|
// See ajax_example_autotextfields for an example of 'fade'.
|
|
'effect' => 'slide',
|
|
// 'speed' defaults to 'slow'. You can also use 'fast'
|
|
// or a number of milliseconds for the animation to last.
|
|
// 'speed' => 'slow',
|
|
// Don't show any throbber...
|
|
'progress' => array('type' => 'none'),
|
|
),
|
|
);
|
|
|
|
$form['checkboxes_fieldset'] = array(
|
|
'#title' => t("Generated Checkboxes"),
|
|
// The prefix/suffix provide the div that we're replacing, named by
|
|
// #ajax['wrapper'] above.
|
|
'#prefix' => '<div id="checkboxes-div">',
|
|
'#suffix' => '</div>',
|
|
'#type' => 'fieldset',
|
|
'#description' => t('This is where we get automatically generated checkboxes'),
|
|
);
|
|
|
|
for ($i = 1; $i <= $num_checkboxes; $i++) {
|
|
$form['checkboxes_fieldset']["checkbox$i"] = array(
|
|
'#type' => 'checkbox',
|
|
'#title' => "Checkbox $i",
|
|
);
|
|
}
|
|
|
|
$form['submit'] = array(
|
|
'#type' => 'submit',
|
|
'#value' => t('Submit'),
|
|
);
|
|
|
|
return $form;
|
|
}
|
|
|
|
/**
|
|
* Callback for autocheckboxes.
|
|
*
|
|
* 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.
|
|
* See @link ajax_example_advanced.inc AJAX Advanced Commands for more details
|
|
* on AJAX framework commands.
|
|
*
|
|
* @return array
|
|
* Renderable array (the checkboxes fieldset)
|
|
*/
|
|
function ajax_example_autocheckboxes_callback($form, $form_state) {
|
|
return $form['checkboxes_fieldset'];
|
|
}
|
|
|
|
|
|
/**
|
|
* Show/hide textfields based on AJAX-enabled checkbox clicks.
|
|
*/
|
|
function ajax_example_autotextfields($form, &$form_state) {
|
|
|
|
$form['ask_first_name'] = array(
|
|
'#type' => 'checkbox',
|
|
'#title' => t('Ask me my first name'),
|
|
'#ajax' => array(
|
|
'callback' => 'ajax_example_autotextfields_callback',
|
|
'wrapper' => 'textfields',
|
|
'effect' => 'fade',
|
|
),
|
|
);
|
|
$form['ask_last_name'] = array(
|
|
'#type' => 'checkbox',
|
|
'#title' => t('Ask me my last name'),
|
|
'#ajax' => array(
|
|
'callback' => 'ajax_example_autotextfields_callback',
|
|
'wrapper' => 'textfields',
|
|
'effect' => 'fade',
|
|
),
|
|
);
|
|
|
|
$form['textfields'] = array(
|
|
'#title' => t("Generated text fields for first and last name"),
|
|
'#prefix' => '<div id="textfields">',
|
|
'#suffix' => '</div>',
|
|
'#type' => 'fieldset',
|
|
'#description' => t('This is where we put automatically generated textfields'),
|
|
);
|
|
|
|
// Since checkboxes return TRUE or FALSE, we have to check that
|
|
// $form_state has been filled as well as what it contains.
|
|
if (!empty($form_state['values']['ask_first_name']) && $form_state['values']['ask_first_name']) {
|
|
$form['textfields']['first_name'] = array(
|
|
'#type' => 'textfield',
|
|
'#title' => t('First Name'),
|
|
);
|
|
}
|
|
if (!empty($form_state['values']['ask_last_name']) && $form_state['values']['ask_last_name']) {
|
|
$form['textfields']['last_name'] = array(
|
|
'#type' => 'textfield',
|
|
'#title' => t('Last Name'),
|
|
);
|
|
}
|
|
|
|
$form['submit'] = array(
|
|
'#type' => 'submit',
|
|
'#value' => t('Click Me'),
|
|
);
|
|
|
|
return $form;
|
|
}
|
|
|
|
/**
|
|
* Callback for autotextfields.
|
|
*
|
|
* Selects the piece of the form we want to use as replacement text and returns
|
|
* it as a form (renderable array).
|
|
*
|
|
* @return array
|
|
* Renderable array (the textfields element)
|
|
*/
|
|
function ajax_example_autotextfields_callback($form, $form_state) {
|
|
return $form['textfields'];
|
|
}
|
|
|
|
|
|
/**
|
|
* A very basic form which with an AJAX-enabled submit.
|
|
*
|
|
* On submit, the markup in the #markup element is updated.
|
|
*/
|
|
function ajax_example_submit_driven_ajax($form, &$form_state) {
|
|
$form['box'] = array(
|
|
'#type' => 'markup',
|
|
'#prefix' => '<div id="box">',
|
|
'#suffix' => '</div>',
|
|
'#markup' => '<h1>Initial markup for box</h1>',
|
|
);
|
|
|
|
$form['submit'] = array(
|
|
'#type' => 'submit',
|
|
'#ajax' => array(
|
|
'callback' => 'ajax_example_submit_driven_callback',
|
|
'wrapper' => 'box',
|
|
),
|
|
'#value' => t('Submit'),
|
|
);
|
|
|
|
return $form;
|
|
}
|
|
|
|
/**
|
|
* Callback for submit_driven example.
|
|
*
|
|
* Select the 'box' element, change the markup in it, and return it as a
|
|
* renderable array.
|
|
*
|
|
* @return array
|
|
* Renderable array (the box element)
|
|
*/
|
|
function ajax_example_submit_driven_callback($form, $form_state) {
|
|
// In most cases, it is recommended that you put this logic in form generation
|
|
// rather than the callback. Submit driven forms are an exception, because
|
|
// you may not want to return the form at all.
|
|
$element = $form['box'];
|
|
$element['#markup'] = "Clicked submit ({$form_state['values']['op']}): " . date('c');
|
|
return $element;
|
|
}
|
|
|
|
|
|
/**
|
|
* AJAX-based dropdown example form.
|
|
*
|
|
* A form with a dropdown whose options are dependent on a
|
|
* choice made in a previous dropdown.
|
|
*
|
|
* On changing the first dropdown, the options in the second
|
|
* are updated.
|
|
*/
|
|
function ajax_example_dependent_dropdown($form, &$form_state) {
|
|
// Get the list of options to populate the first dropdown.
|
|
$options_first = _ajax_example_get_first_dropdown_options();
|
|
// If we have a value for the first dropdown from $form_state['values'] we use
|
|
// this both as the default value for the first dropdown and also as a
|
|
// parameter to pass to the function that retrieves the options for the
|
|
// second dropdown.
|
|
$selected = isset($form_state['values']['dropdown_first']) ? $form_state['values']['dropdown_first'] : key($options_first);
|
|
|
|
$form['dropdown_first'] = array(
|
|
'#type' => 'select',
|
|
'#title' => 'Instrument Type',
|
|
'#options' => $options_first,
|
|
'#default_value' => $selected,
|
|
// Bind an ajax callback to the change event (which is the default for the
|
|
// select form type) of the first dropdown. It will replace the second
|
|
// dropdown when rebuilt.
|
|
'#ajax' => array(
|
|
// When 'event' occurs, Drupal will perform an ajax request in the
|
|
// background. Usually the default value is sufficient (eg. change for
|
|
// select elements), but valid values include any jQuery event,
|
|
// most notably 'mousedown', 'blur', and 'submit'.
|
|
// 'event' => 'change',
|
|
'callback' => 'ajax_example_dependent_dropdown_callback',
|
|
'wrapper' => 'dropdown-second-replace',
|
|
),
|
|
);
|
|
|
|
$form['dropdown_second'] = array(
|
|
'#type' => 'select',
|
|
'#title' => $options_first[$selected] . ' ' . t('Instruments'),
|
|
// The entire enclosing div created here gets replaced when dropdown_first
|
|
// is changed.
|
|
'#prefix' => '<div id="dropdown-second-replace">',
|
|
'#suffix' => '</div>',
|
|
// When the form is rebuilt during ajax processing, the $selected variable
|
|
// will now have the new value and so the options will change.
|
|
'#options' => _ajax_example_get_second_dropdown_options($selected),
|
|
'#default_value' => isset($form_state['values']['dropdown_second']) ? $form_state['values']['dropdown_second'] : '',
|
|
);
|
|
$form['submit'] = array(
|
|
'#type' => 'submit',
|
|
'#value' => t('Submit'),
|
|
);
|
|
return $form;
|
|
}
|
|
|
|
/**
|
|
* Selects just the second dropdown to be returned for re-rendering.
|
|
*
|
|
* Since the controlling logic for populating the form is in the form builder
|
|
* function, all we do here is select the element and return it to be updated.
|
|
*
|
|
* @return array
|
|
* Renderable array (the second dropdown)
|
|
*/
|
|
function ajax_example_dependent_dropdown_callback($form, $form_state) {
|
|
return $form['dropdown_second'];
|
|
}
|
|
|
|
/**
|
|
* Helper function to populate the first dropdown.
|
|
*
|
|
* This would normally be pulling data from the database.
|
|
*
|
|
* @return array
|
|
* Dropdown options.
|
|
*/
|
|
function _ajax_example_get_first_dropdown_options() {
|
|
// drupal_map_assoc() just makes an array('String' => 'String'...).
|
|
return drupal_map_assoc(
|
|
array(
|
|
t('String'),
|
|
t('Woodwind'),
|
|
t('Brass'),
|
|
t('Percussion'),
|
|
)
|
|
);
|
|
}
|
|
|
|
/**
|
|
* Helper function to populate the second dropdown.
|
|
*
|
|
* This would normally be pulling data from the database.
|
|
*
|
|
* @param string $key
|
|
* This will determine which set of options is returned.
|
|
*
|
|
* @return array
|
|
* Dropdown options
|
|
*/
|
|
function _ajax_example_get_second_dropdown_options($key = '') {
|
|
$options = array(
|
|
t('String') => drupal_map_assoc(
|
|
array(
|
|
t('Violin'),
|
|
t('Viola'),
|
|
t('Cello'),
|
|
t('Double Bass'),
|
|
)
|
|
),
|
|
t('Woodwind') => drupal_map_assoc(
|
|
array(
|
|
t('Flute'),
|
|
t('Clarinet'),
|
|
t('Oboe'),
|
|
t('Bassoon'),
|
|
)
|
|
),
|
|
t('Brass') => drupal_map_assoc(
|
|
array(
|
|
t('Trumpet'),
|
|
t('Trombone'),
|
|
t('French Horn'),
|
|
t('Euphonium'),
|
|
)
|
|
),
|
|
t('Percussion') => drupal_map_assoc(
|
|
array(
|
|
t('Bass Drum'),
|
|
t('Timpani'),
|
|
t('Snare Drum'),
|
|
t('Tambourine'),
|
|
)
|
|
),
|
|
);
|
|
if (isset($options[$key])) {
|
|
return $options[$key];
|
|
}
|
|
else {
|
|
return array();
|
|
}
|
|
}
|
|
/**
|
|
* @} End of "defgroup ajax_example".
|
|
*/
|