| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693 | <?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". */
 |