example_element.module

  1. drupal
    1. 5 developer/examples/example_element.module

This is an example demonstrating how a module can define custom form elements.

Form elements are already familiar to anyone who uses Forms API. Examples of core form elements are 'textfield', 'checkbox' and 'fieldset'. Drupal utilizes hook_elements() to define these FAPI types, and this occurs in the core function system_elements().

Each form element has a #type value that determines how it's treated by the Form API and how it's ultimately rendered into HTML. hook_elements() allows modules to define new element types, and tell the Form API what default values they should automatically be populated with.

By implementing hook_elements in your own module, you can create custom form elements with their own properties, validation and theming.

In this example, we will define a phone number field that is expanded into several text fields for area code, phone number and extention, each of which is validated.

Functions & methods

NameDescription
example_element_demoThis is a simple form to demonstrate how to use the phonenumber form element we defined.
example_element_elementsImplementation of hook_elements().
example_element_expandOur process callback to expand the control.
example_element_menuImplementation of hook_menu().
example_element_validateOur element's validation function.
theme_phonenumberTheme function to format the output.

File

developer/examples/example_element.module
View source
  1. <?php
  2. /**
  3. * @file
  4. * This is an example demonstrating how a module can define custom form
  5. * elements.
  6. *
  7. * Form elements are already familiar to anyone who uses Forms API. Examples
  8. * of core form elements are 'textfield', 'checkbox' and 'fieldset'. Drupal
  9. * utilizes hook_elements() to define these FAPI types, and this occurs in
  10. * the core function system_elements().
  11. *
  12. * Each form element has a #type value that determines how it's treated by
  13. * the Form API and how it's ultimately rendered into HTML. hook_elements()
  14. * allows modules to define new element types, and tell the Form API what
  15. * default values they should automatically be populated with.
  16. *
  17. * By implementing hook_elements in your own module, you can create custom
  18. * form elements with their own properties, validation and theming.
  19. *
  20. * In this example, we will define a phone number field that is expanded
  21. * into several text fields for area code, phone number and extention, each
  22. * of which is validated.
  23. */
  24. /**
  25. * Implementation of hook_menu().
  26. *
  27. * This just defines a page that we can use to test our form elements.
  28. */
  29. function example_element_menu($may_cache) {
  30. $items = array();
  31. if ($may_cache) {
  32. $items[] = array(
  33. 'path' => 'example_element',
  34. 'title' => t('Example element demo'),
  35. 'access' => user_access('access content'),
  36. 'type' => MENU_NORMAL_ITEM,
  37. 'callback' => 'drupal_get_form',
  38. 'callback arguments' => array('example_element_demo'),
  39. );
  40. }
  41. return $items;
  42. }
  43. /**
  44. * Implementation of hook_elements().
  45. */
  46. function example_element_elements() {
  47. $type['phonenumber'] = array(
  48. '#input' => TRUE,
  49. '#process' => array('example_element_expand' => array()),
  50. '#validate' => array('example_element_validate' => array()),
  51. '#default_value' => array('areacode' => '', 'number' => '', 'extension' => ''),
  52. );
  53. return $type;
  54. }
  55. /**
  56. * Our process callback to expand the control.
  57. */
  58. function example_element_expand($element) {
  59. $element['#tree'] = TRUE;
  60. if (!isset($element['#value'])) {
  61. $element['#value'] = array('areacode' => '', 'number' => '', 'extension' => '');
  62. }
  63. $element['areacode'] = array(
  64. '#type' => 'textfield',
  65. '#size' => 3,
  66. '#maxlength' => 3,
  67. '#value' => $element['#value']['areacode'],
  68. '#prefix' => '(',
  69. '#suffix' => ')',
  70. );
  71. $element['number'] = array(
  72. '#type' => 'textfield',
  73. '#size' => 8,
  74. '#maxlength' => 8,
  75. '#required' => TRUE,
  76. '#value' => $element['#value']['number'],
  77. );
  78. $element['extension'] = array(
  79. '#type' => 'textfield',
  80. '#size' => 10,
  81. '#maxlength' => 10,
  82. '#prefix' => t('ext'),
  83. '#value' => $element['#value']['extension'],
  84. );
  85. return $element;
  86. }
  87. /**
  88. * Our element's validation function.
  89. *
  90. * We check that:
  91. * - the area code is a three digit number
  92. * - the number is numeric, with an optional dash
  93. *
  94. * Any problems are attached to the form element using form_error().
  95. */
  96. function example_element_validate($form) {
  97. if (isset($form['#value']['areacode'])) {
  98. if (0 == preg_match('/^\d{3}$/', $form['#value']['areacode'])) {
  99. form_error($form['areacode'], t('The areacode is invalid.'));
  100. }
  101. }
  102. if (isset($form['#value']['number'])) {
  103. if (0 == preg_match('/^\d{3}-?\d{4}$/', $form['#value']['number'])) {
  104. form_error($form['number'], t('The number is invalid.'));
  105. }
  106. }
  107. return $form;
  108. }
  109. /**
  110. * Theme function to format the output.
  111. *
  112. * We use the container-inline class so that all three of the HTML elements
  113. * are placed next to each other, rather than on separate lines.
  114. */
  115. function theme_phonenumber($element) {
  116. return theme('form_element', $element, '<div class="container-inline">'. $element['#children'] .'</div>');
  117. }
  118. /**
  119. * This is a simple form to demonstrate how to use the phonenumber form
  120. * element we defined.
  121. */
  122. function example_element_demo() {
  123. $form['example_element_test_1'] = array(
  124. '#type' => 'phonenumber',
  125. '#title' => t('Phone number 1'),
  126. '#default_value' => variable_get('example_element_test_1',
  127. array('areacode' => '123', 'number' => '456-7890', 'extension' => '')
  128. ),
  129. '#description' => t('A phone number.'),
  130. );
  131. $form['example_element_test_2'] = array(
  132. '#type' => 'phonenumber',
  133. '#title' => t('Phone number 2'),
  134. '#default_value' => variable_get('example_element_test_2',
  135. array('areacode' => '', 'number' => '456-7890', 'extension' => '23')
  136. ),
  137. '#description' => t('Another phone number, a fax perhaps?'),
  138. );
  139. return system_settings_form($form);
  140. }
Login or register to post comments