ajax_example.module

  1. examples
    1. 7 ajax_example/ajax_example.module
    2. 8 ajax_example/ajax_example.module

AJAX Examples module file with basic examples.

Functions & methods

NameDescription
ajax_example_autocheckboxesAJAX-enabled select element causes replacement of a set of checkboxes based on the selection.
ajax_example_autocheckboxes_callbackCallback 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_example_autotextfieldsShow/hide textfields based on AJAX-enabled checkbox clicks.
ajax_example_autotextfields_callbackSelects the piece of the form we want to use as replacement text and returns it as a form (renderable array).
ajax_example_dependent_dropdownA form with a dropdown whose options are dependent on a choice made in a previous dropdown.
ajax_example_dependent_dropdown_callbackSelects just the second dropdown to be returned for re-rendering
ajax_example_intro
ajax_example_menuImplements hook_menu().
ajax_example_simplestSimple form whose ajax-enabled 'changethis' member causes a text change in the description of the 'replace_textfield' member. See Form API Tutorial
ajax_example_simplest_callbackCallback for ajax_example_simplest.
ajax_example_submit_driven_ajaxA very basic form which with an AJAX-enabled submit.
ajax_example_submit_driven_callbackSelect the 'box' element, change the markup in it, and return it as a renderable array.
_ajax_example_get_first_dropdown_optionsHelper function to populate the first dropdown. This would normally be pulling data from the database.
_ajax_example_get_second_dropdown_optionsHelper function to populate the second dropdown. This would normally be pulling data from the database.

File

ajax_example/ajax_example.module
View source
  1. <?php
  2. /**
  3. * @file
  4. * AJAX Examples module file with basic examples.
  5. */
  6. /**
  7. * @defgroup ajax_example Example: AJAX
  8. * @ingroup examples
  9. * @{
  10. * These examples show basic AJAX concepts.
  11. *
  12. * General documentation is available at
  13. * @link ajax AJAX Framework documentation @endlink and at the
  14. * @link http://drupal.org/node/752056 AJAX Forms handbook page @endlink.
  15. *
  16. * The several examples here demonstrate basic AJAX usage.
  17. */
  18. // The Node Form Alter example needs to be in another file.
  19. module_load_include('inc', 'ajax_example', 'ajax_example_node_form_alter');
  20. /**
  21. * Implements hook_menu().
  22. *
  23. * Sets up calls to drupal_get_form() for all our example cases.
  24. *
  25. * @see menu_example.module for more details on hook_menu().
  26. */
  27. function ajax_example_menu() {
  28. $items = array();
  29. $items['examples/ajax_example'] = array(
  30. 'title' => 'AJAX Example',
  31. 'page callback' => 'ajax_example_intro',
  32. 'access callback' => TRUE,
  33. 'expanded' => TRUE,
  34. );
  35. // Change the description of a form element.
  36. $items['examples/ajax_example/simplest'] = array(
  37. 'title' => 'Simplest AJAX Example',
  38. 'page callback' => 'drupal_get_form',
  39. 'page arguments' => array('ajax_example_simplest'),
  40. 'access callback' => TRUE,
  41. 'weight' => 0,
  42. );
  43. // Generate a changing number of checkboxes.
  44. $items['examples/ajax_example/autocheckboxes'] = array(
  45. 'title' => 'Generate checkboxes',
  46. 'page callback' => 'drupal_get_form',
  47. 'page arguments' => array('ajax_example_autocheckboxes'),
  48. 'access callback' => TRUE,
  49. 'weight' => 1,
  50. );
  51. // Generate different textfields based on form state.
  52. $items['examples/ajax_example/autotextfields'] = array(
  53. 'title' => 'Generate textfields',
  54. 'page callback' => 'drupal_get_form',
  55. 'page arguments' => array('ajax_example_autotextfields'),
  56. 'access callback' => TRUE,
  57. 'weight' => 2,
  58. );
  59. // Submit a form without a page reload.
  60. $items['examples/ajax_example/submit_driven_ajax'] = array(
  61. 'title' => 'Submit-driven AJAX',
  62. 'page callback' => 'drupal_get_form',
  63. 'page arguments' => array('ajax_example_submit_driven_ajax'),
  64. 'access callback' => TRUE,
  65. 'weight' => 3,
  66. );
  67. // Repopulate a dropdown based on form state.
  68. $items['examples/ajax_example/dependent_dropdown'] = array(
  69. 'title' => 'Dependent dropdown',
  70. 'page callback' => 'drupal_get_form',
  71. 'page arguments' => array('ajax_example_dependent_dropdown'),
  72. 'access callback' => TRUE,
  73. 'weight' => 4,
  74. );
  75. // Repopulate a dropdown, but this time with graceful degredation.
  76. // See ajax_example_graceful_degradation.inc.
  77. $items['examples/ajax_example/dependent_dropdown_degrades'] = array(
  78. 'title' => 'Dependent dropdown (with graceful degradation)',
  79. 'page callback' => 'drupal_get_form',
  80. 'page arguments' => array('ajax_example_dependent_dropdown_degrades'),
  81. 'access callback' => TRUE,
  82. 'weight' => 5,
  83. 'file' => 'ajax_example_graceful_degradation.inc',
  84. );
  85. // The above example as it appears to users with no javascript.
  86. $items['examples/ajax_example/dependent_dropdown_degrades_no_js'] = array(
  87. 'title' => 'Dependent dropdown with javascript off',
  88. 'page callback' => 'drupal_get_form',
  89. 'page arguments' => array('ajax_example_dependent_dropdown_degrades', TRUE),
  90. 'access callback' => TRUE,
  91. 'file' => 'ajax_example_graceful_degradation.inc',
  92. 'weight' => 5,
  93. );
  94. // Populate a form section based on input in another element.
  95. $items['examples/ajax_example/dynamic_sections'] = array(
  96. 'title' => 'Dynamic Sections (with graceful degradation)',
  97. 'page callback' => 'drupal_get_form',
  98. 'page arguments' => array('ajax_example_dynamic_sections'),
  99. 'access callback' => TRUE,
  100. 'weight' => 6,
  101. 'file' => 'ajax_example_graceful_degradation.inc',
  102. );
  103. // The above example as it appears to users with no javascript.
  104. $items['examples/ajax_example/dynamic_sections_no_js'] = array(
  105. 'title' => 'Dynamic Sections w/JS turned off',
  106. 'page callback' => 'drupal_get_form',
  107. 'page arguments' => array('ajax_example_dynamic_sections', TRUE),
  108. 'access callback' => TRUE,
  109. 'weight' => 6,
  110. 'file' => 'ajax_example_graceful_degradation.inc',
  111. );
  112. // A classic multi-step wizard, but with no page reloads.
  113. // See ajax_example_graceful_degradation.inc.
  114. $items['examples/ajax_example/wizard'] = array(
  115. 'title' => 'Wizard (with graceful degradation)',
  116. 'page callback' => 'drupal_get_form',
  117. 'page arguments' => array('ajax_example_wizard'),
  118. 'access callback' => TRUE,
  119. 'file' => 'ajax_example_graceful_degradation.inc',
  120. 'weight' => 7,
  121. );
  122. // The above example as it appears to users with no javascript.
  123. $items['examples/ajax_example/wizard_no_js'] = array(
  124. 'title' => 'Wizard w/JS turned off',
  125. 'page callback' => 'drupal_get_form',
  126. 'page arguments' => array('ajax_example_wizard', TRUE),
  127. 'access callback' => TRUE,
  128. 'file' => 'ajax_example_graceful_degradation.inc',
  129. 'weight' => 7,
  130. );
  131. // Add-more button that creates additional form elements.
  132. // See ajax_example_graceful_degradation.inc.
  133. $items['examples/ajax_example/add_more'] = array(
  134. 'title' => 'Add-more button (with graceful degradation)',
  135. 'page callback' => 'drupal_get_form',
  136. 'page arguments' => array('ajax_example_add_more'),
  137. 'access callback' => TRUE,
  138. 'file' => 'ajax_example_graceful_degradation.inc',
  139. 'weight' => 8,
  140. );
  141. // The above example as it appears to users with no javascript.
  142. $items['examples/ajax_example/add_more_no_js'] = array(
  143. 'title' => 'Add-more button w/JS turned off',
  144. 'page callback' => 'drupal_get_form',
  145. 'page arguments' => array('ajax_example_add_more', TRUE),
  146. 'access callback' => TRUE,
  147. 'file' => 'ajax_example_graceful_degradation.inc',
  148. 'weight' => 8,
  149. );
  150. // Use the AJAX framework outside the context of a form using the use-ajax
  151. // class. See ajax_example_misc.inc.
  152. $items['examples/ajax_example/ajax_link'] = array(
  153. 'title' => 'Ajax Link ("use-ajax" class)',
  154. 'page callback' => 'ajax_example_render_link',
  155. 'access callback' => TRUE,
  156. 'file' => 'ajax_example_misc.inc',
  157. 'weight' => 9,
  158. );
  159. // Use the AJAX framework outside the context of a form using a renderable
  160. // array of type link with the #ajax property. See ajax_example_misc.inc.
  161. $items['examples/ajax_example/ajax_link_renderable'] = array(
  162. 'title' => 'Ajax Link (Renderable Array)',
  163. 'page callback' => 'ajax_example_render_link_ra',
  164. 'access callback' => TRUE,
  165. 'file' => 'ajax_example_misc.inc',
  166. 'weight' => 9,
  167. );
  168. // A menu callback is required when using ajax outside of the Form API.
  169. $items['ajax_link_callback'] = array(
  170. 'page callback' => 'ajax_link_response',
  171. 'access callback' => 'user_access',
  172. 'access arguments' => array('access content'),
  173. 'type' => MENU_CALLBACK,
  174. 'file' => 'ajax_example_misc.inc',
  175. );
  176. // Use AJAX framework commands outside of the #ajax form property.
  177. // See ajax_example_advanced.inc.
  178. $items['examples/ajax_example/advanced_commands'] = array(
  179. 'title' => 'AJAX framework commands',
  180. 'page callback' => 'drupal_get_form',
  181. 'page arguments' => array('ajax_example_advanced_commands'),
  182. 'access callback' => TRUE,
  183. 'file' => 'ajax_example_advanced.inc',
  184. 'weight' => 10,
  185. );
  186. return $items;
  187. }
  188. function ajax_example_intro() {
  189. $markup = t('The AJAX example module provides many examples of AJAX including forms, links, and AJAX commands.');
  190. return $markup;
  191. }
  192. /**
  193. * Simple form whose ajax-enabled 'changethis' member causes a text change
  194. * in the description of the 'replace_textfield' member.
  195. * See @link http://drupal.org/node/262422 Form API Tutorial @endlink
  196. */
  197. function ajax_example_simplest($form, &$form_state) {
  198. $form = array();
  199. $form['changethis'] = array(
  200. '#title' => t("Choose something and explain why"),
  201. '#type' => 'select',
  202. '#options' => array(
  203. 'one' => 'one',
  204. 'two' => 'two',
  205. 'three' => 'three',
  206. ),
  207. '#ajax' => array(
  208. // #ajax has two required keys: callback and wrapper.
  209. // 'callback' is a function that will be called when this element changes.
  210. 'callback' => 'ajax_example_simplest_callback',
  211. // 'wrapper' is the HTML id of the page element that will be replaced.
  212. 'wrapper' => 'replace_textfield_div',
  213. // There are also several optional keys - see ajax_example_autocheckboxes
  214. // below for details on 'method', 'effect' and 'speed' and
  215. // ajax_example_dependent_dropdown for 'event'.
  216. ),
  217. );
  218. // This entire form element will be replaced whenever 'changethis' is updated.
  219. $form['replace_textfield'] = array(
  220. '#type' => 'textfield',
  221. '#title' => t("Why"),
  222. // The prefix/suffix provide the div that we're replacing, named by
  223. // #ajax['wrapper'] above.
  224. '#prefix' => '<div id="replace_textfield_div">',
  225. '#suffix' => '</div>',
  226. );
  227. // An AJAX request calls the form builder function for every change.
  228. // We can change how we build the form based on $form_state.
  229. if (!empty($form_state['values']['changethis'])) {
  230. $form['replace_textfield']['#description'] = t("Say why you chose '@value'", array('@value' => $form_state['values']['changethis']));
  231. }
  232. return $form;
  233. }
  234. /**
  235. * Callback for ajax_example_simplest.
  236. *
  237. * On an ajax submit, the form builder function is called again, then the $form
  238. * and $form_state are passed to this callback function so it can select which
  239. * portion of the form to send on to the client.
  240. *
  241. * @return renderable array (the textfield element)
  242. */
  243. function ajax_example_simplest_callback($form, $form_state) {
  244. // The form has already been submitted and updated. We can return the replaced
  245. // item as it is.
  246. return $form['replace_textfield'];
  247. }
  248. /**
  249. * AJAX-enabled select element causes replacement of a set of checkboxes
  250. * based on the selection.
  251. */
  252. function ajax_example_autocheckboxes($form, &$form_state) {
  253. // Since the form builder is called after every AJAX request, we rebuild
  254. // the form based on $form_state.
  255. $num_checkboxes = !empty($form_state['values']['howmany_select']) ? $form_state['values']['howmany_select'] : 1;
  256. $form['howmany_select'] = array(
  257. '#title' => t('How many checkboxes do you want?'),
  258. '#type' => 'select',
  259. '#options' => array(1 => 1, 2 => 2, 3 => 3, 4 => 4),
  260. '#default_value' => $num_checkboxes,
  261. '#ajax' => array(
  262. 'callback' => 'ajax_example_autocheckboxes_callback',
  263. 'wrapper' => 'checkboxes-div',
  264. //'method' defaults to replaceWith, but valid values also include
  265. // append, prepend, before and after.
  266. // 'method' => 'replaceWith',
  267. // 'effect' defaults to none. Other valid values are 'fade' and 'slide'.
  268. // See ajax_example_autotextfields for an example of 'fade'.
  269. 'effect' => 'slide',
  270. // 'speed' defaults to 'slow'. You can also use 'fast'
  271. // or a number of milliseconds for the animation to last.
  272. // 'speed' => 'slow',
  273. // Don't show any throbber...
  274. 'progress' => array('type' => 'none'),
  275. ),
  276. );
  277. $form['checkboxes_fieldset'] = array(
  278. '#title' => t("Generated Checkboxes"),
  279. // The prefix/suffix provide the div that we're replacing, named by
  280. // #ajax['wrapper'] above.
  281. '#prefix' => '<div id="checkboxes-div">',
  282. '#suffix' => '</div>',
  283. '#type' => 'fieldset',
  284. '#description' => t('This is where we get automatically generated checkboxes'),
  285. );
  286. for ($i = 1; $i <= $num_checkboxes; $i++) {
  287. $form['checkboxes_fieldset']["checkbox$i"] = array(
  288. '#type' => 'checkbox',
  289. '#title' => "Checkbox $i",
  290. );
  291. }
  292. $form['submit'] = array(
  293. '#type' => 'submit',
  294. '#value' => t('Submit'),
  295. );
  296. return $form;
  297. }
  298. /**
  299. * Callback element needs only select the portion of the form to be updated.
  300. * Since #ajax['callback'] return can be HTML or a renderable array (or an
  301. * array of commands), we can just return a piece of the form.
  302. * See @link ajax_example_advanced.inc AJAX Advanced Commands for more details
  303. * on AJAX framework commands.
  304. *
  305. * @return renderable array (the checkboxes fieldset)
  306. */
  307. function ajax_example_autocheckboxes_callback($form, $form_state) {
  308. return $form['checkboxes_fieldset'];
  309. }
  310. /**
  311. * Show/hide textfields based on AJAX-enabled checkbox clicks.
  312. */
  313. function ajax_example_autotextfields($form, &$form_state) {
  314. $form['ask_first_name'] = array(
  315. '#type' => 'checkbox',
  316. '#title' => t('Ask me my first name'),
  317. '#ajax' => array(
  318. 'callback' => 'ajax_example_autotextfields_callback',
  319. 'wrapper' => 'textfields',
  320. 'effect' => 'fade',
  321. )
  322. );
  323. $form['ask_last_name'] = array(
  324. '#type' => 'checkbox',
  325. '#title' => t('Ask me my last name'),
  326. '#ajax' => array(
  327. 'callback' => 'ajax_example_autotextfields_callback',
  328. 'wrapper' => 'textfields',
  329. 'effect' => 'fade',
  330. ),
  331. );
  332. $form['textfields'] = array(
  333. '#title' => t("Generated text fields for first and last name"),
  334. '#prefix' => '<div id="textfields">',
  335. '#suffix' => '</div>',
  336. '#type' => 'fieldset',
  337. '#description' => t('This is where we put automatically generated textfields'),
  338. );
  339. // Since checkboxes return TRUE or FALSE, we have to check that
  340. // $form_state has been filled as well as what it contains.
  341. if (!empty($form_state['values']['ask_first_name']) && $form_state['values']['ask_first_name']) {
  342. $form['textfields']['first_name'] = array(
  343. '#type' => 'textfield',
  344. '#title' => t('First Name'),
  345. );
  346. }
  347. if (!empty($form_state['values']['ask_last_name']) && $form_state['values']['ask_last_name']) {
  348. $form['textfields']['last_name'] = array(
  349. '#type' => 'textfield',
  350. '#title' => t('Last Name'),
  351. );
  352. }
  353. $form['submit'] = array(
  354. '#type' => 'submit',
  355. '#value' => t('Click Me'),
  356. );
  357. return $form;
  358. }
  359. /**
  360. * Selects the piece of the form we want to use as replacement text and returns
  361. * it as a form (renderable array).
  362. *
  363. * @return renderable array (the textfields element)
  364. */
  365. function ajax_example_autotextfields_callback($form, $form_state) {
  366. return $form['textfields'];
  367. }
  368. /**
  369. * A very basic form which with an AJAX-enabled submit.
  370. *
  371. * On submit, the markup in the #markup element is updated.
  372. */
  373. function ajax_example_submit_driven_ajax($form, &$form_state) {
  374. $form['box'] = array(
  375. '#type' => 'markup',
  376. '#prefix' => '<div id="box">',
  377. '#suffix' => '</div>',
  378. '#markup' => '<h1>Initial markup for box</h1>',
  379. );
  380. $form['submit'] = array(
  381. '#type' => 'submit',
  382. '#ajax' => array(
  383. 'callback' => 'ajax_example_submit_driven_callback',
  384. 'wrapper' => 'box',
  385. 'name' => 'submit1',
  386. ),
  387. '#value' => t('Submit'),
  388. );
  389. return $form;
  390. }
  391. /**
  392. * Select the 'box' element, change the markup in it, and return it as a
  393. * renderable array.
  394. *
  395. * @return renderable array (the box element)
  396. */
  397. function ajax_example_submit_driven_callback($form, $form_state) {
  398. // In most cases, it is recomended that you put this logic in form generation
  399. // rather than the callback. Submit driven forms are an exception, because
  400. // you may not want to return the form at all.
  401. $element = $form['box'];
  402. $element['#markup'] = "Clicked submit ({$form_state['values']['op']}): " . date('c');
  403. return $element;
  404. }
  405. /**
  406. * A form with a dropdown whose options are dependent on a
  407. * choice made in a previous dropdown.
  408. *
  409. * On changing the first dropdown, the options in the second
  410. * are updated.
  411. */
  412. function ajax_example_dependent_dropdown($form, &$form_state) {
  413. // Get the list of options to populate the first dropdown.
  414. $options_first = _ajax_example_get_first_dropdown_options();
  415. // If we have a value for the first dropdown from $form_state['values'] we use
  416. // this both as the default value for the first dropdown and also as a
  417. // parameter to pass to the function that retrieves the options for the
  418. // second dropdown.
  419. $selected = isset($form_state['values']['dropdown_first']) ? $form_state['values']['dropdown_first'] : key($options_first);
  420. $form['dropdown_first'] = array(
  421. '#type' => 'select',
  422. '#title' => 'Instrument Type',
  423. '#options' => $options_first,
  424. '#default_value' => $selected,
  425. // Bind an ajax callback to the change event (which is the default for the
  426. // select form type) of the first dropdown. It will replace the second
  427. // dropdown when rebuilt
  428. '#ajax' => array(
  429. // When 'event' occurs, Drupal will perform an ajax request in the
  430. // background. Usually the default value is sufficient (eg. change for
  431. // select elements), but valid values include any jQuery event,
  432. // most notably 'mousedown', 'blur', and 'submit'.
  433. // 'event' => 'change',
  434. 'callback' => 'ajax_example_dependent_dropdown_callback',
  435. 'wrapper' => 'dropdown-second-replace',
  436. ),
  437. );
  438. $form['dropdown_second'] = array(
  439. '#type' => 'select',
  440. '#title' => $options_first[$selected] . ' ' . t('Instruments'),
  441. // The entire enclosing div created here gets replaced when dropdown_first
  442. // is changed.
  443. '#prefix' => '<div id="dropdown-second-replace">',
  444. '#suffix' => '</div>',
  445. // when the form is rebuilt during ajax processing, the $selected variable
  446. // will now have the new value and so the options will change
  447. '#options' => _ajax_example_get_second_dropdown_options($selected),
  448. '#default_value' => isset($form_state['values']['dropdown_second']) ? $form_state['values']['dropdown_second'] : '',
  449. );
  450. $form['submit'] = array(
  451. '#type' => 'submit',
  452. '#value' => t('Submit'),
  453. );
  454. return $form;
  455. }
  456. /**
  457. * Selects just the second dropdown to be returned for re-rendering
  458. *
  459. * Since the controlling logic for populating the form is in the form builder
  460. * function, all we do here is select the element and return it to be updated.
  461. *
  462. * @return renderable array (the second dropdown)
  463. */
  464. function ajax_example_dependent_dropdown_callback($form, $form_state) {
  465. return $form['dropdown_second'];
  466. }
  467. /**
  468. * Helper function to populate the first dropdown. This would normally be
  469. * pulling data from the database.
  470. *
  471. * @return array of options
  472. */
  473. function _ajax_example_get_first_dropdown_options() {
  474. // drupal_map_assoc() just makes an array('String' => 'String'...).
  475. return drupal_map_assoc(array(t('String'), t('Woodwind'), t('Brass'), t('Percussion')));
  476. }
  477. /**
  478. * Helper function to populate the second dropdown. This would normally be
  479. * pulling data from the database.
  480. *
  481. * @param $key
  482. * This will determine which set of options is returned.
  483. *
  484. * @return array of options
  485. */
  486. function _ajax_example_get_second_dropdown_options($key = '') {
  487. $options = array(
  488. t('String') => drupal_map_assoc(array(t('Violin'), t('Viola'), t('Cello'), t('Double Bass'))),
  489. t('Woodwind') => drupal_map_assoc(array(t('Flute'), t('Clarinet'), t('Oboe'), t('Bassoon'))),
  490. t('Brass') => drupal_map_assoc(array(t('Trumpet'), t('Trombone'), t('French Horn'), t('Euphonium'))),
  491. t('Percussion') => drupal_map_assoc(array(t('Bass Drum'), t('Timpani'), t('Snare Drum'), t('Tambourine'))),
  492. );
  493. if (isset($options[$key])) {
  494. return $options[$key];
  495. }
  496. else {
  497. return array();
  498. }
  499. }
  500. /**
  501. * @} End of "defgroup ajax_example".
  502. */
Login or register to post comments