/[drupal]/contributions/modules/activeselect/API.txt
ViewVC logotype

Contents of /contributions/modules/activeselect/API.txt

Parent Directory Parent Directory | Revision Log Revision Log | View Revision Graph Revision Graph


Revision 1.4 - (show annotations) (download)
Sun Apr 9 05:11:52 2006 UTC (3 years, 7 months ago) by jaza
Branch: MAIN
CVS Tags: DRUPAL-4-7--1-0, DRUPAL-5--1-0, HEAD
Branch point for: DRUPAL-5, DRUPAL-4-7
Changes since 1.3: +37 -19 lines
File MIME type: text/plain
- Changed theme_activeselect() to use _form_set_class() instead of _form_get_class() (the latter function has been removed from Drupal core).
- #57929: use JSON instead of pipe delimiters for AJAX response text. Activeselect now uses drupal_to_js() (on the PHP end) and parseJson() (on the JS end) for response text, and this has allowed a large amount of pipe-parsing code to be removed from the Activeselect JS library. API.txt has been updated to reflect this, and category_activeselect() has been updated to use the new API.
- New activeselect_explode_values() function, which does the work of turning the request string into a PHP array. API.txt and category_activeselect() have been updated with this function.
1 // $Id: API.txt,v 1.3 2006/03/29 12:51:48 jaza Exp $
2
3 Implementing activeselect in other modules
4 ------------------------------------------
5
6 These are instructions for developers who wish to use activeselect in their modules. Activeselect defines a new type of AJAX-enabled form element (the 'activeselect' element). As such, in order to make use of this functionality, developers must define instances of this element within a form, and must also write callback functions that will be executed via AJAX.
7
8 1. Defining instances of the element
9
10 Defining an activeselect is very similar to defining a regular select element, except that there are a few additional properties, of special significance, that need to be provided. Example:
11
12 <?php
13 function foo_form_page() {
14 $activeselect = module_exist('activeselect');
15
16 $form['bar-1'] = array(
17 '#type' => 'select',
18 '#title' => t('Bar 1'),
19 '#default_value' => array('val-1'),
20 '#options' => array('val-1' => t('Value 1'), 'val-2' => t('Value 2'), 'val-3' => t('Value 3')),
21 '#description' => t('Foo bar bar.'),
22 '#required' => TRUE,
23 );
24 if ($activeselect) {
25 $form['bar-1']['#type'] = 'activeselect';
26 $form['bar-1']['#activeselect_path'] = 'foo/activeselect';
27 $form['bar-1']['#activeselect_targets'] = 'bar-2,bar-3';
28 $form['bar-1']['#activeselect_extra'] = '';
29 }
30
31 $form['bar-2'] = array(
32 '#type' => 'select',
33 '#title' => t('Bar 2'),
34 '#default_value' => array('val-1-bar-2'),
35 '#options' => array('val-1-bar-2' => t('Value 1 (bar-2)'), 'val-2-bar-2' => t('Value 2 (bar-2)'), 'val-3-bar-2' => t('Value 3 (bar-2)')),
36 '#description' => t('Foo bar bar.'),
37 '#multiple' => TRUE,
38 '#required' => TRUE,
39 );
40 $form['bar-3'] = array(
41 '#type' => 'select',
42 '#title' => t('Bar 3'),
43 '#default_value' => array('val-1-bar-3'),
44 '#options' => array('val-1-bar-3' => t('Value 1 (bar-3)'), 'val-2-bar-3' => t('Value 2 (bar-3)'), 'val-3-bar-3' => t('Value 3 (bar-3)')),
45 '#description' => t('Foo bar bar.'),
46 '#multiple' => TRUE,
47 '#required' => TRUE,
48 );
49
50 return drupal_get_form('foo_form_page', $form);
51 }
52 ?>
53
54 As the example shows, the additional activeselect properties are as follows:
55
56 - #activeselect_path: the Drupal system path of the activeselect menu callback page, which will be requested using JavaScript. This is usually in the form '[modulename]/activeselect'.
57 - #activeselect_targets: the names of one or more target elements for this activeselect, separated by commas (no spaces). Each target element must be either a select or an activeselect.
58 - #activeselect_extra: any additional data that needs to be passed to the callback function as a parameter (as a string, NOT as an array or an object).
59
60 It is very important that the values defined in the '#options' array for each target element include EVERY POSSIBLE OPTION that could be outputted by your activeselect callback function. There are two reasons for this. Firstly, if the activeselect module is not present (or if it is present, but the user's browser has inadequate JavaScript support), then the form will degrade gracefully, and the page will still be reasonably usable. Secondly, if activeselect is present (and adequate JS support is available), then whatever values the user submits must be defined in the '#options' array for that element. This is because Drupal checks this presence as part of its default validation routine, and so this validation will fail if the option element cannot be verified.
61
62 It is also recommended that you use the technique provided in the example, for dynamically determining whether or not to make the element an activeselect. This allows your module to function just as (or almost as) effectively without activeselect as it does with it.
63
64 2. Defining the menu callback
65
66 <?php
67 function foo_menu($may_cache) {
68 $items = array();
69
70 if ($may_cache) {
71 $items[] = array('path' => 'foo/activeselect',
72 'title' => t('activeselect foo'),
73 'callback' => 'foo_activeselect',
74 'access' => user_access('access content'),
75 'type' => MENU_CALLBACK,
76 );
77
78 // Other items ...
79 $items[] = array('path' => 'foo/page',
80 'title' => t('foo bar'),
81 'callback' => 'foo_form_page',
82 'access' => user_access('access content'),
83 'type' => MENU_CALLBACK,
84 );
85 }
86
87 return $items;
88 }
89 ?>
90
91 This makes 'foo/activeselect' a page, that can be accessed through its URL, just like any other page on your site.
92
93 3. Writing the callback function
94
95 The callback function must have the name that you specified in the 'callback' field of your menu item. It must also have exactly the right parameters, and it must have a return value that matches a precise format. But apart from that, what the callback function does is completely up to you. Example:
96
97 function foo_activeselect($source, $targets, $string, $extra = NULL) {
98 if (empty($source) || empty($targets) || empty($string)) {
99 exit();
100 }
101
102 $targets = explode(',', $targets);
103 $output = array();
104
105 $array = activeselect_explode_values($string);
106
107 foreach ($targets as $target) {
108 $options = array();
109
110 $first_element = TRUE;
111 foreach ($array as $key => $value) {
112 $options[$key. '-'. $target]['value'] = $value. ' ('. $target. ')';
113
114 if ($first_element) {
115 $options[$key. '-'. $target]['selected'] = TRUE;
116 $first_element = FALSE;
117 }
118 else {
119 $options[$key. '-'. $target]['selected'] = FALSE;
120 }
121 }
122 $multiple = TRUE;
123
124 $output[$target] = array('options' => $options, 'multiple' => $multiple);
125 }
126
127 activeselect_set_header_nocache();
128
129 print drupal_to_js($output);
130 exit();
131 }
132
133 The format of the variables passed in as parameters is as follows:
134
135 - $source: the name of the source activeselect element, as defined by the module author in a $form array. The name does not include the 'edit-' prefix that is prepended to it when it is outputted on the page.
136 - $targets: the names of the target activeselect element(s), separated by commas. These names also do not include the 'edit-' prefix.
137 - $string: the options that the user has currently selected in the source activeselect, represented as a string. Each option in the string is separated by double pipe '|' symbols, and within each option, the option's internal value and its user-displayed text are separated by a single pipe '|' symbol. It is recommended that you use the activeselect_explode_values() function, as shown, to convert this string into an array of keys and values.
138 - $extra: the data (if any) that has been defined for the source activeselect's 'extra' attribute. The format of this field is up to the module developer, but it must be stored as a string.
139
140 And the format of the output value is as follows (when represented as a nested PHP array):
141
142 array(
143 'target-name-1' => array(
144 'options' => array(
145 'opt-val-1' => array(
146 'value' => 'opt-text-1',
147 'selected' => TRUE
148 ),
149 'opt-val-2' => array(
150 'value' => 'opt-text-2',
151 'selected' => FALSE
152 )
153 ),
154 'multiple' => TRUE
155 ),
156 'target-name-2' => array(
157 'options' => array(
158 'opt-val-3' => array(
159 'value' => 'opt-text-3',
160 'selected' => FALSE
161 )
162 ),
163 'multiple' => FALSE
164 ),
165 );
166
167 Values are grouped first by target, and then by option element. Each target has an 'options' attribute (which holds the array of options), as well as a boolean 'multiple' attribute (to indicate whether or not the element should be a multi-select). Similarly, each option element has a 'value' attribute (which holds the user-displayed text of that element), as well as a boolean 'selected' attribute (to indicate whether or not the option should be set to 'selected' when it is added to the target element).
168
169 As the example above illustrates, the best way to build your output is as a nested PHP array. However, the final output of your callback must be a string in JSON (JavaScript Object Notation) format. It is recommended that you use the drupal_to_js() function (which is part of Drupal core), as shown, to convert your nested PHP array into a JSON string, which can then be outputted. The activeselect JavaScript library will then be able to process your output, using the Drupal-provided parseJson() JavaScript function.
170
171 It is also important that you call the activeselect_set_header_nocache() function before printing your output. This function sets the HTTP headers for the activeselect page, such that the user's browser is instructed not to cache the content of the page. If you do not set the headers in this way, then you may experience problems with your activeselect elements in MSIE (as this browser caches HTTP GET requests by default).

  ViewVC Help
Powered by ViewVC 1.1.2