danielebarchiesi@0
|
1 <?php
|
danielebarchiesi@0
|
2
|
danielebarchiesi@0
|
3 /**
|
danielebarchiesi@0
|
4 * @file
|
danielebarchiesi@0
|
5 * Functions for use with Drupal's Ajax framework.
|
danielebarchiesi@0
|
6 */
|
danielebarchiesi@0
|
7
|
danielebarchiesi@0
|
8 /**
|
danielebarchiesi@0
|
9 * @defgroup ajax Ajax framework
|
danielebarchiesi@0
|
10 * @{
|
danielebarchiesi@0
|
11 * Functions for Drupal's Ajax framework.
|
danielebarchiesi@0
|
12 *
|
danielebarchiesi@0
|
13 * Drupal's Ajax framework is used to dynamically update parts of a page's HTML
|
danielebarchiesi@0
|
14 * based on data from the server. Upon a specified event, such as a button
|
danielebarchiesi@0
|
15 * click, a callback function is triggered which performs server-side logic and
|
danielebarchiesi@0
|
16 * may return updated markup, which is then replaced on-the-fly with no page
|
danielebarchiesi@0
|
17 * refresh necessary.
|
danielebarchiesi@0
|
18 *
|
danielebarchiesi@0
|
19 * This framework creates a PHP macro language that allows the server to
|
danielebarchiesi@0
|
20 * instruct JavaScript to perform actions on the client browser. When using
|
danielebarchiesi@0
|
21 * forms, it can be used with the #ajax property.
|
danielebarchiesi@0
|
22 * The #ajax property can be used to bind events to the Ajax framework. By
|
danielebarchiesi@0
|
23 * default, #ajax uses 'system/ajax' as its path for submission and thus calls
|
danielebarchiesi@0
|
24 * ajax_form_callback() and a defined #ajax['callback'] function.
|
danielebarchiesi@0
|
25 * However, you may optionally specify a different path to request or a
|
danielebarchiesi@0
|
26 * different callback function to invoke, which can return updated HTML or can
|
danielebarchiesi@0
|
27 * also return a richer set of
|
danielebarchiesi@0
|
28 * @link ajax_commands Ajax framework commands @endlink.
|
danielebarchiesi@0
|
29 *
|
danielebarchiesi@0
|
30 * Standard form handling is as follows:
|
danielebarchiesi@0
|
31 * - A form element has a #ajax property that includes #ajax['callback'] and
|
danielebarchiesi@0
|
32 * omits #ajax['path']. See below about using #ajax['path'] to implement
|
danielebarchiesi@0
|
33 * advanced use-cases that require something other than standard form
|
danielebarchiesi@0
|
34 * handling.
|
danielebarchiesi@0
|
35 * - On the specified element, Ajax processing is triggered by a change to
|
danielebarchiesi@0
|
36 * that element.
|
danielebarchiesi@0
|
37 * - The browser submits an HTTP POST request to the 'system/ajax' Drupal
|
danielebarchiesi@0
|
38 * path.
|
danielebarchiesi@0
|
39 * - The menu page callback for 'system/ajax', ajax_form_callback(), calls
|
danielebarchiesi@0
|
40 * drupal_process_form() to process the form submission and rebuild the
|
danielebarchiesi@0
|
41 * form if necessary. The form is processed in much the same way as if it
|
danielebarchiesi@0
|
42 * were submitted without Ajax, with the same #process functions and
|
danielebarchiesi@0
|
43 * validation and submission handlers called in either case, making it easy
|
danielebarchiesi@0
|
44 * to create Ajax-enabled forms that degrade gracefully when JavaScript is
|
danielebarchiesi@0
|
45 * disabled.
|
danielebarchiesi@0
|
46 * - After form processing is complete, ajax_form_callback() calls the
|
danielebarchiesi@0
|
47 * function named by #ajax['callback'], which returns the form element that
|
danielebarchiesi@0
|
48 * has been updated and needs to be returned to the browser, or
|
danielebarchiesi@0
|
49 * alternatively, an array of custom Ajax commands.
|
danielebarchiesi@0
|
50 * - The page delivery callback for 'system/ajax', ajax_deliver(), renders the
|
danielebarchiesi@0
|
51 * element returned by #ajax['callback'], and returns the JSON string
|
danielebarchiesi@0
|
52 * created by ajax_render() to the browser.
|
danielebarchiesi@0
|
53 * - The browser unserializes the returned JSON string into an array of
|
danielebarchiesi@0
|
54 * command objects and executes each command, resulting in the old page
|
danielebarchiesi@0
|
55 * content within and including the HTML element specified by
|
danielebarchiesi@0
|
56 * #ajax['wrapper'] being replaced by the new content returned by
|
danielebarchiesi@0
|
57 * #ajax['callback'], using a JavaScript animation effect specified by
|
danielebarchiesi@0
|
58 * #ajax['effect'].
|
danielebarchiesi@0
|
59 *
|
danielebarchiesi@0
|
60 * A simple example of basic Ajax use from the
|
danielebarchiesi@0
|
61 * @link http://drupal.org/project/examples Examples module @endlink follows:
|
danielebarchiesi@0
|
62 * @code
|
danielebarchiesi@0
|
63 * function main_page() {
|
danielebarchiesi@0
|
64 * return drupal_get_form('ajax_example_simplest');
|
danielebarchiesi@0
|
65 * }
|
danielebarchiesi@0
|
66 *
|
danielebarchiesi@0
|
67 * function ajax_example_simplest($form, &$form_state) {
|
danielebarchiesi@0
|
68 * $form = array();
|
danielebarchiesi@0
|
69 * $form['changethis'] = array(
|
danielebarchiesi@0
|
70 * '#type' => 'select',
|
danielebarchiesi@0
|
71 * '#options' => array(
|
danielebarchiesi@0
|
72 * 'one' => 'one',
|
danielebarchiesi@0
|
73 * 'two' => 'two',
|
danielebarchiesi@0
|
74 * 'three' => 'three',
|
danielebarchiesi@0
|
75 * ),
|
danielebarchiesi@0
|
76 * '#ajax' => array(
|
danielebarchiesi@0
|
77 * 'callback' => 'ajax_example_simplest_callback',
|
danielebarchiesi@0
|
78 * 'wrapper' => 'replace_textfield_div',
|
danielebarchiesi@0
|
79 * ),
|
danielebarchiesi@0
|
80 * );
|
danielebarchiesi@0
|
81
|
danielebarchiesi@0
|
82 * // This entire form element will be replaced with an updated value.
|
danielebarchiesi@0
|
83 * $form['replace_textfield'] = array(
|
danielebarchiesi@0
|
84 * '#type' => 'textfield',
|
danielebarchiesi@0
|
85 * '#title' => t("The default value will be changed"),
|
danielebarchiesi@0
|
86 * '#description' => t("Say something about why you chose") . "'" .
|
danielebarchiesi@0
|
87 * (!empty($form_state['values']['changethis'])
|
danielebarchiesi@0
|
88 * ? $form_state['values']['changethis'] : t("Not changed yet")) . "'",
|
danielebarchiesi@0
|
89 * '#prefix' => '<div id="replace_textfield_div">',
|
danielebarchiesi@0
|
90 * '#suffix' => '</div>',
|
danielebarchiesi@0
|
91 * );
|
danielebarchiesi@0
|
92 * return $form;
|
danielebarchiesi@0
|
93 * }
|
danielebarchiesi@0
|
94 *
|
danielebarchiesi@0
|
95 * function ajax_example_simplest_callback($form, $form_state) {
|
danielebarchiesi@0
|
96 * // The form has already been submitted and updated. We can return the replaced
|
danielebarchiesi@0
|
97 * // item as it is.
|
danielebarchiesi@0
|
98 * return $form['replace_textfield'];
|
danielebarchiesi@0
|
99 * }
|
danielebarchiesi@0
|
100 * @endcode
|
danielebarchiesi@0
|
101 *
|
danielebarchiesi@0
|
102 * In the above example, the 'changethis' element is Ajax-enabled. The default
|
danielebarchiesi@0
|
103 * #ajax['event'] is 'change', so when the 'changethis' element changes,
|
danielebarchiesi@0
|
104 * an Ajax call is made. The form is submitted and reprocessed, and then the
|
danielebarchiesi@0
|
105 * callback is called. In this case, the form has been automatically
|
danielebarchiesi@0
|
106 * built changing $form['replace_textfield']['#description'], so the callback
|
danielebarchiesi@0
|
107 * just returns that part of the form.
|
danielebarchiesi@0
|
108 *
|
danielebarchiesi@0
|
109 * To implement Ajax handling in a form, add '#ajax' to the form
|
danielebarchiesi@0
|
110 * definition of a field. That field will trigger an Ajax event when it is
|
danielebarchiesi@0
|
111 * clicked (or changed, depending on the kind of field). #ajax supports
|
danielebarchiesi@0
|
112 * the following parameters (either 'path' or 'callback' is required at least):
|
danielebarchiesi@0
|
113 * - #ajax['callback']: The callback to invoke to handle the server side of the
|
danielebarchiesi@0
|
114 * Ajax event, which will receive a $form and $form_state as arguments, and
|
danielebarchiesi@0
|
115 * returns a renderable array (most often a form or form fragment), an HTML
|
danielebarchiesi@0
|
116 * string, or an array of Ajax commands. If returning a renderable array or
|
danielebarchiesi@0
|
117 * a string, the value will replace the original element named in
|
danielebarchiesi@0
|
118 * #ajax['wrapper'], and
|
danielebarchiesi@0
|
119 * theme_status_messages()
|
danielebarchiesi@0
|
120 * will be prepended to that
|
danielebarchiesi@0
|
121 * element. (If the status messages are not wanted, return an array
|
danielebarchiesi@0
|
122 * of Ajax commands instead.)
|
danielebarchiesi@0
|
123 * #ajax['wrapper']. If an array of Ajax commands is returned, it will be
|
danielebarchiesi@0
|
124 * executed by the calling code.
|
danielebarchiesi@0
|
125 * - #ajax['path']: The menu path to use for the request. This is often omitted
|
danielebarchiesi@0
|
126 * and the default is used. This path should map
|
danielebarchiesi@0
|
127 * to a menu page callback that returns data using ajax_render(). Defaults to
|
danielebarchiesi@0
|
128 * 'system/ajax', which invokes ajax_form_callback(), eventually calling
|
danielebarchiesi@0
|
129 * the function named in #ajax['callback']. If you use a custom
|
danielebarchiesi@0
|
130 * path, you must set up the menu entry and handle the entire callback in your
|
danielebarchiesi@0
|
131 * own code.
|
danielebarchiesi@0
|
132 * - #ajax['wrapper']: The CSS ID of the area to be replaced by the content
|
danielebarchiesi@0
|
133 * returned by the #ajax['callback'] function. The content returned from
|
danielebarchiesi@0
|
134 * the callback will replace the entire element named by #ajax['wrapper'].
|
danielebarchiesi@0
|
135 * The wrapper is usually created using #prefix and #suffix properties in the
|
danielebarchiesi@0
|
136 * form. Note that this is the wrapper ID, not a CSS selector. So to replace
|
danielebarchiesi@0
|
137 * the element referred to by the CSS selector #some-selector on the page,
|
danielebarchiesi@0
|
138 * use #ajax['wrapper'] = 'some-selector', not '#some-selector'.
|
danielebarchiesi@0
|
139 * - #ajax['effect']: The jQuery effect to use when placing the new HTML.
|
danielebarchiesi@0
|
140 * Defaults to no effect. Valid options are 'none', 'slide', or 'fade'.
|
danielebarchiesi@0
|
141 * - #ajax['speed']: The effect speed to use. Defaults to 'slow'. May be
|
danielebarchiesi@0
|
142 * 'slow', 'fast' or a number in milliseconds which represents the length
|
danielebarchiesi@0
|
143 * of time the effect should run.
|
danielebarchiesi@0
|
144 * - #ajax['event']: The JavaScript event to respond to. This is normally
|
danielebarchiesi@0
|
145 * selected automatically for the type of form widget being used, and
|
danielebarchiesi@0
|
146 * is only needed if you need to override the default behavior.
|
danielebarchiesi@0
|
147 * - #ajax['prevent']: A JavaScript event to prevent when 'event' is triggered.
|
danielebarchiesi@0
|
148 * Defaults to 'click' for #ajax on #type 'submit', 'button', and
|
danielebarchiesi@0
|
149 * 'image_button'. Multiple events may be specified separated by spaces.
|
danielebarchiesi@0
|
150 * For example, when binding #ajax behaviors to form buttons, pressing the
|
danielebarchiesi@0
|
151 * ENTER key within a textfield triggers the 'click' event of the form's first
|
danielebarchiesi@0
|
152 * submit button. Triggering Ajax in this situation leads to problems, like
|
danielebarchiesi@0
|
153 * breaking autocomplete textfields. Because of that, Ajax behaviors are bound
|
danielebarchiesi@0
|
154 * to the 'mousedown' event on form buttons by default. However, binding to
|
danielebarchiesi@0
|
155 * 'mousedown' rather than 'click' means that it is possible to trigger a
|
danielebarchiesi@0
|
156 * click by pressing the mouse, holding the mouse button down until the Ajax
|
danielebarchiesi@0
|
157 * request is complete and the button is re-enabled, and then releasing the
|
danielebarchiesi@0
|
158 * mouse button. For this case, 'prevent' can be set to 'click', so an
|
danielebarchiesi@0
|
159 * additional event handler is bound to prevent such a click from triggering a
|
danielebarchiesi@0
|
160 * non-Ajax form submission. This also prevents a textfield's ENTER press
|
danielebarchiesi@0
|
161 * triggering a button's non-Ajax form submission behavior.
|
danielebarchiesi@0
|
162 * - #ajax['method']: The jQuery method to use to place the new HTML.
|
danielebarchiesi@0
|
163 * Defaults to 'replaceWith'. May be: 'replaceWith', 'append', 'prepend',
|
danielebarchiesi@0
|
164 * 'before', 'after', or 'html'. See the
|
danielebarchiesi@0
|
165 * @link http://api.jquery.com/category/manipulation/ jQuery manipulators documentation @endlink
|
danielebarchiesi@0
|
166 * for more information on these methods.
|
danielebarchiesi@0
|
167 * - #ajax['progress']: Choose either a throbber or progress bar that is
|
danielebarchiesi@0
|
168 * displayed while awaiting a response from the callback, and add an optional
|
danielebarchiesi@0
|
169 * message. Possible keys: 'type', 'message', 'url', 'interval'.
|
danielebarchiesi@0
|
170 * More information is available in the
|
danielebarchiesi@0
|
171 * @link forms_api_reference.html Form API Reference @endlink
|
danielebarchiesi@0
|
172 *
|
danielebarchiesi@0
|
173 * In addition to using Form API for doing in-form modification, Ajax may be
|
danielebarchiesi@0
|
174 * enabled by adding classes to buttons and links. By adding the 'use-ajax'
|
danielebarchiesi@0
|
175 * class to a link, the link will be loaded via an Ajax call. When using this
|
danielebarchiesi@0
|
176 * method, the href of the link can contain '/nojs/' as part of the path. When
|
danielebarchiesi@0
|
177 * the Ajax framework makes the request, it will convert this to '/ajax/'.
|
danielebarchiesi@0
|
178 * The server is then able to easily tell if this request was made through an
|
danielebarchiesi@0
|
179 * actual Ajax request or in a degraded state, and respond appropriately.
|
danielebarchiesi@0
|
180 *
|
danielebarchiesi@0
|
181 * Similarly, submit buttons can be given the class 'use-ajax-submit'. The
|
danielebarchiesi@0
|
182 * form will then be submitted via Ajax to the path specified in the #action.
|
danielebarchiesi@0
|
183 * Like the ajax-submit class above, this path will have '/nojs/' replaced with
|
danielebarchiesi@0
|
184 * '/ajax/' so that the submit handler can tell if the form was submitted
|
danielebarchiesi@0
|
185 * in a degraded state or not.
|
danielebarchiesi@0
|
186 *
|
danielebarchiesi@0
|
187 * When responding to Ajax requests, the server should do what it needs to do
|
danielebarchiesi@0
|
188 * for that request, then create a commands array. This commands array will
|
danielebarchiesi@0
|
189 * be converted to a JSON object and returned to the client, which will then
|
danielebarchiesi@0
|
190 * iterate over the array and process it like a macro language.
|
danielebarchiesi@0
|
191 *
|
danielebarchiesi@0
|
192 * Each command item is an associative array which will be converted to a
|
danielebarchiesi@0
|
193 * command object on the JavaScript side. $command_item['command'] is the type
|
danielebarchiesi@0
|
194 * of command, e.g. 'alert' or 'replace', and will correspond to a method in the
|
danielebarchiesi@0
|
195 * Drupal.ajax[command] space. The command array may contain any other data that
|
danielebarchiesi@0
|
196 * the command needs to process, e.g. 'method', 'selector', 'settings', etc.
|
danielebarchiesi@0
|
197 *
|
danielebarchiesi@0
|
198 * Commands are usually created with a couple of helper functions, so they
|
danielebarchiesi@0
|
199 * look like this:
|
danielebarchiesi@0
|
200 * @code
|
danielebarchiesi@0
|
201 * $commands = array();
|
danielebarchiesi@0
|
202 * // Replace the content of '#object-1' on the page with 'some html here'.
|
danielebarchiesi@0
|
203 * $commands[] = ajax_command_replace('#object-1', 'some html here');
|
danielebarchiesi@0
|
204 * // Add a visual "changed" marker to the '#object-1' element.
|
danielebarchiesi@0
|
205 * $commands[] = ajax_command_changed('#object-1');
|
danielebarchiesi@0
|
206 * // Menu 'page callback' and #ajax['callback'] functions are supposed to
|
danielebarchiesi@0
|
207 * // return render arrays. If returning an Ajax commands array, it must be
|
danielebarchiesi@0
|
208 * // encapsulated in a render array structure.
|
danielebarchiesi@0
|
209 * return array('#type' => 'ajax', '#commands' => $commands);
|
danielebarchiesi@0
|
210 * @endcode
|
danielebarchiesi@0
|
211 *
|
danielebarchiesi@0
|
212 * When returning an Ajax command array, it is often useful to have
|
danielebarchiesi@0
|
213 * status messages rendered along with other tasks in the command array.
|
danielebarchiesi@0
|
214 * In that case the the Ajax commands array may be constructed like this:
|
danielebarchiesi@0
|
215 * @code
|
danielebarchiesi@0
|
216 * $commands = array();
|
danielebarchiesi@0
|
217 * $commands[] = ajax_command_replace(NULL, $output);
|
danielebarchiesi@0
|
218 * $commands[] = ajax_command_prepend(NULL, theme('status_messages'));
|
danielebarchiesi@0
|
219 * return array('#type' => 'ajax', '#commands' => $commands);
|
danielebarchiesi@0
|
220 * @endcode
|
danielebarchiesi@0
|
221 *
|
danielebarchiesi@0
|
222 * See @link ajax_commands Ajax framework commands @endlink
|
danielebarchiesi@0
|
223 */
|
danielebarchiesi@0
|
224
|
danielebarchiesi@0
|
225 /**
|
danielebarchiesi@0
|
226 * Renders a commands array into JSON.
|
danielebarchiesi@0
|
227 *
|
danielebarchiesi@0
|
228 * @param $commands
|
danielebarchiesi@0
|
229 * A list of macro commands generated by the use of ajax_command_*()
|
danielebarchiesi@0
|
230 * functions.
|
danielebarchiesi@0
|
231 */
|
danielebarchiesi@0
|
232 function ajax_render($commands = array()) {
|
danielebarchiesi@0
|
233 // Ajax responses aren't rendered with html.tpl.php, so we have to call
|
danielebarchiesi@0
|
234 // drupal_get_css() and drupal_get_js() here, in order to have new files added
|
danielebarchiesi@0
|
235 // during this request to be loaded by the page. We only want to send back
|
danielebarchiesi@0
|
236 // files that the page hasn't already loaded, so we implement simple diffing
|
danielebarchiesi@0
|
237 // logic using array_diff_key().
|
danielebarchiesi@0
|
238 foreach (array('css', 'js') as $type) {
|
danielebarchiesi@0
|
239 // It is highly suspicious if $_POST['ajax_page_state'][$type] is empty,
|
danielebarchiesi@0
|
240 // since the base page ought to have at least one JS file and one CSS file
|
danielebarchiesi@0
|
241 // loaded. It probably indicates an error, and rather than making the page
|
danielebarchiesi@0
|
242 // reload all of the files, instead we return no new files.
|
danielebarchiesi@0
|
243 if (empty($_POST['ajax_page_state'][$type])) {
|
danielebarchiesi@0
|
244 $items[$type] = array();
|
danielebarchiesi@0
|
245 }
|
danielebarchiesi@0
|
246 else {
|
danielebarchiesi@0
|
247 $function = 'drupal_add_' . $type;
|
danielebarchiesi@0
|
248 $items[$type] = $function();
|
danielebarchiesi@0
|
249 drupal_alter($type, $items[$type]);
|
danielebarchiesi@0
|
250 // @todo Inline CSS and JS items are indexed numerically. These can't be
|
danielebarchiesi@0
|
251 // reliably diffed with array_diff_key(), since the number can change
|
danielebarchiesi@0
|
252 // due to factors unrelated to the inline content, so for now, we strip
|
danielebarchiesi@0
|
253 // the inline items from Ajax responses, and can add support for them
|
danielebarchiesi@0
|
254 // when drupal_add_css() and drupal_add_js() are changed to use a hash
|
danielebarchiesi@0
|
255 // of the inline content as the array key.
|
danielebarchiesi@0
|
256 foreach ($items[$type] as $key => $item) {
|
danielebarchiesi@0
|
257 if (is_numeric($key)) {
|
danielebarchiesi@0
|
258 unset($items[$type][$key]);
|
danielebarchiesi@0
|
259 }
|
danielebarchiesi@0
|
260 }
|
danielebarchiesi@0
|
261 // Ensure that the page doesn't reload what it already has.
|
danielebarchiesi@0
|
262 $items[$type] = array_diff_key($items[$type], $_POST['ajax_page_state'][$type]);
|
danielebarchiesi@0
|
263 }
|
danielebarchiesi@0
|
264 }
|
danielebarchiesi@0
|
265
|
danielebarchiesi@0
|
266 // Render the HTML to load these files, and add AJAX commands to insert this
|
danielebarchiesi@0
|
267 // HTML in the page. We pass TRUE as the $skip_alter argument to prevent the
|
danielebarchiesi@0
|
268 // data from being altered again, as we already altered it above. Settings are
|
danielebarchiesi@0
|
269 // handled separately, afterwards.
|
danielebarchiesi@0
|
270 if (isset($items['js']['settings'])) {
|
danielebarchiesi@0
|
271 unset($items['js']['settings']);
|
danielebarchiesi@0
|
272 }
|
danielebarchiesi@0
|
273 $styles = drupal_get_css($items['css'], TRUE);
|
danielebarchiesi@0
|
274 $scripts_footer = drupal_get_js('footer', $items['js'], TRUE);
|
danielebarchiesi@0
|
275 $scripts_header = drupal_get_js('header', $items['js'], TRUE);
|
danielebarchiesi@0
|
276
|
danielebarchiesi@0
|
277 $extra_commands = array();
|
danielebarchiesi@0
|
278 if (!empty($styles)) {
|
danielebarchiesi@0
|
279 $extra_commands[] = ajax_command_prepend('head', $styles);
|
danielebarchiesi@0
|
280 }
|
danielebarchiesi@0
|
281 if (!empty($scripts_header)) {
|
danielebarchiesi@0
|
282 $extra_commands[] = ajax_command_prepend('head', $scripts_header);
|
danielebarchiesi@0
|
283 }
|
danielebarchiesi@0
|
284 if (!empty($scripts_footer)) {
|
danielebarchiesi@0
|
285 $extra_commands[] = ajax_command_append('body', $scripts_footer);
|
danielebarchiesi@0
|
286 }
|
danielebarchiesi@0
|
287 if (!empty($extra_commands)) {
|
danielebarchiesi@0
|
288 $commands = array_merge($extra_commands, $commands);
|
danielebarchiesi@0
|
289 }
|
danielebarchiesi@0
|
290
|
danielebarchiesi@0
|
291 // Now add a command to merge changes and additions to Drupal.settings.
|
danielebarchiesi@0
|
292 $scripts = drupal_add_js();
|
danielebarchiesi@0
|
293 if (!empty($scripts['settings'])) {
|
danielebarchiesi@0
|
294 $settings = $scripts['settings'];
|
danielebarchiesi@0
|
295 array_unshift($commands, ajax_command_settings(call_user_func_array('array_merge_recursive', $settings['data']), TRUE));
|
danielebarchiesi@0
|
296 }
|
danielebarchiesi@0
|
297
|
danielebarchiesi@0
|
298 // Allow modules to alter any Ajax response.
|
danielebarchiesi@0
|
299 drupal_alter('ajax_render', $commands);
|
danielebarchiesi@0
|
300
|
danielebarchiesi@0
|
301 return drupal_json_encode($commands);
|
danielebarchiesi@0
|
302 }
|
danielebarchiesi@0
|
303
|
danielebarchiesi@0
|
304 /**
|
danielebarchiesi@0
|
305 * Gets a form submitted via #ajax during an Ajax callback.
|
danielebarchiesi@0
|
306 *
|
danielebarchiesi@0
|
307 * This will load a form from the form cache used during Ajax operations. It
|
danielebarchiesi@0
|
308 * pulls the form info from $_POST.
|
danielebarchiesi@0
|
309 *
|
danielebarchiesi@0
|
310 * @return
|
danielebarchiesi@0
|
311 * An array containing the $form and $form_state. Use the list() function
|
danielebarchiesi@0
|
312 * to break these apart:
|
danielebarchiesi@0
|
313 * @code
|
danielebarchiesi@0
|
314 * list($form, $form_state, $form_id, $form_build_id) = ajax_get_form();
|
danielebarchiesi@0
|
315 * @endcode
|
danielebarchiesi@0
|
316 */
|
danielebarchiesi@0
|
317 function ajax_get_form() {
|
danielebarchiesi@0
|
318 $form_state = form_state_defaults();
|
danielebarchiesi@0
|
319
|
danielebarchiesi@0
|
320 $form_build_id = $_POST['form_build_id'];
|
danielebarchiesi@0
|
321
|
danielebarchiesi@0
|
322 // Get the form from the cache.
|
danielebarchiesi@0
|
323 $form = form_get_cache($form_build_id, $form_state);
|
danielebarchiesi@0
|
324 if (!$form) {
|
danielebarchiesi@0
|
325 // If $form cannot be loaded from the cache, the form_build_id in $_POST
|
danielebarchiesi@0
|
326 // must be invalid, which means that someone performed a POST request onto
|
danielebarchiesi@0
|
327 // system/ajax without actually viewing the concerned form in the browser.
|
danielebarchiesi@0
|
328 // This is likely a hacking attempt as it never happens under normal
|
danielebarchiesi@0
|
329 // circumstances, so we just do nothing.
|
danielebarchiesi@0
|
330 watchdog('ajax', 'Invalid form POST data.', array(), WATCHDOG_WARNING);
|
danielebarchiesi@0
|
331 drupal_exit();
|
danielebarchiesi@0
|
332 }
|
danielebarchiesi@0
|
333
|
danielebarchiesi@0
|
334 // Since some of the submit handlers are run, redirects need to be disabled.
|
danielebarchiesi@0
|
335 $form_state['no_redirect'] = TRUE;
|
danielebarchiesi@0
|
336
|
danielebarchiesi@0
|
337 // When a form is rebuilt after Ajax processing, its #build_id and #action
|
danielebarchiesi@0
|
338 // should not change.
|
danielebarchiesi@0
|
339 // @see drupal_rebuild_form()
|
danielebarchiesi@0
|
340 $form_state['rebuild_info']['copy']['#build_id'] = TRUE;
|
danielebarchiesi@0
|
341 $form_state['rebuild_info']['copy']['#action'] = TRUE;
|
danielebarchiesi@0
|
342
|
danielebarchiesi@0
|
343 // The form needs to be processed; prepare for that by setting a few internal
|
danielebarchiesi@0
|
344 // variables.
|
danielebarchiesi@0
|
345 $form_state['input'] = $_POST;
|
danielebarchiesi@0
|
346 $form_id = $form['#form_id'];
|
danielebarchiesi@0
|
347
|
danielebarchiesi@0
|
348 return array($form, $form_state, $form_id, $form_build_id);
|
danielebarchiesi@0
|
349 }
|
danielebarchiesi@0
|
350
|
danielebarchiesi@0
|
351 /**
|
danielebarchiesi@0
|
352 * Menu callback; handles Ajax requests for the #ajax Form API property.
|
danielebarchiesi@0
|
353 *
|
danielebarchiesi@0
|
354 * This rebuilds the form from cache and invokes the defined #ajax['callback']
|
danielebarchiesi@0
|
355 * to return an Ajax command structure for JavaScript. In case no 'callback' has
|
danielebarchiesi@0
|
356 * been defined, nothing will happen.
|
danielebarchiesi@0
|
357 *
|
danielebarchiesi@0
|
358 * The Form API #ajax property can be set both for buttons and other input
|
danielebarchiesi@0
|
359 * elements.
|
danielebarchiesi@0
|
360 *
|
danielebarchiesi@0
|
361 * This function is also the canonical example of how to implement
|
danielebarchiesi@0
|
362 * #ajax['path']. If processing is required that cannot be accomplished with
|
danielebarchiesi@0
|
363 * a callback, re-implement this function and set #ajax['path'] to the
|
danielebarchiesi@0
|
364 * enhanced function.
|
danielebarchiesi@0
|
365 *
|
danielebarchiesi@0
|
366 * @see system_menu()
|
danielebarchiesi@0
|
367 */
|
danielebarchiesi@0
|
368 function ajax_form_callback() {
|
danielebarchiesi@0
|
369 list($form, $form_state) = ajax_get_form();
|
danielebarchiesi@0
|
370 drupal_process_form($form['#form_id'], $form, $form_state);
|
danielebarchiesi@0
|
371
|
danielebarchiesi@0
|
372 // We need to return the part of the form (or some other content) that needs
|
danielebarchiesi@0
|
373 // to be re-rendered so the browser can update the page with changed content.
|
danielebarchiesi@0
|
374 // Since this is the generic menu callback used by many Ajax elements, it is
|
danielebarchiesi@0
|
375 // up to the #ajax['callback'] function of the element (may or may not be a
|
danielebarchiesi@0
|
376 // button) that triggered the Ajax request to determine what needs to be
|
danielebarchiesi@0
|
377 // rendered.
|
danielebarchiesi@0
|
378 if (!empty($form_state['triggering_element'])) {
|
danielebarchiesi@0
|
379 $callback = $form_state['triggering_element']['#ajax']['callback'];
|
danielebarchiesi@0
|
380 }
|
danielebarchiesi@0
|
381 if (!empty($callback) && function_exists($callback)) {
|
danielebarchiesi@0
|
382 return $callback($form, $form_state);
|
danielebarchiesi@0
|
383 }
|
danielebarchiesi@0
|
384 }
|
danielebarchiesi@0
|
385
|
danielebarchiesi@0
|
386 /**
|
danielebarchiesi@0
|
387 * Theme callback for Ajax requests.
|
danielebarchiesi@0
|
388 *
|
danielebarchiesi@0
|
389 * Many different pages can invoke an Ajax request to system/ajax or another
|
danielebarchiesi@0
|
390 * generic Ajax path. It is almost always desired for an Ajax response to be
|
danielebarchiesi@0
|
391 * rendered using the same theme as the base page, because most themes are built
|
danielebarchiesi@0
|
392 * with the assumption that they control the entire page, so if the CSS for two
|
danielebarchiesi@0
|
393 * themes are both loaded for a given page, they may conflict with each other.
|
danielebarchiesi@0
|
394 * For example, Bartik is Drupal's default theme, and Seven is Drupal's default
|
danielebarchiesi@0
|
395 * administration theme. Depending on whether the "Use the administration theme
|
danielebarchiesi@0
|
396 * when editing or creating content" checkbox is checked, the node edit form may
|
danielebarchiesi@0
|
397 * be displayed in either theme, but the Ajax response to the Field module's
|
danielebarchiesi@0
|
398 * "Add another item" button should be rendered using the same theme as the rest
|
danielebarchiesi@0
|
399 * of the page. Therefore, system_menu() sets the 'theme callback' for
|
danielebarchiesi@0
|
400 * 'system/ajax' to this function, and it is recommended that modules
|
danielebarchiesi@0
|
401 * implementing other generic Ajax paths do the same.
|
danielebarchiesi@0
|
402 *
|
danielebarchiesi@0
|
403 * @see system_menu()
|
danielebarchiesi@0
|
404 * @see file_menu()
|
danielebarchiesi@0
|
405 */
|
danielebarchiesi@0
|
406 function ajax_base_page_theme() {
|
danielebarchiesi@0
|
407 if (!empty($_POST['ajax_page_state']['theme']) && !empty($_POST['ajax_page_state']['theme_token'])) {
|
danielebarchiesi@0
|
408 $theme = $_POST['ajax_page_state']['theme'];
|
danielebarchiesi@0
|
409 $token = $_POST['ajax_page_state']['theme_token'];
|
danielebarchiesi@0
|
410
|
danielebarchiesi@0
|
411 // Prevent a request forgery from giving a person access to a theme they
|
danielebarchiesi@0
|
412 // shouldn't be otherwise allowed to see. However, since everyone is allowed
|
danielebarchiesi@0
|
413 // to see the default theme, token validation isn't required for that, and
|
danielebarchiesi@0
|
414 // bypassing it allows most use-cases to work even when accessed from the
|
danielebarchiesi@0
|
415 // page cache.
|
danielebarchiesi@0
|
416 if ($theme === variable_get('theme_default', 'bartik') || drupal_valid_token($token, $theme)) {
|
danielebarchiesi@0
|
417 return $theme;
|
danielebarchiesi@0
|
418 }
|
danielebarchiesi@0
|
419 }
|
danielebarchiesi@0
|
420 }
|
danielebarchiesi@0
|
421
|
danielebarchiesi@0
|
422 /**
|
danielebarchiesi@0
|
423 * Packages and sends the result of a page callback as an Ajax response.
|
danielebarchiesi@0
|
424 *
|
danielebarchiesi@0
|
425 * This function is the equivalent of drupal_deliver_html_page(), but for Ajax
|
danielebarchiesi@0
|
426 * requests. Like that function, it:
|
danielebarchiesi@0
|
427 * - Adds needed HTTP headers.
|
danielebarchiesi@0
|
428 * - Prints rendered output.
|
danielebarchiesi@0
|
429 * - Performs end-of-request tasks.
|
danielebarchiesi@0
|
430 *
|
danielebarchiesi@0
|
431 * @param $page_callback_result
|
danielebarchiesi@0
|
432 * The result of a page callback. Can be one of:
|
danielebarchiesi@0
|
433 * - NULL: to indicate no content.
|
danielebarchiesi@0
|
434 * - An integer menu status constant: to indicate an error condition.
|
danielebarchiesi@0
|
435 * - A string of HTML content.
|
danielebarchiesi@0
|
436 * - A renderable array of content.
|
danielebarchiesi@0
|
437 *
|
danielebarchiesi@0
|
438 * @see drupal_deliver_html_page()
|
danielebarchiesi@0
|
439 */
|
danielebarchiesi@0
|
440 function ajax_deliver($page_callback_result) {
|
danielebarchiesi@0
|
441 // Browsers do not allow JavaScript to read the contents of a user's local
|
danielebarchiesi@0
|
442 // files. To work around that, the jQuery Form plugin submits forms containing
|
danielebarchiesi@0
|
443 // a file input element to an IFRAME, instead of using XHR. Browsers do not
|
danielebarchiesi@0
|
444 // normally expect JSON strings as content within an IFRAME, so the response
|
danielebarchiesi@0
|
445 // must be customized accordingly.
|
danielebarchiesi@0
|
446 // @see http://malsup.com/jquery/form/#file-upload
|
danielebarchiesi@0
|
447 // @see Drupal.ajax.prototype.beforeSend()
|
danielebarchiesi@0
|
448 $iframe_upload = !empty($_POST['ajax_iframe_upload']);
|
danielebarchiesi@0
|
449
|
danielebarchiesi@0
|
450 // Emit a Content-Type HTTP header if none has been added by the page callback
|
danielebarchiesi@0
|
451 // or by a wrapping delivery callback.
|
danielebarchiesi@0
|
452 if (is_null(drupal_get_http_header('Content-Type'))) {
|
danielebarchiesi@0
|
453 if (!$iframe_upload) {
|
danielebarchiesi@0
|
454 // Standard JSON can be returned to a browser's XHR object, and to
|
danielebarchiesi@0
|
455 // non-browser user agents.
|
danielebarchiesi@0
|
456 // @see http://www.ietf.org/rfc/rfc4627.txt?number=4627
|
danielebarchiesi@0
|
457 drupal_add_http_header('Content-Type', 'application/json; charset=utf-8');
|
danielebarchiesi@0
|
458 }
|
danielebarchiesi@0
|
459 else {
|
danielebarchiesi@0
|
460 // Browser IFRAMEs expect HTML. With most other content types, Internet
|
danielebarchiesi@0
|
461 // Explorer presents the user with a download prompt.
|
danielebarchiesi@0
|
462 drupal_add_http_header('Content-Type', 'text/html; charset=utf-8');
|
danielebarchiesi@0
|
463 }
|
danielebarchiesi@0
|
464 }
|
danielebarchiesi@0
|
465
|
danielebarchiesi@0
|
466 // Print the response.
|
danielebarchiesi@0
|
467 $commands = ajax_prepare_response($page_callback_result);
|
danielebarchiesi@0
|
468 $json = ajax_render($commands);
|
danielebarchiesi@0
|
469 if (!$iframe_upload) {
|
danielebarchiesi@0
|
470 // Standard JSON can be returned to a browser's XHR object, and to
|
danielebarchiesi@0
|
471 // non-browser user agents.
|
danielebarchiesi@0
|
472 print $json;
|
danielebarchiesi@0
|
473 }
|
danielebarchiesi@0
|
474 else {
|
danielebarchiesi@0
|
475 // Browser IFRAMEs expect HTML. Browser extensions, such as Linkification
|
danielebarchiesi@0
|
476 // and Skype's Browser Highlighter, convert URLs, phone numbers, etc. into
|
danielebarchiesi@0
|
477 // links. This corrupts the JSON response. Protect the integrity of the
|
danielebarchiesi@0
|
478 // JSON data by making it the value of a textarea.
|
danielebarchiesi@0
|
479 // @see http://malsup.com/jquery/form/#file-upload
|
danielebarchiesi@0
|
480 // @see http://drupal.org/node/1009382
|
danielebarchiesi@0
|
481 print '<textarea>' . $json . '</textarea>';
|
danielebarchiesi@0
|
482 }
|
danielebarchiesi@0
|
483
|
danielebarchiesi@0
|
484 // Perform end-of-request tasks.
|
danielebarchiesi@0
|
485 ajax_footer();
|
danielebarchiesi@0
|
486 }
|
danielebarchiesi@0
|
487
|
danielebarchiesi@0
|
488 /**
|
danielebarchiesi@0
|
489 * Converts the return value of a page callback into an Ajax commands array.
|
danielebarchiesi@0
|
490 *
|
danielebarchiesi@0
|
491 * @param $page_callback_result
|
danielebarchiesi@0
|
492 * The result of a page callback. Can be one of:
|
danielebarchiesi@0
|
493 * - NULL: to indicate no content.
|
danielebarchiesi@0
|
494 * - An integer menu status constant: to indicate an error condition.
|
danielebarchiesi@0
|
495 * - A string of HTML content.
|
danielebarchiesi@0
|
496 * - A renderable array of content.
|
danielebarchiesi@0
|
497 *
|
danielebarchiesi@0
|
498 * @return
|
danielebarchiesi@0
|
499 * An Ajax commands array that can be passed to ajax_render().
|
danielebarchiesi@0
|
500 */
|
danielebarchiesi@0
|
501 function ajax_prepare_response($page_callback_result) {
|
danielebarchiesi@0
|
502 $commands = array();
|
danielebarchiesi@0
|
503 if (!isset($page_callback_result)) {
|
danielebarchiesi@0
|
504 // Simply delivering an empty commands array is sufficient. This results
|
danielebarchiesi@0
|
505 // in the Ajax request being completed, but nothing being done to the page.
|
danielebarchiesi@0
|
506 }
|
danielebarchiesi@0
|
507 elseif (is_int($page_callback_result)) {
|
danielebarchiesi@0
|
508 switch ($page_callback_result) {
|
danielebarchiesi@0
|
509 case MENU_NOT_FOUND:
|
danielebarchiesi@0
|
510 $commands[] = ajax_command_alert(t('The requested page could not be found.'));
|
danielebarchiesi@0
|
511 break;
|
danielebarchiesi@0
|
512
|
danielebarchiesi@0
|
513 case MENU_ACCESS_DENIED:
|
danielebarchiesi@0
|
514 $commands[] = ajax_command_alert(t('You are not authorized to access this page.'));
|
danielebarchiesi@0
|
515 break;
|
danielebarchiesi@0
|
516
|
danielebarchiesi@0
|
517 case MENU_SITE_OFFLINE:
|
danielebarchiesi@0
|
518 $commands[] = ajax_command_alert(filter_xss_admin(variable_get('maintenance_mode_message',
|
danielebarchiesi@0
|
519 t('@site is currently under maintenance. We should be back shortly. Thank you for your patience.', array('@site' => variable_get('site_name', 'Drupal'))))));
|
danielebarchiesi@0
|
520 break;
|
danielebarchiesi@0
|
521 }
|
danielebarchiesi@0
|
522 }
|
danielebarchiesi@0
|
523 elseif (is_array($page_callback_result) && isset($page_callback_result['#type']) && ($page_callback_result['#type'] == 'ajax')) {
|
danielebarchiesi@0
|
524 // Complex Ajax callbacks can return a result that contains an error message
|
danielebarchiesi@0
|
525 // or a specific set of commands to send to the browser.
|
danielebarchiesi@0
|
526 $page_callback_result += element_info('ajax');
|
danielebarchiesi@0
|
527 $error = $page_callback_result['#error'];
|
danielebarchiesi@0
|
528 if (isset($error) && $error !== FALSE) {
|
danielebarchiesi@0
|
529 if ((empty($error) || $error === TRUE)) {
|
danielebarchiesi@0
|
530 $error = t('An error occurred while handling the request: The server received invalid input.');
|
danielebarchiesi@0
|
531 }
|
danielebarchiesi@0
|
532 $commands[] = ajax_command_alert($error);
|
danielebarchiesi@0
|
533 }
|
danielebarchiesi@0
|
534 else {
|
danielebarchiesi@0
|
535 $commands = $page_callback_result['#commands'];
|
danielebarchiesi@0
|
536 }
|
danielebarchiesi@0
|
537 }
|
danielebarchiesi@0
|
538 else {
|
danielebarchiesi@0
|
539 // Like normal page callbacks, simple Ajax callbacks can return HTML
|
danielebarchiesi@0
|
540 // content, as a string or render array. This HTML is inserted in some
|
danielebarchiesi@0
|
541 // relationship to #ajax['wrapper'], as determined by which jQuery DOM
|
danielebarchiesi@0
|
542 // manipulation method is used. The method used is specified by
|
danielebarchiesi@0
|
543 // #ajax['method']. The default method is 'replaceWith', which completely
|
danielebarchiesi@0
|
544 // replaces the old wrapper element and its content with the new HTML.
|
danielebarchiesi@0
|
545 $html = is_string($page_callback_result) ? $page_callback_result : drupal_render($page_callback_result);
|
danielebarchiesi@0
|
546 $commands[] = ajax_command_insert(NULL, $html);
|
danielebarchiesi@0
|
547 // Add the status messages inside the new content's wrapper element, so that
|
danielebarchiesi@0
|
548 // on subsequent Ajax requests, it is treated as old content.
|
danielebarchiesi@0
|
549 $commands[] = ajax_command_prepend(NULL, theme('status_messages'));
|
danielebarchiesi@0
|
550 }
|
danielebarchiesi@0
|
551
|
danielebarchiesi@0
|
552 return $commands;
|
danielebarchiesi@0
|
553 }
|
danielebarchiesi@0
|
554
|
danielebarchiesi@0
|
555 /**
|
danielebarchiesi@0
|
556 * Performs end-of-Ajax-request tasks.
|
danielebarchiesi@0
|
557 *
|
danielebarchiesi@0
|
558 * This function is the equivalent of drupal_page_footer(), but for Ajax
|
danielebarchiesi@0
|
559 * requests.
|
danielebarchiesi@0
|
560 *
|
danielebarchiesi@0
|
561 * @see drupal_page_footer()
|
danielebarchiesi@0
|
562 */
|
danielebarchiesi@0
|
563 function ajax_footer() {
|
danielebarchiesi@0
|
564 // Even for Ajax requests, invoke hook_exit() implementations. There may be
|
danielebarchiesi@0
|
565 // modules that need very fast Ajax responses, and therefore, run Ajax
|
danielebarchiesi@0
|
566 // requests with an early bootstrap.
|
danielebarchiesi@0
|
567 if (drupal_get_bootstrap_phase() == DRUPAL_BOOTSTRAP_FULL && (!defined('MAINTENANCE_MODE') || MAINTENANCE_MODE != 'update')) {
|
danielebarchiesi@0
|
568 module_invoke_all('exit');
|
danielebarchiesi@0
|
569 }
|
danielebarchiesi@0
|
570
|
danielebarchiesi@0
|
571 // Commit the user session. See above comment about the possibility of this
|
danielebarchiesi@0
|
572 // function running without session.inc loaded.
|
danielebarchiesi@0
|
573 if (function_exists('drupal_session_commit')) {
|
danielebarchiesi@0
|
574 drupal_session_commit();
|
danielebarchiesi@0
|
575 }
|
danielebarchiesi@0
|
576 }
|
danielebarchiesi@0
|
577
|
danielebarchiesi@0
|
578 /**
|
danielebarchiesi@0
|
579 * Form element processing handler for the #ajax form property.
|
danielebarchiesi@0
|
580 *
|
danielebarchiesi@0
|
581 * @param $element
|
danielebarchiesi@0
|
582 * An associative array containing the properties of the element.
|
danielebarchiesi@0
|
583 *
|
danielebarchiesi@0
|
584 * @return
|
danielebarchiesi@0
|
585 * The processed element.
|
danielebarchiesi@0
|
586 *
|
danielebarchiesi@0
|
587 * @see ajax_pre_render_element()
|
danielebarchiesi@0
|
588 */
|
danielebarchiesi@0
|
589 function ajax_process_form($element, &$form_state) {
|
danielebarchiesi@0
|
590 $element = ajax_pre_render_element($element);
|
danielebarchiesi@0
|
591 if (!empty($element['#ajax_processed'])) {
|
danielebarchiesi@0
|
592 $form_state['cache'] = TRUE;
|
danielebarchiesi@0
|
593 }
|
danielebarchiesi@0
|
594 return $element;
|
danielebarchiesi@0
|
595 }
|
danielebarchiesi@0
|
596
|
danielebarchiesi@0
|
597 /**
|
danielebarchiesi@0
|
598 * Adds Ajax information about an element to communicate with JavaScript.
|
danielebarchiesi@0
|
599 *
|
danielebarchiesi@0
|
600 * If #ajax['path'] is set on an element, this additional JavaScript is added
|
danielebarchiesi@0
|
601 * to the page header to attach the Ajax behaviors. See ajax.js for more
|
danielebarchiesi@0
|
602 * information.
|
danielebarchiesi@0
|
603 *
|
danielebarchiesi@0
|
604 * @param $element
|
danielebarchiesi@0
|
605 * An associative array containing the properties of the element.
|
danielebarchiesi@0
|
606 * Properties used:
|
danielebarchiesi@0
|
607 * - #ajax['event']
|
danielebarchiesi@0
|
608 * - #ajax['prevent']
|
danielebarchiesi@0
|
609 * - #ajax['path']
|
danielebarchiesi@0
|
610 * - #ajax['options']
|
danielebarchiesi@0
|
611 * - #ajax['wrapper']
|
danielebarchiesi@0
|
612 * - #ajax['parameters']
|
danielebarchiesi@0
|
613 * - #ajax['effect']
|
danielebarchiesi@0
|
614 *
|
danielebarchiesi@0
|
615 * @return
|
danielebarchiesi@0
|
616 * The processed element with the necessary JavaScript attached to it.
|
danielebarchiesi@0
|
617 */
|
danielebarchiesi@0
|
618 function ajax_pre_render_element($element) {
|
danielebarchiesi@0
|
619 // Skip already processed elements.
|
danielebarchiesi@0
|
620 if (isset($element['#ajax_processed'])) {
|
danielebarchiesi@0
|
621 return $element;
|
danielebarchiesi@0
|
622 }
|
danielebarchiesi@0
|
623 // Initialize #ajax_processed, so we do not process this element again.
|
danielebarchiesi@0
|
624 $element['#ajax_processed'] = FALSE;
|
danielebarchiesi@0
|
625
|
danielebarchiesi@0
|
626 // Nothing to do if there is neither a callback nor a path.
|
danielebarchiesi@0
|
627 if (!(isset($element['#ajax']['callback']) || isset($element['#ajax']['path']))) {
|
danielebarchiesi@0
|
628 return $element;
|
danielebarchiesi@0
|
629 }
|
danielebarchiesi@0
|
630
|
danielebarchiesi@0
|
631 // Add a reasonable default event handler if none was specified.
|
danielebarchiesi@0
|
632 if (isset($element['#ajax']) && !isset($element['#ajax']['event'])) {
|
danielebarchiesi@0
|
633 switch ($element['#type']) {
|
danielebarchiesi@0
|
634 case 'submit':
|
danielebarchiesi@0
|
635 case 'button':
|
danielebarchiesi@0
|
636 case 'image_button':
|
danielebarchiesi@0
|
637 // Pressing the ENTER key within a textfield triggers the click event of
|
danielebarchiesi@0
|
638 // the form's first submit button. Triggering Ajax in this situation
|
danielebarchiesi@0
|
639 // leads to problems, like breaking autocomplete textfields, so we bind
|
danielebarchiesi@0
|
640 // to mousedown instead of click.
|
danielebarchiesi@0
|
641 // @see http://drupal.org/node/216059
|
danielebarchiesi@0
|
642 $element['#ajax']['event'] = 'mousedown';
|
danielebarchiesi@0
|
643 // Retain keyboard accessibility by setting 'keypress'. This causes
|
danielebarchiesi@0
|
644 // ajax.js to trigger 'event' when SPACE or ENTER are pressed while the
|
danielebarchiesi@0
|
645 // button has focus.
|
danielebarchiesi@0
|
646 $element['#ajax']['keypress'] = TRUE;
|
danielebarchiesi@0
|
647 // Binding to mousedown rather than click means that it is possible to
|
danielebarchiesi@0
|
648 // trigger a click by pressing the mouse, holding the mouse button down
|
danielebarchiesi@0
|
649 // until the Ajax request is complete and the button is re-enabled, and
|
danielebarchiesi@0
|
650 // then releasing the mouse button. Set 'prevent' so that ajax.js binds
|
danielebarchiesi@0
|
651 // an additional handler to prevent such a click from triggering a
|
danielebarchiesi@0
|
652 // non-Ajax form submission. This also prevents a textfield's ENTER
|
danielebarchiesi@0
|
653 // press triggering this button's non-Ajax form submission behavior.
|
danielebarchiesi@0
|
654 if (!isset($element['#ajax']['prevent'])) {
|
danielebarchiesi@0
|
655 $element['#ajax']['prevent'] = 'click';
|
danielebarchiesi@0
|
656 }
|
danielebarchiesi@0
|
657 break;
|
danielebarchiesi@0
|
658
|
danielebarchiesi@0
|
659 case 'password':
|
danielebarchiesi@0
|
660 case 'textfield':
|
danielebarchiesi@0
|
661 case 'textarea':
|
danielebarchiesi@0
|
662 $element['#ajax']['event'] = 'blur';
|
danielebarchiesi@0
|
663 break;
|
danielebarchiesi@0
|
664
|
danielebarchiesi@0
|
665 case 'radio':
|
danielebarchiesi@0
|
666 case 'checkbox':
|
danielebarchiesi@0
|
667 case 'select':
|
danielebarchiesi@0
|
668 $element['#ajax']['event'] = 'change';
|
danielebarchiesi@0
|
669 break;
|
danielebarchiesi@0
|
670
|
danielebarchiesi@0
|
671 case 'link':
|
danielebarchiesi@0
|
672 $element['#ajax']['event'] = 'click';
|
danielebarchiesi@0
|
673 break;
|
danielebarchiesi@0
|
674
|
danielebarchiesi@0
|
675 default:
|
danielebarchiesi@0
|
676 return $element;
|
danielebarchiesi@0
|
677 }
|
danielebarchiesi@0
|
678 }
|
danielebarchiesi@0
|
679
|
danielebarchiesi@0
|
680 // Attach JavaScript settings to the element.
|
danielebarchiesi@0
|
681 if (isset($element['#ajax']['event'])) {
|
danielebarchiesi@0
|
682 $element['#attached']['library'][] = array('system', 'jquery.form');
|
danielebarchiesi@0
|
683 $element['#attached']['library'][] = array('system', 'drupal.ajax');
|
danielebarchiesi@0
|
684
|
danielebarchiesi@0
|
685 $settings = $element['#ajax'];
|
danielebarchiesi@0
|
686
|
danielebarchiesi@0
|
687 // Assign default settings.
|
danielebarchiesi@0
|
688 $settings += array(
|
danielebarchiesi@0
|
689 'path' => 'system/ajax',
|
danielebarchiesi@0
|
690 'options' => array(),
|
danielebarchiesi@0
|
691 );
|
danielebarchiesi@0
|
692
|
danielebarchiesi@0
|
693 // @todo Legacy support. Remove in Drupal 8.
|
danielebarchiesi@0
|
694 if (isset($settings['method']) && $settings['method'] == 'replace') {
|
danielebarchiesi@0
|
695 $settings['method'] = 'replaceWith';
|
danielebarchiesi@0
|
696 }
|
danielebarchiesi@0
|
697
|
danielebarchiesi@0
|
698 // Change path to URL.
|
danielebarchiesi@0
|
699 $settings['url'] = url($settings['path'], $settings['options']);
|
danielebarchiesi@0
|
700 unset($settings['path'], $settings['options']);
|
danielebarchiesi@0
|
701
|
danielebarchiesi@0
|
702 // Add special data to $settings['submit'] so that when this element
|
danielebarchiesi@0
|
703 // triggers an Ajax submission, Drupal's form processing can determine which
|
danielebarchiesi@0
|
704 // element triggered it.
|
danielebarchiesi@0
|
705 // @see _form_element_triggered_scripted_submission()
|
danielebarchiesi@0
|
706 if (isset($settings['trigger_as'])) {
|
danielebarchiesi@0
|
707 // An element can add a 'trigger_as' key within #ajax to make the element
|
danielebarchiesi@0
|
708 // submit as though another one (for example, a non-button can use this
|
danielebarchiesi@0
|
709 // to submit the form as though a button were clicked). When using this,
|
danielebarchiesi@0
|
710 // the 'name' key is always required to identify the element to trigger
|
danielebarchiesi@0
|
711 // as. The 'value' key is optional, and only needed when multiple elements
|
danielebarchiesi@0
|
712 // share the same name, which is commonly the case for buttons.
|
danielebarchiesi@0
|
713 $settings['submit']['_triggering_element_name'] = $settings['trigger_as']['name'];
|
danielebarchiesi@0
|
714 if (isset($settings['trigger_as']['value'])) {
|
danielebarchiesi@0
|
715 $settings['submit']['_triggering_element_value'] = $settings['trigger_as']['value'];
|
danielebarchiesi@0
|
716 }
|
danielebarchiesi@0
|
717 unset($settings['trigger_as']);
|
danielebarchiesi@0
|
718 }
|
danielebarchiesi@0
|
719 elseif (isset($element['#name'])) {
|
danielebarchiesi@0
|
720 // Most of the time, elements can submit as themselves, in which case the
|
danielebarchiesi@0
|
721 // 'trigger_as' key isn't needed, and the element's name is used.
|
danielebarchiesi@0
|
722 $settings['submit']['_triggering_element_name'] = $element['#name'];
|
danielebarchiesi@0
|
723 // If the element is a (non-image) button, its name may not identify it
|
danielebarchiesi@0
|
724 // uniquely, in which case a match on value is also needed.
|
danielebarchiesi@0
|
725 // @see _form_button_was_clicked()
|
danielebarchiesi@0
|
726 if (isset($element['#button_type']) && empty($element['#has_garbage_value'])) {
|
danielebarchiesi@0
|
727 $settings['submit']['_triggering_element_value'] = $element['#value'];
|
danielebarchiesi@0
|
728 }
|
danielebarchiesi@0
|
729 }
|
danielebarchiesi@0
|
730
|
danielebarchiesi@0
|
731 // Convert a simple #ajax['progress'] string into an array.
|
danielebarchiesi@0
|
732 if (isset($settings['progress']) && is_string($settings['progress'])) {
|
danielebarchiesi@0
|
733 $settings['progress'] = array('type' => $settings['progress']);
|
danielebarchiesi@0
|
734 }
|
danielebarchiesi@0
|
735 // Change progress path to a full URL.
|
danielebarchiesi@0
|
736 if (isset($settings['progress']['path'])) {
|
danielebarchiesi@0
|
737 $settings['progress']['url'] = url($settings['progress']['path']);
|
danielebarchiesi@0
|
738 unset($settings['progress']['path']);
|
danielebarchiesi@0
|
739 }
|
danielebarchiesi@0
|
740
|
danielebarchiesi@0
|
741 $element['#attached']['js'][] = array(
|
danielebarchiesi@0
|
742 'type' => 'setting',
|
danielebarchiesi@0
|
743 'data' => array('ajax' => array($element['#id'] => $settings)),
|
danielebarchiesi@0
|
744 );
|
danielebarchiesi@0
|
745
|
danielebarchiesi@0
|
746 // Indicate that Ajax processing was successful.
|
danielebarchiesi@0
|
747 $element['#ajax_processed'] = TRUE;
|
danielebarchiesi@0
|
748 }
|
danielebarchiesi@0
|
749 return $element;
|
danielebarchiesi@0
|
750 }
|
danielebarchiesi@0
|
751
|
danielebarchiesi@0
|
752 /**
|
danielebarchiesi@0
|
753 * @} End of "defgroup ajax".
|
danielebarchiesi@0
|
754 */
|
danielebarchiesi@0
|
755
|
danielebarchiesi@0
|
756 /**
|
danielebarchiesi@0
|
757 * @defgroup ajax_commands Ajax framework commands
|
danielebarchiesi@0
|
758 * @{
|
danielebarchiesi@0
|
759 * Functions to create various Ajax commands.
|
danielebarchiesi@0
|
760 *
|
danielebarchiesi@0
|
761 * These functions can be used to create arrays for use with the
|
danielebarchiesi@0
|
762 * ajax_render() function.
|
danielebarchiesi@0
|
763 */
|
danielebarchiesi@0
|
764
|
danielebarchiesi@0
|
765 /**
|
danielebarchiesi@0
|
766 * Creates a Drupal Ajax 'alert' command.
|
danielebarchiesi@0
|
767 *
|
danielebarchiesi@0
|
768 * The 'alert' command instructs the client to display a JavaScript alert
|
danielebarchiesi@0
|
769 * dialog box.
|
danielebarchiesi@0
|
770 *
|
danielebarchiesi@0
|
771 * This command is implemented by Drupal.ajax.prototype.commands.alert()
|
danielebarchiesi@0
|
772 * defined in misc/ajax.js.
|
danielebarchiesi@0
|
773 *
|
danielebarchiesi@0
|
774 * @param $text
|
danielebarchiesi@0
|
775 * The message string to display to the user.
|
danielebarchiesi@0
|
776 *
|
danielebarchiesi@0
|
777 * @return
|
danielebarchiesi@0
|
778 * An array suitable for use with the ajax_render() function.
|
danielebarchiesi@0
|
779 */
|
danielebarchiesi@0
|
780 function ajax_command_alert($text) {
|
danielebarchiesi@0
|
781 return array(
|
danielebarchiesi@0
|
782 'command' => 'alert',
|
danielebarchiesi@0
|
783 'text' => $text,
|
danielebarchiesi@0
|
784 );
|
danielebarchiesi@0
|
785 }
|
danielebarchiesi@0
|
786
|
danielebarchiesi@0
|
787 /**
|
danielebarchiesi@0
|
788 * Creates a Drupal Ajax 'insert' command using the method in #ajax['method'].
|
danielebarchiesi@0
|
789 *
|
danielebarchiesi@0
|
790 * This command instructs the client to insert the given HTML using whichever
|
danielebarchiesi@0
|
791 * jQuery DOM manipulation method has been specified in the #ajax['method']
|
danielebarchiesi@0
|
792 * variable of the element that triggered the request.
|
danielebarchiesi@0
|
793 *
|
danielebarchiesi@0
|
794 * This command is implemented by Drupal.ajax.prototype.commands.insert()
|
danielebarchiesi@0
|
795 * defined in misc/ajax.js.
|
danielebarchiesi@0
|
796 *
|
danielebarchiesi@0
|
797 * @param $selector
|
danielebarchiesi@0
|
798 * A jQuery selector string. If the command is a response to a request from
|
danielebarchiesi@0
|
799 * an #ajax form element then this value can be NULL.
|
danielebarchiesi@0
|
800 * @param $html
|
danielebarchiesi@0
|
801 * The data to use with the jQuery method.
|
danielebarchiesi@0
|
802 * @param $settings
|
danielebarchiesi@0
|
803 * An optional array of settings that will be used for this command only.
|
danielebarchiesi@0
|
804 *
|
danielebarchiesi@0
|
805 * @return
|
danielebarchiesi@0
|
806 * An array suitable for use with the ajax_render() function.
|
danielebarchiesi@0
|
807 */
|
danielebarchiesi@0
|
808 function ajax_command_insert($selector, $html, $settings = NULL) {
|
danielebarchiesi@0
|
809 return array(
|
danielebarchiesi@0
|
810 'command' => 'insert',
|
danielebarchiesi@0
|
811 'method' => NULL,
|
danielebarchiesi@0
|
812 'selector' => $selector,
|
danielebarchiesi@0
|
813 'data' => $html,
|
danielebarchiesi@0
|
814 'settings' => $settings,
|
danielebarchiesi@0
|
815 );
|
danielebarchiesi@0
|
816 }
|
danielebarchiesi@0
|
817
|
danielebarchiesi@0
|
818 /**
|
danielebarchiesi@0
|
819 * Creates a Drupal Ajax 'insert/replaceWith' command.
|
danielebarchiesi@0
|
820 *
|
danielebarchiesi@0
|
821 * The 'insert/replaceWith' command instructs the client to use jQuery's
|
danielebarchiesi@0
|
822 * replaceWith() method to replace each element matched matched by the given
|
danielebarchiesi@0
|
823 * selector with the given HTML.
|
danielebarchiesi@0
|
824 *
|
danielebarchiesi@0
|
825 * This command is implemented by Drupal.ajax.prototype.commands.insert()
|
danielebarchiesi@0
|
826 * defined in misc/ajax.js.
|
danielebarchiesi@0
|
827 *
|
danielebarchiesi@0
|
828 * @param $selector
|
danielebarchiesi@0
|
829 * A jQuery selector string. If the command is a response to a request from
|
danielebarchiesi@0
|
830 * an #ajax form element then this value can be NULL.
|
danielebarchiesi@0
|
831 * @param $html
|
danielebarchiesi@0
|
832 * The data to use with the jQuery replaceWith() method.
|
danielebarchiesi@0
|
833 * @param $settings
|
danielebarchiesi@0
|
834 * An optional array of settings that will be used for this command only.
|
danielebarchiesi@0
|
835 *
|
danielebarchiesi@0
|
836 * @return
|
danielebarchiesi@0
|
837 * An array suitable for use with the ajax_render() function.
|
danielebarchiesi@0
|
838 *
|
danielebarchiesi@0
|
839 * See
|
danielebarchiesi@0
|
840 * @link http://docs.jquery.com/Manipulation/replaceWith#content jQuery replaceWith command @endlink
|
danielebarchiesi@0
|
841 */
|
danielebarchiesi@0
|
842 function ajax_command_replace($selector, $html, $settings = NULL) {
|
danielebarchiesi@0
|
843 return array(
|
danielebarchiesi@0
|
844 'command' => 'insert',
|
danielebarchiesi@0
|
845 'method' => 'replaceWith',
|
danielebarchiesi@0
|
846 'selector' => $selector,
|
danielebarchiesi@0
|
847 'data' => $html,
|
danielebarchiesi@0
|
848 'settings' => $settings,
|
danielebarchiesi@0
|
849 );
|
danielebarchiesi@0
|
850 }
|
danielebarchiesi@0
|
851
|
danielebarchiesi@0
|
852 /**
|
danielebarchiesi@0
|
853 * Creates a Drupal Ajax 'insert/html' command.
|
danielebarchiesi@0
|
854 *
|
danielebarchiesi@0
|
855 * The 'insert/html' command instructs the client to use jQuery's html()
|
danielebarchiesi@0
|
856 * method to set the HTML content of each element matched by the given
|
danielebarchiesi@0
|
857 * selector while leaving the outer tags intact.
|
danielebarchiesi@0
|
858 *
|
danielebarchiesi@0
|
859 * This command is implemented by Drupal.ajax.prototype.commands.insert()
|
danielebarchiesi@0
|
860 * defined in misc/ajax.js.
|
danielebarchiesi@0
|
861 *
|
danielebarchiesi@0
|
862 * @param $selector
|
danielebarchiesi@0
|
863 * A jQuery selector string. If the command is a response to a request from
|
danielebarchiesi@0
|
864 * an #ajax form element then this value can be NULL.
|
danielebarchiesi@0
|
865 * @param $html
|
danielebarchiesi@0
|
866 * The data to use with the jQuery html() method.
|
danielebarchiesi@0
|
867 * @param $settings
|
danielebarchiesi@0
|
868 * An optional array of settings that will be used for this command only.
|
danielebarchiesi@0
|
869 *
|
danielebarchiesi@0
|
870 * @return
|
danielebarchiesi@0
|
871 * An array suitable for use with the ajax_render() function.
|
danielebarchiesi@0
|
872 *
|
danielebarchiesi@0
|
873 * @see http://docs.jquery.com/Attributes/html#val
|
danielebarchiesi@0
|
874 */
|
danielebarchiesi@0
|
875 function ajax_command_html($selector, $html, $settings = NULL) {
|
danielebarchiesi@0
|
876 return array(
|
danielebarchiesi@0
|
877 'command' => 'insert',
|
danielebarchiesi@0
|
878 'method' => 'html',
|
danielebarchiesi@0
|
879 'selector' => $selector,
|
danielebarchiesi@0
|
880 'data' => $html,
|
danielebarchiesi@0
|
881 'settings' => $settings,
|
danielebarchiesi@0
|
882 );
|
danielebarchiesi@0
|
883 }
|
danielebarchiesi@0
|
884
|
danielebarchiesi@0
|
885 /**
|
danielebarchiesi@0
|
886 * Creates a Drupal Ajax 'insert/prepend' command.
|
danielebarchiesi@0
|
887 *
|
danielebarchiesi@0
|
888 * The 'insert/prepend' command instructs the client to use jQuery's prepend()
|
danielebarchiesi@0
|
889 * method to prepend the given HTML content to the inside each element matched
|
danielebarchiesi@0
|
890 * by the given selector.
|
danielebarchiesi@0
|
891 *
|
danielebarchiesi@0
|
892 * This command is implemented by Drupal.ajax.prototype.commands.insert()
|
danielebarchiesi@0
|
893 * defined in misc/ajax.js.
|
danielebarchiesi@0
|
894 *
|
danielebarchiesi@0
|
895 * @param $selector
|
danielebarchiesi@0
|
896 * A jQuery selector string. If the command is a response to a request from
|
danielebarchiesi@0
|
897 * an #ajax form element then this value can be NULL.
|
danielebarchiesi@0
|
898 * @param $html
|
danielebarchiesi@0
|
899 * The data to use with the jQuery prepend() method.
|
danielebarchiesi@0
|
900 * @param $settings
|
danielebarchiesi@0
|
901 * An optional array of settings that will be used for this command only.
|
danielebarchiesi@0
|
902 *
|
danielebarchiesi@0
|
903 * @return
|
danielebarchiesi@0
|
904 * An array suitable for use with the ajax_render() function.
|
danielebarchiesi@0
|
905 *
|
danielebarchiesi@0
|
906 * @see http://docs.jquery.com/Manipulation/prepend#content
|
danielebarchiesi@0
|
907 */
|
danielebarchiesi@0
|
908 function ajax_command_prepend($selector, $html, $settings = NULL) {
|
danielebarchiesi@0
|
909 return array(
|
danielebarchiesi@0
|
910 'command' => 'insert',
|
danielebarchiesi@0
|
911 'method' => 'prepend',
|
danielebarchiesi@0
|
912 'selector' => $selector,
|
danielebarchiesi@0
|
913 'data' => $html,
|
danielebarchiesi@0
|
914 'settings' => $settings,
|
danielebarchiesi@0
|
915 );
|
danielebarchiesi@0
|
916 }
|
danielebarchiesi@0
|
917
|
danielebarchiesi@0
|
918 /**
|
danielebarchiesi@0
|
919 * Creates a Drupal Ajax 'insert/append' command.
|
danielebarchiesi@0
|
920 *
|
danielebarchiesi@0
|
921 * The 'insert/append' command instructs the client to use jQuery's append()
|
danielebarchiesi@0
|
922 * method to append the given HTML content to the inside of each element matched
|
danielebarchiesi@0
|
923 * by the given selector.
|
danielebarchiesi@0
|
924 *
|
danielebarchiesi@0
|
925 * This command is implemented by Drupal.ajax.prototype.commands.insert()
|
danielebarchiesi@0
|
926 * defined in misc/ajax.js.
|
danielebarchiesi@0
|
927 *
|
danielebarchiesi@0
|
928 * @param $selector
|
danielebarchiesi@0
|
929 * A jQuery selector string. If the command is a response to a request from
|
danielebarchiesi@0
|
930 * an #ajax form element then this value can be NULL.
|
danielebarchiesi@0
|
931 * @param $html
|
danielebarchiesi@0
|
932 * The data to use with the jQuery append() method.
|
danielebarchiesi@0
|
933 * @param $settings
|
danielebarchiesi@0
|
934 * An optional array of settings that will be used for this command only.
|
danielebarchiesi@0
|
935 *
|
danielebarchiesi@0
|
936 * @return
|
danielebarchiesi@0
|
937 * An array suitable for use with the ajax_render() function.
|
danielebarchiesi@0
|
938 *
|
danielebarchiesi@0
|
939 * @see http://docs.jquery.com/Manipulation/append#content
|
danielebarchiesi@0
|
940 */
|
danielebarchiesi@0
|
941 function ajax_command_append($selector, $html, $settings = NULL) {
|
danielebarchiesi@0
|
942 return array(
|
danielebarchiesi@0
|
943 'command' => 'insert',
|
danielebarchiesi@0
|
944 'method' => 'append',
|
danielebarchiesi@0
|
945 'selector' => $selector,
|
danielebarchiesi@0
|
946 'data' => $html,
|
danielebarchiesi@0
|
947 'settings' => $settings,
|
danielebarchiesi@0
|
948 );
|
danielebarchiesi@0
|
949 }
|
danielebarchiesi@0
|
950
|
danielebarchiesi@0
|
951 /**
|
danielebarchiesi@0
|
952 * Creates a Drupal Ajax 'insert/after' command.
|
danielebarchiesi@0
|
953 *
|
danielebarchiesi@0
|
954 * The 'insert/after' command instructs the client to use jQuery's after()
|
danielebarchiesi@0
|
955 * method to insert the given HTML content after each element matched by
|
danielebarchiesi@0
|
956 * the given selector.
|
danielebarchiesi@0
|
957 *
|
danielebarchiesi@0
|
958 * This command is implemented by Drupal.ajax.prototype.commands.insert()
|
danielebarchiesi@0
|
959 * defined in misc/ajax.js.
|
danielebarchiesi@0
|
960 *
|
danielebarchiesi@0
|
961 * @param $selector
|
danielebarchiesi@0
|
962 * A jQuery selector string. If the command is a response to a request from
|
danielebarchiesi@0
|
963 * an #ajax form element then this value can be NULL.
|
danielebarchiesi@0
|
964 * @param $html
|
danielebarchiesi@0
|
965 * The data to use with the jQuery after() method.
|
danielebarchiesi@0
|
966 * @param $settings
|
danielebarchiesi@0
|
967 * An optional array of settings that will be used for this command only.
|
danielebarchiesi@0
|
968 *
|
danielebarchiesi@0
|
969 * @return
|
danielebarchiesi@0
|
970 * An array suitable for use with the ajax_render() function.
|
danielebarchiesi@0
|
971 *
|
danielebarchiesi@0
|
972 * @see http://docs.jquery.com/Manipulation/after#content
|
danielebarchiesi@0
|
973 */
|
danielebarchiesi@0
|
974 function ajax_command_after($selector, $html, $settings = NULL) {
|
danielebarchiesi@0
|
975 return array(
|
danielebarchiesi@0
|
976 'command' => 'insert',
|
danielebarchiesi@0
|
977 'method' => 'after',
|
danielebarchiesi@0
|
978 'selector' => $selector,
|
danielebarchiesi@0
|
979 'data' => $html,
|
danielebarchiesi@0
|
980 'settings' => $settings,
|
danielebarchiesi@0
|
981 );
|
danielebarchiesi@0
|
982 }
|
danielebarchiesi@0
|
983
|
danielebarchiesi@0
|
984 /**
|
danielebarchiesi@0
|
985 * Creates a Drupal Ajax 'insert/before' command.
|
danielebarchiesi@0
|
986 *
|
danielebarchiesi@0
|
987 * The 'insert/before' command instructs the client to use jQuery's before()
|
danielebarchiesi@0
|
988 * method to insert the given HTML content before each of elements matched by
|
danielebarchiesi@0
|
989 * the given selector.
|
danielebarchiesi@0
|
990 *
|
danielebarchiesi@0
|
991 * This command is implemented by Drupal.ajax.prototype.commands.insert()
|
danielebarchiesi@0
|
992 * defined in misc/ajax.js.
|
danielebarchiesi@0
|
993 *
|
danielebarchiesi@0
|
994 * @param $selector
|
danielebarchiesi@0
|
995 * A jQuery selector string. If the command is a response to a request from
|
danielebarchiesi@0
|
996 * an #ajax form element then this value can be NULL.
|
danielebarchiesi@0
|
997 * @param $html
|
danielebarchiesi@0
|
998 * The data to use with the jQuery before() method.
|
danielebarchiesi@0
|
999 * @param $settings
|
danielebarchiesi@0
|
1000 * An optional array of settings that will be used for this command only.
|
danielebarchiesi@0
|
1001 *
|
danielebarchiesi@0
|
1002 * @return
|
danielebarchiesi@0
|
1003 * An array suitable for use with the ajax_render() function.
|
danielebarchiesi@0
|
1004 *
|
danielebarchiesi@0
|
1005 * @see http://docs.jquery.com/Manipulation/before#content
|
danielebarchiesi@0
|
1006 */
|
danielebarchiesi@0
|
1007 function ajax_command_before($selector, $html, $settings = NULL) {
|
danielebarchiesi@0
|
1008 return array(
|
danielebarchiesi@0
|
1009 'command' => 'insert',
|
danielebarchiesi@0
|
1010 'method' => 'before',
|
danielebarchiesi@0
|
1011 'selector' => $selector,
|
danielebarchiesi@0
|
1012 'data' => $html,
|
danielebarchiesi@0
|
1013 'settings' => $settings,
|
danielebarchiesi@0
|
1014 );
|
danielebarchiesi@0
|
1015 }
|
danielebarchiesi@0
|
1016
|
danielebarchiesi@0
|
1017 /**
|
danielebarchiesi@0
|
1018 * Creates a Drupal Ajax 'remove' command.
|
danielebarchiesi@0
|
1019 *
|
danielebarchiesi@0
|
1020 * The 'remove' command instructs the client to use jQuery's remove() method
|
danielebarchiesi@0
|
1021 * to remove each of elements matched by the given selector, and everything
|
danielebarchiesi@0
|
1022 * within them.
|
danielebarchiesi@0
|
1023 *
|
danielebarchiesi@0
|
1024 * This command is implemented by Drupal.ajax.prototype.commands.remove()
|
danielebarchiesi@0
|
1025 * defined in misc/ajax.js.
|
danielebarchiesi@0
|
1026 *
|
danielebarchiesi@0
|
1027 * @param $selector
|
danielebarchiesi@0
|
1028 * A jQuery selector string. If the command is a response to a request from
|
danielebarchiesi@0
|
1029 * an #ajax form element then this value can be NULL.
|
danielebarchiesi@0
|
1030 *
|
danielebarchiesi@0
|
1031 * @return
|
danielebarchiesi@0
|
1032 * An array suitable for use with the ajax_render() function.
|
danielebarchiesi@0
|
1033 *
|
danielebarchiesi@0
|
1034 * @see http://docs.jquery.com/Manipulation/remove#expr
|
danielebarchiesi@0
|
1035 */
|
danielebarchiesi@0
|
1036 function ajax_command_remove($selector) {
|
danielebarchiesi@0
|
1037 return array(
|
danielebarchiesi@0
|
1038 'command' => 'remove',
|
danielebarchiesi@0
|
1039 'selector' => $selector,
|
danielebarchiesi@0
|
1040 );
|
danielebarchiesi@0
|
1041 }
|
danielebarchiesi@0
|
1042
|
danielebarchiesi@0
|
1043 /**
|
danielebarchiesi@0
|
1044 * Creates a Drupal Ajax 'changed' command.
|
danielebarchiesi@0
|
1045 *
|
danielebarchiesi@0
|
1046 * This command instructs the client to mark each of the elements matched by the
|
danielebarchiesi@0
|
1047 * given selector as 'ajax-changed'.
|
danielebarchiesi@0
|
1048 *
|
danielebarchiesi@0
|
1049 * This command is implemented by Drupal.ajax.prototype.commands.changed()
|
danielebarchiesi@0
|
1050 * defined in misc/ajax.js.
|
danielebarchiesi@0
|
1051 *
|
danielebarchiesi@0
|
1052 * @param $selector
|
danielebarchiesi@0
|
1053 * A jQuery selector string. If the command is a response to a request from
|
danielebarchiesi@0
|
1054 * an #ajax form element then this value can be NULL.
|
danielebarchiesi@0
|
1055 * @param $asterisk
|
danielebarchiesi@0
|
1056 * An optional CSS selector which must be inside $selector. If specified,
|
danielebarchiesi@0
|
1057 * an asterisk will be appended to the HTML inside the $asterisk selector.
|
danielebarchiesi@0
|
1058 *
|
danielebarchiesi@0
|
1059 * @return
|
danielebarchiesi@0
|
1060 * An array suitable for use with the ajax_render() function.
|
danielebarchiesi@0
|
1061 */
|
danielebarchiesi@0
|
1062 function ajax_command_changed($selector, $asterisk = '') {
|
danielebarchiesi@0
|
1063 return array(
|
danielebarchiesi@0
|
1064 'command' => 'changed',
|
danielebarchiesi@0
|
1065 'selector' => $selector,
|
danielebarchiesi@0
|
1066 'asterisk' => $asterisk,
|
danielebarchiesi@0
|
1067 );
|
danielebarchiesi@0
|
1068 }
|
danielebarchiesi@0
|
1069
|
danielebarchiesi@0
|
1070 /**
|
danielebarchiesi@0
|
1071 * Creates a Drupal Ajax 'css' command.
|
danielebarchiesi@0
|
1072 *
|
danielebarchiesi@0
|
1073 * The 'css' command will instruct the client to use the jQuery css() method
|
danielebarchiesi@0
|
1074 * to apply the CSS arguments to elements matched by the given selector.
|
danielebarchiesi@0
|
1075 *
|
danielebarchiesi@0
|
1076 * This command is implemented by Drupal.ajax.prototype.commands.css()
|
danielebarchiesi@0
|
1077 * defined in misc/ajax.js.
|
danielebarchiesi@0
|
1078 *
|
danielebarchiesi@0
|
1079 * @param $selector
|
danielebarchiesi@0
|
1080 * A jQuery selector string. If the command is a response to a request from
|
danielebarchiesi@0
|
1081 * an #ajax form element then this value can be NULL.
|
danielebarchiesi@0
|
1082 * @param $argument
|
danielebarchiesi@0
|
1083 * An array of key/value pairs to set in the CSS for the selector.
|
danielebarchiesi@0
|
1084 *
|
danielebarchiesi@0
|
1085 * @return
|
danielebarchiesi@0
|
1086 * An array suitable for use with the ajax_render() function.
|
danielebarchiesi@0
|
1087 *
|
danielebarchiesi@0
|
1088 * @see http://docs.jquery.com/CSS/css#properties
|
danielebarchiesi@0
|
1089 */
|
danielebarchiesi@0
|
1090 function ajax_command_css($selector, $argument) {
|
danielebarchiesi@0
|
1091 return array(
|
danielebarchiesi@0
|
1092 'command' => 'css',
|
danielebarchiesi@0
|
1093 'selector' => $selector,
|
danielebarchiesi@0
|
1094 'argument' => $argument,
|
danielebarchiesi@0
|
1095 );
|
danielebarchiesi@0
|
1096 }
|
danielebarchiesi@0
|
1097
|
danielebarchiesi@0
|
1098 /**
|
danielebarchiesi@0
|
1099 * Creates a Drupal Ajax 'settings' command.
|
danielebarchiesi@0
|
1100 *
|
danielebarchiesi@0
|
1101 * The 'settings' command instructs the client either to use the given array as
|
danielebarchiesi@0
|
1102 * the settings for ajax-loaded content or to extend Drupal.settings with the
|
danielebarchiesi@0
|
1103 * given array, depending on the value of the $merge parameter.
|
danielebarchiesi@0
|
1104 *
|
danielebarchiesi@0
|
1105 * This command is implemented by Drupal.ajax.prototype.commands.settings()
|
danielebarchiesi@0
|
1106 * defined in misc/ajax.js.
|
danielebarchiesi@0
|
1107 *
|
danielebarchiesi@0
|
1108 * @param $argument
|
danielebarchiesi@0
|
1109 * An array of key/value pairs to add to the settings. This will be utilized
|
danielebarchiesi@0
|
1110 * for all commands after this if they do not include their own settings
|
danielebarchiesi@0
|
1111 * array.
|
danielebarchiesi@0
|
1112 * @param $merge
|
danielebarchiesi@0
|
1113 * Whether or not the passed settings in $argument should be merged into the
|
danielebarchiesi@0
|
1114 * global Drupal.settings on the page. By default (FALSE), the settings that
|
danielebarchiesi@0
|
1115 * are passed to Drupal.attachBehaviors will not include the global
|
danielebarchiesi@0
|
1116 * Drupal.settings.
|
danielebarchiesi@0
|
1117 *
|
danielebarchiesi@0
|
1118 * @return
|
danielebarchiesi@0
|
1119 * An array suitable for use with the ajax_render() function.
|
danielebarchiesi@0
|
1120 */
|
danielebarchiesi@0
|
1121 function ajax_command_settings($argument, $merge = FALSE) {
|
danielebarchiesi@0
|
1122 return array(
|
danielebarchiesi@0
|
1123 'command' => 'settings',
|
danielebarchiesi@0
|
1124 'settings' => $argument,
|
danielebarchiesi@0
|
1125 'merge' => $merge,
|
danielebarchiesi@0
|
1126 );
|
danielebarchiesi@0
|
1127 }
|
danielebarchiesi@0
|
1128
|
danielebarchiesi@0
|
1129 /**
|
danielebarchiesi@0
|
1130 * Creates a Drupal Ajax 'data' command.
|
danielebarchiesi@0
|
1131 *
|
danielebarchiesi@0
|
1132 * The 'data' command instructs the client to attach the name=value pair of
|
danielebarchiesi@0
|
1133 * data to the selector via jQuery's data cache.
|
danielebarchiesi@0
|
1134 *
|
danielebarchiesi@0
|
1135 * This command is implemented by Drupal.ajax.prototype.commands.data()
|
danielebarchiesi@0
|
1136 * defined in misc/ajax.js.
|
danielebarchiesi@0
|
1137 *
|
danielebarchiesi@0
|
1138 * @param $selector
|
danielebarchiesi@0
|
1139 * A jQuery selector string. If the command is a response to a request from
|
danielebarchiesi@0
|
1140 * an #ajax form element then this value can be NULL.
|
danielebarchiesi@0
|
1141 * @param $name
|
danielebarchiesi@0
|
1142 * The name or key (in the key value pair) of the data attached to this
|
danielebarchiesi@0
|
1143 * selector.
|
danielebarchiesi@0
|
1144 * @param $value
|
danielebarchiesi@0
|
1145 * The value of the data. Not just limited to strings can be any format.
|
danielebarchiesi@0
|
1146 *
|
danielebarchiesi@0
|
1147 * @return
|
danielebarchiesi@0
|
1148 * An array suitable for use with the ajax_render() function.
|
danielebarchiesi@0
|
1149 *
|
danielebarchiesi@0
|
1150 * @see http://docs.jquery.com/Core/data#namevalue
|
danielebarchiesi@0
|
1151 */
|
danielebarchiesi@0
|
1152 function ajax_command_data($selector, $name, $value) {
|
danielebarchiesi@0
|
1153 return array(
|
danielebarchiesi@0
|
1154 'command' => 'data',
|
danielebarchiesi@0
|
1155 'selector' => $selector,
|
danielebarchiesi@0
|
1156 'name' => $name,
|
danielebarchiesi@0
|
1157 'value' => $value,
|
danielebarchiesi@0
|
1158 );
|
danielebarchiesi@0
|
1159 }
|
danielebarchiesi@0
|
1160
|
danielebarchiesi@0
|
1161 /**
|
danielebarchiesi@0
|
1162 * Creates a Drupal Ajax 'invoke' command.
|
danielebarchiesi@0
|
1163 *
|
danielebarchiesi@0
|
1164 * The 'invoke' command will instruct the client to invoke the given jQuery
|
danielebarchiesi@0
|
1165 * method with the supplied arguments on the elements matched by the given
|
danielebarchiesi@0
|
1166 * selector. Intended for simple jQuery commands, such as attr(), addClass(),
|
danielebarchiesi@0
|
1167 * removeClass(), toggleClass(), etc.
|
danielebarchiesi@0
|
1168 *
|
danielebarchiesi@0
|
1169 * This command is implemented by Drupal.ajax.prototype.commands.invoke()
|
danielebarchiesi@0
|
1170 * defined in misc/ajax.js.
|
danielebarchiesi@0
|
1171 *
|
danielebarchiesi@0
|
1172 * @param $selector
|
danielebarchiesi@0
|
1173 * A jQuery selector string. If the command is a response to a request from
|
danielebarchiesi@0
|
1174 * an #ajax form element then this value can be NULL.
|
danielebarchiesi@0
|
1175 * @param $method
|
danielebarchiesi@0
|
1176 * The jQuery method to invoke.
|
danielebarchiesi@0
|
1177 * @param $arguments
|
danielebarchiesi@0
|
1178 * (optional) A list of arguments to the jQuery $method, if any.
|
danielebarchiesi@0
|
1179 *
|
danielebarchiesi@0
|
1180 * @return
|
danielebarchiesi@0
|
1181 * An array suitable for use with the ajax_render() function.
|
danielebarchiesi@0
|
1182 */
|
danielebarchiesi@0
|
1183 function ajax_command_invoke($selector, $method, array $arguments = array()) {
|
danielebarchiesi@0
|
1184 return array(
|
danielebarchiesi@0
|
1185 'command' => 'invoke',
|
danielebarchiesi@0
|
1186 'selector' => $selector,
|
danielebarchiesi@0
|
1187 'method' => $method,
|
danielebarchiesi@0
|
1188 'arguments' => $arguments,
|
danielebarchiesi@0
|
1189 );
|
danielebarchiesi@0
|
1190 }
|
danielebarchiesi@0
|
1191
|
danielebarchiesi@0
|
1192 /**
|
danielebarchiesi@0
|
1193 * Creates a Drupal Ajax 'restripe' command.
|
danielebarchiesi@0
|
1194 *
|
danielebarchiesi@0
|
1195 * The 'restripe' command instructs the client to restripe a table. This is
|
danielebarchiesi@0
|
1196 * usually used after a table has been modified by a replace or append command.
|
danielebarchiesi@0
|
1197 *
|
danielebarchiesi@0
|
1198 * This command is implemented by Drupal.ajax.prototype.commands.restripe()
|
danielebarchiesi@0
|
1199 * defined in misc/ajax.js.
|
danielebarchiesi@0
|
1200 *
|
danielebarchiesi@0
|
1201 * @param $selector
|
danielebarchiesi@0
|
1202 * A jQuery selector string.
|
danielebarchiesi@0
|
1203 *
|
danielebarchiesi@0
|
1204 * @return
|
danielebarchiesi@0
|
1205 * An array suitable for use with the ajax_render() function.
|
danielebarchiesi@0
|
1206 */
|
danielebarchiesi@0
|
1207 function ajax_command_restripe($selector) {
|
danielebarchiesi@0
|
1208 return array(
|
danielebarchiesi@0
|
1209 'command' => 'restripe',
|
danielebarchiesi@0
|
1210 'selector' => $selector,
|
danielebarchiesi@0
|
1211 );
|
danielebarchiesi@0
|
1212 }
|