2009-08-17 07:29:32 +00:00
< ? php
/**
* @ file
2011-02-19 00:09:11 +00:00
* Functions for use with Drupal ' s Ajax framework .
2009-08-17 07:29:32 +00:00
*/
/**
2011-02-19 00:09:11 +00:00
* @ defgroup ajax Ajax framework
2009-08-17 07:29:32 +00:00
* @ {
2011-02-19 00:09:11 +00:00
* Functions for Drupal ' s Ajax framework .
2011-01-02 17:26:40 +00:00
*
2011-02-19 00:09:11 +00:00
* Drupal 's Ajax framework is used to dynamically update parts of a page' s HTML
2009-08-17 07:29:32 +00:00
* based on data from the server . Upon a specified event , such as a button
* click , a callback function is triggered which performs server - side logic and
* may return updated markup , which is then replaced on - the - fly with no page
* refresh necessary .
*
* This framework creates a PHP macro language that allows the server to
* instruct JavaScript to perform actions on the client browser . When using
* forms , it can be used with the #ajax property.
2011-02-19 00:09:11 +00:00
* The #ajax property can be used to bind events to the Ajax framework. By
2010-01-27 11:19:11 +00:00
* default , #ajax uses 'system/ajax' as its path for submission and thus calls
2010-04-30 08:07:55 +00:00
* ajax_form_callback () and a defined #ajax['callback'] function.
* However , you may optionally specify a different path to request or a
* different callback function to invoke , which can return updated HTML or can
2011-12-05 12:52:27 +00:00
* also return a richer set of
* @ link ajax_commands Ajax framework commands @ endlink .
2009-08-17 07:29:32 +00:00
*
2010-01-27 11:19:11 +00:00
* Standard form handling is as follows :
2010-09-27 00:53:56 +00:00
* - A form element has a #ajax property that includes #ajax['callback'] and
* omits #ajax['path']. See below about using #ajax['path'] to implement
* advanced use - cases that require something other than standard form
* handling .
2011-02-19 00:09:11 +00:00
* - On the specified element , Ajax processing is triggered by a change to
2010-01-27 11:19:11 +00:00
* that element .
2010-09-27 00:53:56 +00:00
* - The browser submits an HTTP POST request to the 'system/ajax' Drupal
* path .
* - The menu page callback for 'system/ajax' , ajax_form_callback (), calls
* drupal_process_form () to process the form submission and rebuild the
* form if necessary . The form is processed in much the same way as if it
2011-02-19 00:09:11 +00:00
* were submitted without Ajax , with the same #process functions and
2010-09-27 00:53:56 +00:00
* validation and submission handlers called in either case , making it easy
2011-02-19 00:09:11 +00:00
* to create Ajax - enabled forms that degrade gracefully when JavaScript is
2010-09-27 00:53:56 +00:00
* disabled .
* - After form processing is complete , ajax_form_callback () calls the
* function named by #ajax['callback'], which returns the form element that
* has been updated and needs to be returned to the browser , or
2011-02-19 00:09:11 +00:00
* alternatively , an array of custom Ajax commands .
2010-09-27 00:53:56 +00:00
* - The page delivery callback for 'system/ajax' , ajax_deliver (), renders the
* element returned by #ajax['callback'], and returns the JSON string
* created by ajax_render () to the browser .
* - The browser unserializes the returned JSON string into an array of
* command objects and executes each command , resulting in the old page
* content within and including the HTML element specified by
* #ajax['wrapper'] being replaced by the new content returned by
* #ajax['callback'], using a JavaScript animation effect specified by
* #ajax['effect'].
2010-01-27 11:19:11 +00:00
*
2011-02-19 00:09:11 +00:00
* A simple example of basic Ajax use from the
2010-01-27 11:19:11 +00:00
* @ link http :// drupal . org / project / examples Examples module @ endlink follows :
* @ code
* function main_page () {
* return drupal_get_form ( 'ajax_example_simplest' );
* }
*
* function ajax_example_simplest ( $form , & $form_state ) {
* $form = array ();
* $form [ 'changethis' ] = array (
* '#type' => 'select' ,
* '#options' => array (
* 'one' => 'one' ,
* 'two' => 'two' ,
* 'three' => 'three' ,
* ),
* '#ajax' => array (
* 'callback' => 'ajax_example_simplest_callback' ,
* 'wrapper' => 'replace_textfield_div' ,
* ),
* );
* // This entire form element will be replaced with an updated value.
* $form [ 'replace_textfield' ] = array (
* '#type' => 'textfield' ,
* '#title' => t ( " The default value will be changed " ),
* '#description' => t ( " Say something about why you chose " ) . " ' " .
* ( ! empty ( $form_state [ 'values' ][ 'changethis' ])
* ? $form_state [ 'values' ][ 'changethis' ] : t ( " Not changed yet " )) . " ' " ,
* '#prefix' => '<div id="replace_textfield_div">' ,
* '#suffix' => '</div>' ,
* );
* return $form ;
* }
*
* function ajax_example_simplest_callback ( $form , $form_state ) {
* // The form has already been submitted and updated. We can return the replaced
* // item as it is.
* return $form [ 'replace_textfield' ];
* }
* @ endcode
2009-08-17 07:29:32 +00:00
*
2011-02-19 00:09:11 +00:00
* In the above example , the 'changethis' element is Ajax - enabled . The default
2010-01-27 11:19:11 +00:00
* #ajax['event'] is 'change', so when the 'changethis' element changes,
2011-02-19 00:09:11 +00:00
* an Ajax call is made . The form is submitted and reprocessed , and then the
2011-12-05 12:52:27 +00:00
* callback is called . In this case , the form has been automatically
2010-01-27 11:19:11 +00:00
* built changing $form [ 'replace_textfield' ][ '#description' ], so the callback
* just returns that part of the form .
*
2011-02-19 00:09:11 +00:00
* To implement Ajax handling in a form , add '#ajax' to the form
* definition of a field . That field will trigger an Ajax event when it is
2009-08-17 07:29:32 +00:00
* clicked ( or changed , depending on the kind of field ) . #ajax supports
* the following parameters ( either 'path' or 'callback' is required at least ) :
2010-01-27 11:19:11 +00:00
* - #ajax['callback']: The callback to invoke to handle the server side of the
2011-02-19 00:09:11 +00:00
* Ajax event , which will receive a $form and $form_state as arguments , and
2010-01-27 11:19:11 +00:00
* returns a renderable array ( most often a form or form fragment ), an HTML
2011-02-19 00:09:11 +00:00
* string , or an array of Ajax commands . If returning a renderable array or
2010-01-27 11:19:11 +00:00
* a string , the value will replace the original element named in
* #ajax['wrapper'], and
* theme_status_messages ()
* will be prepended to that
* element . ( If the status messages are not wanted , return an array
2011-02-19 00:09:11 +00:00
* of Ajax commands instead . )
* #ajax['wrapper']. If an array of Ajax commands is returned, it will be
2010-01-27 11:19:11 +00:00
* executed by the calling code .
* - #ajax['path']: The menu path to use for the request. This is often omitted
* and the default is used . This path should map
2009-10-02 14:55:40 +00:00
* to a menu page callback that returns data using ajax_render () . Defaults to
2010-01-27 11:19:11 +00:00
* 'system/ajax' , which invokes ajax_form_callback (), eventually calling
* the function named in #ajax['callback']. If you use a custom
2009-10-05 02:16:32 +00:00
* path , you must set up the menu entry and handle the entire callback in your
* own code .
2010-01-27 11:19:11 +00:00
* - #ajax['wrapper']: The CSS ID of the area to be replaced by the content
* returned by the #ajax['callback'] function. The content returned from
2009-10-05 02:16:32 +00:00
* the callback will replace the entire element named by #ajax['wrapper'].
* The wrapper is usually created using #prefix and #suffix properties in the
* form . Note that this is the wrapper ID , not a CSS selector . So to replace
* the element referred to by the CSS selector #some-selector on the page,
* use #ajax['wrapper'] = 'some-selector', not '#some-selector'.
2009-08-17 07:29:32 +00:00
* - #ajax['effect']: The jQuery effect to use when placing the new HTML.
* Defaults to no effect . Valid options are 'none' , 'slide' , or 'fade' .
* - #ajax['speed']: The effect speed to use. Defaults to 'slow'. May be
* 'slow' , 'fast' or a number in milliseconds which represents the length
* of time the effect should run .
* - #ajax['event']: The JavaScript event to respond to. This is normally
* selected automatically for the type of form widget being used , and
* is only needed if you need to override the default behavior .
2011-07-22 06:47:23 +00:00
* - #ajax['prevent']: A JavaScript event to prevent when 'event' is triggered.
* Defaults to 'click' for #ajax on #type 'submit', 'button', and
* 'image_button' . Multiple events may be specified separated by spaces .
* For example , when binding #ajax behaviors to form buttons, pressing the
* ENTER key within a textfield triggers the 'click' event of the form ' s first
* submit button . Triggering Ajax in this situation leads to problems , like
* breaking autocomplete textfields . Because of that , Ajax behaviors are bound
* to the 'mousedown' event on form buttons by default . However , binding to
* 'mousedown' rather than 'click' means that it is possible to trigger a
* click by pressing the mouse , holding the mouse button down until the Ajax
* request is complete and the button is re - enabled , and then releasing the
* mouse button . For this case , 'prevent' can be set to 'click' , so an
* additional event handler is bound to prevent such a click from triggering a
* non - Ajax form submission . This also prevents a textfield ' s ENTER press
* triggering a button ' s non - Ajax form submission behavior .
2009-08-17 07:29:32 +00:00
* - #ajax['method']: The jQuery method to use to place the new HTML.
2010-04-30 08:07:55 +00:00
* Defaults to 'replaceWith' . May be : 'replaceWith' , 'append' , 'prepend' ,
* 'before' , 'after' , or 'html' . See the
* @ link http :// api . jquery . com / category / manipulation / jQuery manipulators documentation @ endlink
* for more information on these methods .
2009-10-05 02:16:32 +00:00
* - #ajax['progress']: Choose either a throbber or progress bar that is
* displayed while awaiting a response from the callback , and add an optional
* message . Possible keys : 'type' , 'message' , 'url' , 'interval' .
* More information is available in the
* @ link http :// api . drupal . org / api / drupal / developer -- topics -- forms_api_reference . html / 7 Form API Reference @ endlink
2009-08-17 07:29:32 +00:00
*
2011-02-19 00:09:11 +00:00
* In addition to using Form API for doing in - form modification , Ajax may be
2009-08-17 07:29:32 +00:00
* enabled by adding classes to buttons and links . By adding the 'use-ajax'
2011-02-19 00:09:11 +00:00
* class to a link , the link will be loaded via an Ajax call . When using this
2009-08-17 07:29:32 +00:00
* method , the href of the link can contain '/nojs/' as part of the path . When
2011-02-19 00:09:11 +00:00
* the Ajax framework makes the request , it will convert this to '/ajax/' .
2009-08-17 07:29:32 +00:00
* The server is then able to easily tell if this request was made through an
2011-02-19 00:09:11 +00:00
* actual Ajax request or in a degraded state , and respond appropriately .
2009-08-17 07:29:32 +00:00
*
* Similarly , submit buttons can be given the class ' use - ajax - submit ' . The
2011-02-19 00:09:11 +00:00
* form will then be submitted via Ajax to the path specified in the #action.
2009-08-17 07:29:32 +00:00
* Like the ajax - submit class above , this path will have '/nojs/' replaced with
* '/ajax/' so that the submit handler can tell if the form was submitted
* in a degraded state or not .
*
2011-02-19 00:09:11 +00:00
* When responding to Ajax requests , the server should do what it needs to do
2009-08-17 07:29:32 +00:00
* for that request , then create a commands array . This commands array will
* be converted to a JSON object and returned to the client , which will then
* iterate over the array and process it like a macro language .
*
2011-12-05 12:52:27 +00:00
* Each command item is an associative array which will be converted to a
* command object on the JavaScript side . $command_item [ 'command' ] is the type
* of command , e . g . 'alert' or 'replace' , and will correspond to a method in the
* Drupal . ajax [ command ] space . The command array may contain any other data that
* the command needs to process , e . g . 'method' , 'selector' , 'settings' , etc .
2009-08-17 07:29:32 +00:00
*
* Commands are usually created with a couple of helper functions , so they
* look like this :
* @ code
* $commands = array ();
* // Replace the content of '#object-1' on the page with 'some html here'.
* $commands [] = ajax_command_replace ( '#object-1' , 'some html here' );
* // Add a visual "changed" marker to the '#object-1' element.
* $commands [] = ajax_command_changed ( '#object-1' );
2010-03-13 06:55:50 +00:00
* // Menu 'page callback' and #ajax['callback'] functions are supposed to
2011-02-19 00:09:11 +00:00
* // return render arrays. If returning an Ajax commands array, it must be
2010-04-28 20:25:22 +00:00
* // encapsulated in a render array structure.
2010-03-13 06:55:50 +00:00
* return array ( '#type' => 'ajax' , '#commands' => $commands );
2009-08-17 07:29:32 +00:00
* @ endcode
2009-10-02 14:55:40 +00:00
*
2011-02-19 00:09:11 +00:00
* When returning an Ajax command array , it is often useful to have
2010-01-27 11:19:11 +00:00
* status messages rendered along with other tasks in the command array .
2011-02-19 00:09:11 +00:00
* In that case the the Ajax commands array may be constructed like this :
2009-10-02 14:55:40 +00:00
* @ code
* $commands = array ();
* $commands [] = ajax_command_replace ( NULL , $output );
* $commands [] = ajax_command_prepend ( NULL , theme ( 'status_messages' ));
2010-03-13 06:55:50 +00:00
* return array ( '#type' => 'ajax' , '#commands' => $commands );
2009-10-02 14:55:40 +00:00
* @ endcode
*
2011-02-19 00:09:11 +00:00
* See @ link ajax_commands Ajax framework commands @ endlink
2009-08-17 07:29:32 +00:00
*/
/**
2011-12-05 12:52:27 +00:00
* Renders a commands array into JSON .
2009-08-17 07:29:32 +00:00
*
* @ param $commands
* A list of macro commands generated by the use of ajax_command_ * ()
* functions .
*/
2010-03-13 06:55:50 +00:00
function ajax_render ( $commands = array ()) {
2011-02-19 00:09:11 +00:00
// Ajax responses aren't rendered with html.tpl.php, so we have to call
2010-10-04 17:46:01 +00:00
// drupal_get_css() and drupal_get_js() here, in order to have new files added
// during this request to be loaded by the page. We only want to send back
// files that the page hasn't already loaded, so we implement simple diffing
// logic using array_diff_key().
foreach ( array ( 'css' , 'js' ) as $type ) {
// It is highly suspicious if $_POST['ajax_page_state'][$type] is empty,
// since the base page ought to have at least one JS file and one CSS file
// loaded. It probably indicates an error, and rather than making the page
// reload all of the files, instead we return no new files.
if ( empty ( $_POST [ 'ajax_page_state' ][ $type ])) {
$items [ $type ] = array ();
}
else {
$function = 'drupal_add_' . $type ;
$items [ $type ] = $function ();
drupal_alter ( $type , $items [ $type ]);
// @todo Inline CSS and JS items are indexed numerically. These can't be
// reliably diffed with array_diff_key(), since the number can change
// due to factors unrelated to the inline content, so for now, we strip
2011-02-19 00:09:11 +00:00
// the inline items from Ajax responses, and can add support for them
2010-10-04 17:46:01 +00:00
// when drupal_add_css() and drupal_add_js() are changed to using md5()
// or some other hash of the inline content.
foreach ( $items [ $type ] as $key => $item ) {
if ( is_numeric ( $key )) {
unset ( $items [ $type ][ $key ]);
}
}
// Ensure that the page doesn't reload what it already has.
$items [ $type ] = array_diff_key ( $items [ $type ], $_POST [ 'ajax_page_state' ][ $type ]);
}
}
2011-09-27 18:15:03 +00:00
// Render the HTML to load these files, and add AJAX commands to insert this
// HTML in the page. We pass TRUE as the $skip_alter argument to prevent the
// data from being altered again, as we already altered it above. Settings are
// handled separately, afterwards.
2010-10-06 23:03:39 +00:00
if ( isset ( $items [ 'js' ][ 'settings' ])) {
unset ( $items [ 'js' ][ 'settings' ]);
}
2010-10-04 17:46:01 +00:00
$styles = drupal_get_css ( $items [ 'css' ], TRUE );
$scripts_footer = drupal_get_js ( 'footer' , $items [ 'js' ], TRUE );
$scripts_header = drupal_get_js ( 'header' , $items [ 'js' ], TRUE );
$extra_commands = array ();
if ( ! empty ( $styles )) {
$extra_commands [] = ajax_command_prepend ( 'head' , $styles );
}
if ( ! empty ( $scripts_header )) {
$extra_commands [] = ajax_command_prepend ( 'head' , $scripts_header );
}
if ( ! empty ( $scripts_footer )) {
$extra_commands [] = ajax_command_append ( 'body' , $scripts_footer );
}
if ( ! empty ( $extra_commands )) {
$commands = array_merge ( $extra_commands , $commands );
}
2011-09-27 18:15:03 +00:00
// Now add a command to merge changes and additions to Drupal.settings.
2010-10-04 17:46:01 +00:00
$scripts = drupal_add_js ();
2009-08-17 07:29:32 +00:00
if ( ! empty ( $scripts [ 'settings' ])) {
2010-10-04 17:46:01 +00:00
$settings = $scripts [ 'settings' ];
array_unshift ( $commands , ajax_command_settings ( call_user_func_array ( 'array_merge_recursive' , $settings [ 'data' ]), TRUE ));
2009-08-17 07:29:32 +00:00
}
2011-02-19 00:09:11 +00:00
// Allow modules to alter any Ajax response.
2009-08-17 07:29:32 +00:00
drupal_alter ( 'ajax_render' , $commands );
2010-03-13 06:55:50 +00:00
return drupal_json_encode ( $commands );
2009-08-17 07:29:32 +00:00
}
/**
2011-12-05 12:52:27 +00:00
* Gets a form submitted via #ajax during an Ajax callback.
2009-08-17 07:29:32 +00:00
*
2011-02-19 00:09:11 +00:00
* This will load a form from the form cache used during Ajax operations . It
2009-08-17 07:29:32 +00:00
* pulls the form info from $_POST .
*
* @ return
* An array containing the $form and $form_state . Use the list () function
* to break these apart :
* @ code
* list ( $form , $form_state , $form_id , $form_build_id ) = ajax_get_form ();
* @ endcode
*/
function ajax_get_form () {
$form_state = form_state_defaults ();
$form_build_id = $_POST [ 'form_build_id' ];
// Get the form from the cache.
$form = form_get_cache ( $form_build_id , $form_state );
if ( ! $form ) {
// If $form cannot be loaded from the cache, the form_build_id in $_POST
// must be invalid, which means that someone performed a POST request onto
// system/ajax without actually viewing the concerned form in the browser.
// This is likely a hacking attempt as it never happens under normal
// circumstances, so we just do nothing.
2011-07-04 16:58:33 +00:00
watchdog ( 'ajax' , 'Invalid form POST data.' , array (), WATCHDOG_WARNING );
2009-10-13 21:16:44 +00:00
drupal_exit ();
2009-08-17 07:29:32 +00:00
}
// Since some of the submit handlers are run, redirects need to be disabled.
2009-09-21 06:44:14 +00:00
$form_state [ 'no_redirect' ] = TRUE ;
2009-08-17 07:29:32 +00:00
2011-02-19 00:09:11 +00:00
// When a form is rebuilt after Ajax processing, its #build_id and #action
2010-09-13 01:09:26 +00:00
// should not change.
// @see drupal_rebuild_form()
$form_state [ 'rebuild_info' ][ 'copy' ][ '#build_id' ] = TRUE ;
$form_state [ 'rebuild_info' ][ 'copy' ][ '#action' ] = TRUE ;
2009-08-17 07:29:32 +00:00
// The form needs to be processed; prepare for that by setting a few internal
// variables.
$form_state [ 'input' ] = $_POST ;
$form_id = $form [ '#form_id' ];
return array ( $form , $form_state , $form_id , $form_build_id );
}
/**
2011-12-05 12:52:27 +00:00
* Page callback : Handles Ajax requests for the #ajax Form API property.
*
2009-10-02 14:55:40 +00:00
* This rebuilds the form from cache and invokes the defined #ajax['callback']
2011-02-19 00:09:11 +00:00
* to return an Ajax command structure for JavaScript . In case no 'callback' has
2009-10-02 14:55:40 +00:00
* been defined , nothing will happen .
*
* The Form API #ajax property can be set both for buttons and other input
* elements .
*
* This function is also the canonical example of how to implement
* #ajax['path']. If processing is required that cannot be accomplished with
* a callback , re - implement this function and set #ajax['path'] to the
* enhanced function .
2011-12-05 12:52:27 +00:00
*
* @ see system_menu ()
2009-08-17 07:29:32 +00:00
*/
function ajax_form_callback () {
2010-09-13 01:09:26 +00:00
list ( $form , $form_state ) = ajax_get_form ();
drupal_process_form ( $form [ '#form_id' ], $form , $form_state );
2009-08-17 07:29:32 +00:00
2010-09-13 01:09:26 +00:00
// We need to return the part of the form (or some other content) that needs
// to be re-rendered so the browser can update the page with changed content.
2011-02-19 00:09:11 +00:00
// Since this is the generic menu callback used by many Ajax elements, it is
2010-09-13 01:09:26 +00:00
// up to the #ajax['callback'] function of the element (may or may not be a
2011-02-19 00:09:11 +00:00
// button) that triggered the Ajax request to determine what needs to be
2010-09-13 01:09:26 +00:00
// rendered.
2010-03-26 18:58:12 +00:00
if ( ! empty ( $form_state [ 'triggering_element' ])) {
$callback = $form_state [ 'triggering_element' ][ '#ajax' ][ 'callback' ];
2009-10-02 14:55:40 +00:00
}
if ( ! empty ( $callback ) && function_exists ( $callback )) {
2009-10-15 14:07:30 +00:00
return $callback ( $form , $form_state );
}
}
2010-10-04 17:46:01 +00:00
/**
2011-12-05 12:52:27 +00:00
* Theme callback : Returns the correct theme for an Ajax request .
*
2011-02-19 00:09:11 +00:00
* Many different pages can invoke an Ajax request to system / ajax or another
* generic Ajax path . It is almost always desired for an Ajax response to be
2010-10-04 17:46:01 +00:00
* rendered using the same theme as the base page , because most themes are built
* with the assumption that they control the entire page , so if the CSS for two
* themes are both loaded for a given page , they may conflict with each other .
* For example , Bartik is Drupal 's default theme, and Seven is Drupal' s default
* administration theme . Depending on whether the " Use the administration theme
* when editing or creating content " checkbox is checked, the node edit form may
2011-02-19 00:09:11 +00:00
* be displayed in either theme , but the Ajax response to the Field module ' s
2010-10-04 17:46:01 +00:00
* " Add another item " button should be rendered using the same theme as the rest
* of the page . Therefore , system_menu () sets the 'theme callback' for
* 'system/ajax' to this function , and it is recommended that modules
2011-02-19 00:09:11 +00:00
* implementing other generic Ajax paths do the same .
2011-12-05 12:52:27 +00:00
*
* @ see system_menu ()
* @ see file_menu ()
2010-10-04 17:46:01 +00:00
*/
function ajax_base_page_theme () {
if ( ! empty ( $_POST [ 'ajax_page_state' ][ 'theme' ]) && ! empty ( $_POST [ 'ajax_page_state' ][ 'theme_token' ])) {
$theme = $_POST [ 'ajax_page_state' ][ 'theme' ];
$token = $_POST [ 'ajax_page_state' ][ 'theme_token' ];
// Prevent a request forgery from giving a person access to a theme they
// shouldn't be otherwise allowed to see. However, since everyone is allowed
// to see the default theme, token validation isn't required for that, and
// bypassing it allows most use-cases to work even when accessed from the
// page cache.
2011-12-13 03:29:45 +00:00
if ( $theme === variable_get ( 'theme_default' , 'stark' ) || drupal_valid_token ( $token , $theme )) {
2010-10-04 17:46:01 +00:00
return $theme ;
}
}
}
2009-10-15 14:07:30 +00:00
/**
2011-12-05 12:52:27 +00:00
* Packages and sends the result of a page callback as an Ajax response .
2009-10-15 14:07:30 +00:00
*
2011-02-19 00:09:11 +00:00
* This function is the equivalent of drupal_deliver_html_page (), but for Ajax
2010-12-23 04:26:31 +00:00
* requests . Like that function , it :
* - Adds needed HTTP headers .
* - Prints rendered output .
* - Performs end - of - request tasks .
*
2009-10-15 14:07:30 +00:00
* @ param $page_callback_result
* The result of a page callback . Can be one of :
* - NULL : to indicate no content .
* - An integer menu status constant : to indicate an error condition .
* - A string of HTML content .
* - A renderable array of content .
2010-12-23 04:26:31 +00:00
*
* @ see drupal_deliver_html_page ()
2009-10-15 14:07:30 +00:00
*/
function ajax_deliver ( $page_callback_result ) {
2011-01-27 23:55:38 +00:00
// Browsers do not allow JavaScript to read the contents of a user's local
// files. To work around that, the jQuery Form plugin submits forms containing
// a file input element to an IFRAME, instead of using XHR. Browsers do not
// normally expect JSON strings as content within an IFRAME, so the response
// must be customized accordingly.
// @see http://malsup.com/jquery/form/#file-upload
// @see Drupal.ajax.prototype.beforeSend()
$iframe_upload = ! empty ( $_POST [ 'ajax_iframe_upload' ]);
2010-12-23 04:26:31 +00:00
// Emit a Content-Type HTTP header if none has been added by the page callback
// or by a wrapping delivery callback.
if ( is_null ( drupal_get_http_header ( 'Content-Type' ))) {
2011-01-27 23:55:38 +00:00
if ( ! $iframe_upload ) {
// Standard JSON can be returned to a browser's XHR object, and to
// non-browser user agents.
// @see http://www.ietf.org/rfc/rfc4627.txt?number=4627
drupal_add_http_header ( 'Content-Type' , 'application/json; charset=utf-8' );
2010-12-23 04:26:31 +00:00
}
else {
2011-01-27 23:55:38 +00:00
// Browser IFRAMEs expect HTML. With most other content types, Internet
// Explorer presents the user with a download prompt.
drupal_add_http_header ( 'Content-Type' , 'text/html; charset=utf-8' );
2010-12-23 04:26:31 +00:00
}
}
2010-03-13 06:55:50 +00:00
2011-01-27 23:55:38 +00:00
// Print the response.
$commands = ajax_prepare_response ( $page_callback_result );
$json = ajax_render ( $commands );
if ( ! $iframe_upload ) {
// Standard JSON can be returned to a browser's XHR object, and to
// non-browser user agents.
print $json ;
}
else {
// Browser IFRAMEs expect HTML. Browser extensions, such as Linkification
// and Skype's Browser Highlighter, convert URLs, phone numbers, etc. into
// links. This corrupts the JSON response. Protect the integrity of the
// JSON data by making it the value of a textarea.
// @see http://malsup.com/jquery/form/#file-upload
// @see http://drupal.org/node/1009382
print '<textarea>' . $json . '</textarea>' ;
}
// Perform end-of-request tasks.
ajax_footer ();
}
/**
2011-02-19 00:09:11 +00:00
* Converts the return value of a page callback into an Ajax commands array .
2011-01-27 23:55:38 +00:00
*
* @ param $page_callback_result
* The result of a page callback . Can be one of :
* - NULL : to indicate no content .
* - An integer menu status constant : to indicate an error condition .
* - A string of HTML content .
* - A renderable array of content .
*
* @ return
2011-02-19 00:09:11 +00:00
* An Ajax commands array that can be passed to ajax_render () .
2011-01-27 23:55:38 +00:00
*/
function ajax_prepare_response ( $page_callback_result ) {
2010-12-23 04:26:31 +00:00
$commands = array ();
2009-10-15 14:07:30 +00:00
if ( ! isset ( $page_callback_result )) {
// Simply delivering an empty commands array is sufficient. This results
2011-02-19 00:09:11 +00:00
// in the Ajax request being completed, but nothing being done to the page.
2009-10-15 14:07:30 +00:00
}
elseif ( is_int ( $page_callback_result )) {
switch ( $page_callback_result ) {
case MENU_NOT_FOUND :
$commands [] = ajax_command_alert ( t ( 'The requested page could not be found.' ));
break ;
2009-08-17 07:29:32 +00:00
2009-10-15 14:07:30 +00:00
case MENU_ACCESS_DENIED :
$commands [] = ajax_command_alert ( t ( 'You are not authorized to access this page.' ));
break ;
case MENU_SITE_OFFLINE :
$commands [] = ajax_command_alert ( filter_xss_admin ( variable_get ( 'maintenance_mode_message' ,
t ( '@site is currently under maintenance. We should be back shortly. Thank you for your patience.' , array ( '@site' => variable_get ( 'site_name' , 'Drupal' ))))));
break ;
2009-08-17 07:29:32 +00:00
}
2009-10-15 14:07:30 +00:00
}
2010-03-13 06:55:50 +00:00
elseif ( is_array ( $page_callback_result ) && isset ( $page_callback_result [ '#type' ]) && ( $page_callback_result [ '#type' ] == 'ajax' )) {
2011-02-19 00:09:11 +00:00
// Complex Ajax callbacks can return a result that contains an error message
2010-03-13 06:55:50 +00:00
// or a specific set of commands to send to the browser.
$page_callback_result += element_info ( 'ajax' );
$error = $page_callback_result [ '#error' ];
if ( isset ( $error ) && $error !== FALSE ) {
if (( empty ( $error ) || $error === TRUE )) {
$error = t ( 'An error occurred while handling the request: The server received invalid input.' );
}
$commands [] = ajax_command_alert ( $error );
}
else {
$commands = $page_callback_result [ '#commands' ];
2009-08-17 07:29:32 +00:00
}
}
2009-10-15 14:07:30 +00:00
else {
2011-02-19 00:09:11 +00:00
// Like normal page callbacks, simple Ajax callbacks can return HTML
2010-04-30 08:07:55 +00:00
// content, as a string or render array. This HTML is inserted in some
// relationship to #ajax['wrapper'], as determined by which jQuery DOM
// manipulation method is used. The method used is specified by
// #ajax['method']. The default method is 'replaceWith', which completely
// replaces the old wrapper element and its content with the new HTML.
2009-10-15 14:07:30 +00:00
$html = is_string ( $page_callback_result ) ? $page_callback_result : drupal_render ( $page_callback_result );
2010-04-30 08:07:55 +00:00
$commands [] = ajax_command_insert ( NULL , $html );
// Add the status messages inside the new content's wrapper element, so that
2011-02-19 00:09:11 +00:00
// on subsequent Ajax requests, it is treated as old content.
2009-10-15 14:07:30 +00:00
$commands [] = ajax_command_prepend ( NULL , theme ( 'status_messages' ));
}
2010-03-13 06:55:50 +00:00
2011-01-27 23:55:38 +00:00
return $commands ;
2010-03-13 06:55:50 +00:00
}
/**
2011-12-05 12:52:27 +00:00
* Performs end - of - Ajax - request tasks .
2010-03-13 06:55:50 +00:00
*
2011-02-19 00:09:11 +00:00
* This function is the equivalent of drupal_page_footer (), but for Ajax
2010-03-13 06:55:50 +00:00
* requests .
*
* @ see drupal_page_footer ()
*/
function ajax_footer () {
2011-02-19 00:09:11 +00:00
// Even for Ajax requests, invoke hook_exit() implementations. There may be
// modules that need very fast Ajax responses, and therefore, run Ajax
2010-03-13 06:55:50 +00:00
// requests with an early bootstrap.
if ( drupal_get_bootstrap_phase () == DRUPAL_BOOTSTRAP_FULL && ( ! defined ( 'MAINTENANCE_MODE' ) || MAINTENANCE_MODE != 'update' )) {
module_invoke_all ( 'exit' );
}
// Commit the user session. See above comment about the possibility of this
// function running without session.inc loaded.
if ( function_exists ( 'drupal_session_commit' )) {
drupal_session_commit ();
}
2009-08-17 07:29:32 +00:00
}
/**
2011-12-05 12:52:27 +00:00
* Form element processing handler for the #ajax form property.
2010-10-21 19:31:39 +00:00
*
* @ param $element
* An associative array containing the properties of the element .
*
* @ return
* The processed element .
*
* @ see ajax_pre_render_element ()
*/
function ajax_process_form ( $element , & $form_state ) {
$element = ajax_pre_render_element ( $element );
if ( ! empty ( $element [ '#ajax_processed' ])) {
$form_state [ 'cache' ] = TRUE ;
}
return $element ;
}
/**
2011-12-05 12:52:27 +00:00
* Adds Ajax information about an element to communicate with JavaScript .
2009-08-17 07:29:32 +00:00
*
* If #ajax['path'] is set on an element, this additional JavaScript is added
2011-02-19 00:09:11 +00:00
* to the page header to attach the Ajax behaviors . See ajax . js for more
2009-08-17 07:29:32 +00:00
* information .
*
* @ param $element
* An associative array containing the properties of the element .
* Properties used :
* - #ajax['event']
2011-07-22 06:47:23 +00:00
* - #ajax['prevent']
2009-08-17 07:29:32 +00:00
* - #ajax['path']
2010-10-21 19:31:39 +00:00
* - #ajax['options']
2009-08-17 07:29:32 +00:00
* - #ajax['wrapper']
* - #ajax['parameters']
* - #ajax['effect']
*
* @ return
2010-10-21 19:31:39 +00:00
* The processed element with the necessary JavaScript attached to it .
2009-08-17 07:29:32 +00:00
*/
2010-10-21 19:31:39 +00:00
function ajax_pre_render_element ( $element ) {
// Skip already processed elements.
if ( isset ( $element [ '#ajax_processed' ])) {
return $element ;
}
// Initialize #ajax_processed, so we do not process this element again.
$element [ '#ajax_processed' ] = FALSE ;
2010-01-08 07:27:32 +00:00
// Nothing to do if there is neither a callback nor a path.
if ( ! ( isset ( $element [ '#ajax' ][ 'callback' ]) || isset ( $element [ '#ajax' ][ 'path' ]))) {
return $element ;
}
2009-08-17 07:29:32 +00:00
// Add a reasonable default event handler if none was specified.
if ( isset ( $element [ '#ajax' ]) && ! isset ( $element [ '#ajax' ][ 'event' ])) {
switch ( $element [ '#type' ]) {
case 'submit' :
case 'button' :
case 'image_button' :
2011-06-30 05:40:14 +00:00
// Pressing the ENTER key within a textfield triggers the click event of
// the form's first submit button. Triggering Ajax in this situation
// leads to problems, like breaking autocomplete textfields, so we bind
// to mousedown instead of click.
// @see http://drupal.org/node/216059
2009-08-17 07:29:32 +00:00
$element [ '#ajax' ][ 'event' ] = 'mousedown' ;
2011-06-30 05:40:14 +00:00
// Retain keyboard accessibility by setting 'keypress'. This causes
// ajax.js to trigger 'event' when SPACE or ENTER are pressed while the
// button has focus.
2009-08-17 07:29:32 +00:00
$element [ '#ajax' ][ 'keypress' ] = TRUE ;
2011-06-30 05:40:14 +00:00
// Binding to mousedown rather than click means that it is possible to
// trigger a click by pressing the mouse, holding the mouse button down
// until the Ajax request is complete and the button is re-enabled, and
// then releasing the mouse button. Set 'prevent' so that ajax.js binds
// an additional handler to prevent such a click from triggering a
// non-Ajax form submission. This also prevents a textfield's ENTER
// press triggering this button's non-Ajax form submission behavior.
2011-07-22 06:47:23 +00:00
if ( ! isset ( $element [ '#ajax' ][ 'prevent' ])) {
$element [ '#ajax' ][ 'prevent' ] = 'click' ;
}
2009-08-17 07:29:32 +00:00
break ;
case 'password' :
case 'textfield' :
case 'textarea' :
$element [ '#ajax' ][ 'event' ] = 'blur' ;
break ;
case 'radio' :
case 'checkbox' :
case 'select' :
$element [ '#ajax' ][ 'event' ] = 'change' ;
break ;
2010-10-21 19:31:39 +00:00
case 'link' :
$element [ '#ajax' ][ 'event' ] = 'click' ;
break ;
2009-08-17 07:29:32 +00:00
default :
return $element ;
}
}
2010-03-26 10:52:38 +00:00
// Attach JavaScript settings to the element.
if ( isset ( $element [ '#ajax' ][ 'event' ])) {
2010-11-30 17:16:37 +00:00
$element [ '#attached' ][ 'library' ][] = array ( 'system' , 'jquery.form' );
$element [ '#attached' ][ 'library' ][] = array ( 'system' , 'drupal.ajax' );
2010-01-08 07:27:32 +00:00
$settings = $element [ '#ajax' ];
// Assign default settings.
$settings += array (
2010-10-21 19:31:39 +00:00
'path' => 'system/ajax' ,
'options' => array (),
2009-08-17 07:29:32 +00:00
);
2010-04-30 08:07:55 +00:00
// @todo Legacy support. Remove in Drupal 8.
2010-12-17 01:03:58 +00:00
if ( isset ( $settings [ 'method' ]) && $settings [ 'method' ] == 'replace' ) {
2010-04-30 08:07:55 +00:00
$settings [ 'method' ] = 'replaceWith' ;
}
2010-10-21 19:31:39 +00:00
// Change path to URL.
$settings [ 'url' ] = url ( $settings [ 'path' ], $settings [ 'options' ]);
unset ( $settings [ 'path' ], $settings [ 'options' ]);
2010-03-26 18:58:12 +00:00
// Add special data to $settings['submit'] so that when this element
2011-02-19 00:09:11 +00:00
// triggers an Ajax submission, Drupal's form processing can determine which
2010-03-26 18:58:12 +00:00
// element triggered it.
// @see _form_element_triggered_scripted_submission()
if ( isset ( $settings [ 'trigger_as' ])) {
// An element can add a 'trigger_as' key within #ajax to make the element
// submit as though another one (for example, a non-button can use this
// to submit the form as though a button were clicked). When using this,
// the 'name' key is always required to identify the element to trigger
// as. The 'value' key is optional, and only needed when multiple elements
// share the same name, which is commonly the case for buttons.
$settings [ 'submit' ][ '_triggering_element_name' ] = $settings [ 'trigger_as' ][ 'name' ];
if ( isset ( $settings [ 'trigger_as' ][ 'value' ])) {
$settings [ 'submit' ][ '_triggering_element_value' ] = $settings [ 'trigger_as' ][ 'value' ];
}
unset ( $settings [ 'trigger_as' ]);
}
2010-10-21 19:31:39 +00:00
elseif ( isset ( $element [ '#name' ])) {
2010-03-26 18:58:12 +00:00
// Most of the time, elements can submit as themselves, in which case the
// 'trigger_as' key isn't needed, and the element's name is used.
$settings [ 'submit' ][ '_triggering_element_name' ] = $element [ '#name' ];
// If the element is a (non-image) button, its name may not identify it
// uniquely, in which case a match on value is also needed.
// @see _form_button_was_clicked()
if ( isset ( $element [ '#button_type' ]) && empty ( $element [ '#has_garbage_value' ])) {
$settings [ 'submit' ][ '_triggering_element_value' ] = $element [ '#value' ];
}
}
2010-01-08 07:27:32 +00:00
// Convert a simple #ajax['progress'] string into an array.
2010-12-17 01:03:58 +00:00
if ( isset ( $settings [ 'progress' ]) && is_string ( $settings [ 'progress' ])) {
2010-01-08 07:27:32 +00:00
$settings [ 'progress' ] = array ( 'type' => $settings [ 'progress' ]);
2009-08-17 07:29:32 +00:00
}
// Change progress path to a full URL.
2010-01-08 07:27:32 +00:00
if ( isset ( $settings [ 'progress' ][ 'path' ])) {
$settings [ 'progress' ][ 'url' ] = url ( $settings [ 'progress' ][ 'path' ]);
unset ( $settings [ 'progress' ][ 'path' ]);
2009-08-17 07:29:32 +00:00
}
2010-03-26 10:52:38 +00:00
$element [ '#attached' ][ 'js' ][] = array (
'type' => 'setting' ,
'data' => array ( 'ajax' => array ( $element [ '#id' ] => $settings )),
);
2009-08-17 07:29:32 +00:00
2011-02-19 00:09:11 +00:00
// Indicate that Ajax processing was successful.
2010-10-21 19:31:39 +00:00
$element [ '#ajax_processed' ] = TRUE ;
2009-08-17 07:29:32 +00:00
}
return $element ;
}
/**
* @ } End of " defgroup ajax " .
*/
/**
2011-02-19 00:09:11 +00:00
* @ defgroup ajax_commands Ajax framework commands
2009-08-17 07:29:32 +00:00
* @ {
2011-02-19 00:09:11 +00:00
* Functions to create various Ajax commands .
2011-01-02 17:26:40 +00:00
*
* These functions can be used to create arrays for use with the
* ajax_render () function .
2009-08-17 07:29:32 +00:00
*/
/**
2011-02-19 00:09:11 +00:00
* Creates a Drupal Ajax 'alert' command .
2009-08-17 07:29:32 +00:00
*
* The 'alert' command instructs the client to display a JavaScript alert
* dialog box .
*
* This command is implemented by Drupal . ajax . prototype . commands . alert ()
* defined in misc / ajax . js .
*
* @ param $text
2010-01-25 10:38:35 +00:00
* The message string to display to the user .
2009-08-17 07:29:32 +00:00
*
* @ return
* An array suitable for use with the ajax_render () function .
*/
function ajax_command_alert ( $text ) {
return array (
'command' => 'alert' ,
'text' => $text ,
);
}
2010-04-30 08:07:55 +00:00
/**
2011-02-19 00:09:11 +00:00
* Creates a Drupal Ajax 'insert' command using the method in #ajax['method'].
2010-04-30 08:07:55 +00:00
*
* This command instructs the client to insert the given HTML using whichever
* jQuery DOM manipulation method has been specified in the #ajax['method']
* variable of the element that triggered the request .
*
* This command is implemented by Drupal . ajax . prototype . commands . insert ()
* defined in misc / ajax . js .
*
* @ param $selector
* A jQuery selector string . If the command is a response to a request from
* an #ajax form element then this value can be NULL.
* @ param $html
* The data to use with the jQuery method .
* @ param $settings
* An optional array of settings that will be used for this command only .
*
* @ return
* An array suitable for use with the ajax_render () function .
*/
function ajax_command_insert ( $selector , $html , $settings = NULL ) {
return array (
'command' => 'insert' ,
'method' => NULL ,
'selector' => $selector ,
'data' => $html ,
'settings' => $settings ,
);
}
2009-08-17 07:29:32 +00:00
/**
2011-02-19 00:09:11 +00:00
* Creates a Drupal Ajax 'insert/replaceWith' command .
2009-08-17 07:29:32 +00:00
*
2009-08-21 00:35:31 +00:00
* The 'insert/replaceWith' command instructs the client to use jQuery ' s
2009-08-17 07:29:32 +00:00
* replaceWith () method to replace each element matched matched by the given
* selector with the given HTML .
*
* This command is implemented by Drupal . ajax . prototype . commands . insert ()
* defined in misc / ajax . js .
*
* @ param $selector
* A jQuery selector string . If the command is a response to a request from
* an #ajax form element then this value can be NULL.
* @ param $html
* The data to use with the jQuery replaceWith () method .
* @ param $settings
* An optional array of settings that will be used for this command only .
*
* @ return
* An array suitable for use with the ajax_render () function .
*
2010-04-30 08:07:55 +00:00
* See @ link http :// docs . jquery . com / Manipulation / replaceWith #content jQuery replaceWith command @endlink
2009-08-17 07:29:32 +00:00
*/
function ajax_command_replace ( $selector , $html , $settings = NULL ) {
return array (
'command' => 'insert' ,
'method' => 'replaceWith' ,
'selector' => $selector ,
'data' => $html ,
'settings' => $settings ,
);
}
/**
2011-02-19 00:09:11 +00:00
* Creates a Drupal Ajax 'insert/html' command .
2009-08-17 07:29:32 +00:00
*
* The 'insert/html' command instructs the client to use jQuery ' s html ()
* method to set the HTML content of each element matched by the given
* selector while leaving the outer tags intact .
*
* This command is implemented by Drupal . ajax . prototype . commands . insert ()
* defined in misc / ajax . js .
*
* @ param $selector
* A jQuery selector string . If the command is a response to a request from
* an #ajax form element then this value can be NULL.
* @ param $html
* The data to use with the jQuery html () method .
* @ param $settings
* An optional array of settings that will be used for this command only .
*
* @ return
* An array suitable for use with the ajax_render () function .
*
* @ see http :// docs . jquery . com / Attributes / html #val
*/
function ajax_command_html ( $selector , $html , $settings = NULL ) {
return array (
'command' => 'insert' ,
'method' => 'html' ,
'selector' => $selector ,
'data' => $html ,
'settings' => $settings ,
);
}
/**
2011-02-19 00:09:11 +00:00
* Creates a Drupal Ajax 'insert/prepend' command .
2009-08-17 07:29:32 +00:00
*
* The 'insert/prepend' command instructs the client to use jQuery ' s prepend ()
* method to prepend the given HTML content to the inside each element matched
* by the given selector .
*
* This command is implemented by Drupal . ajax . prototype . commands . insert ()
* defined in misc / ajax . js .
*
* @ param $selector
* A jQuery selector string . If the command is a response to a request from
* an #ajax form element then this value can be NULL.
* @ param $html
* The data to use with the jQuery prepend () method .
* @ param $settings
* An optional array of settings that will be used for this command only .
*
* @ return
* An array suitable for use with the ajax_render () function .
*
* @ see http :// docs . jquery . com / Manipulation / prepend #content
*/
function ajax_command_prepend ( $selector , $html , $settings = NULL ) {
return array (
'command' => 'insert' ,
'method' => 'prepend' ,
'selector' => $selector ,
'data' => $html ,
'settings' => $settings ,
);
}
/**
2011-02-19 00:09:11 +00:00
* Creates a Drupal Ajax 'insert/append' command .
2009-08-17 07:29:32 +00:00
*
* The 'insert/append' command instructs the client to use jQuery ' s append ()
2011-01-24 12:56:06 +00:00
* method to append the given HTML content to the inside of each element matched
2009-08-17 07:29:32 +00:00
* by the given selector .
*
* This command is implemented by Drupal . ajax . prototype . commands . insert ()
* defined in misc / ajax . js .
*
* @ param $selector
* A jQuery selector string . If the command is a response to a request from
* an #ajax form element then this value can be NULL.
* @ param $html
* The data to use with the jQuery append () method .
* @ param $settings
* An optional array of settings that will be used for this command only .
*
* @ return
* An array suitable for use with the ajax_render () function .
*
* @ see http :// docs . jquery . com / Manipulation / append #content
*/
function ajax_command_append ( $selector , $html , $settings = NULL ) {
return array (
'command' => 'insert' ,
'method' => 'append' ,
'selector' => $selector ,
'data' => $html ,
'settings' => $settings ,
);
}
/**
2011-02-19 00:09:11 +00:00
* Creates a Drupal Ajax 'insert/after' command .
2009-08-17 07:29:32 +00:00
*
* The 'insert/after' command instructs the client to use jQuery ' s after ()
* method to insert the given HTML content after each element matched by
* the given selector .
*
* This command is implemented by Drupal . ajax . prototype . commands . insert ()
* defined in misc / ajax . js .
*
* @ param $selector
* A jQuery selector string . If the command is a response to a request from
* an #ajax form element then this value can be NULL.
* @ param $html
* The data to use with the jQuery after () method .
* @ param $settings
* An optional array of settings that will be used for this command only .
*
* @ return
* An array suitable for use with the ajax_render () function .
*
* @ see http :// docs . jquery . com / Manipulation / after #content
*/
function ajax_command_after ( $selector , $html , $settings = NULL ) {
return array (
'command' => 'insert' ,
'method' => 'after' ,
'selector' => $selector ,
'data' => $html ,
'settings' => $settings ,
);
}
/**
2011-02-19 00:09:11 +00:00
* Creates a Drupal Ajax 'insert/before' command .
2009-08-17 07:29:32 +00:00
*
* The 'insert/before' command instructs the client to use jQuery ' s before ()
* method to insert the given HTML content before each of elements matched by
* the given selector .
*
* This command is implemented by Drupal . ajax . prototype . commands . insert ()
* defined in misc / ajax . js .
*
* @ param $selector
* A jQuery selector string . If the command is a response to a request from
* an #ajax form element then this value can be NULL.
* @ param $html
* The data to use with the jQuery before () method .
* @ param $settings
* An optional array of settings that will be used for this command only .
*
* @ return
* An array suitable for use with the ajax_render () function .
*
* @ see http :// docs . jquery . com / Manipulation / before #content
*/
function ajax_command_before ( $selector , $html , $settings = NULL ) {
return array (
'command' => 'insert' ,
'method' => 'before' ,
'selector' => $selector ,
'data' => $html ,
'settings' => $settings ,
);
}
/**
2011-02-19 00:09:11 +00:00
* Creates a Drupal Ajax 'remove' command .
2009-08-17 07:29:32 +00:00
*
* The 'remove' command instructs the client to use jQuery ' s remove () method
* to remove each of elements matched by the given selector , and everything
* within them .
*
* This command is implemented by Drupal . ajax . prototype . commands . remove ()
* defined in misc / ajax . js .
*
* @ param $selector
* A jQuery selector string . If the command is a response to a request from
* an #ajax form element then this value can be NULL.
*
* @ return
* An array suitable for use with the ajax_render () function .
*
* @ see http :// docs . jquery . com / Manipulation / remove #expr
*/
function ajax_command_remove ( $selector ) {
return array (
'command' => 'remove' ,
'selector' => $selector ,
);
}
/**
2011-02-19 00:09:11 +00:00
* Creates a Drupal Ajax 'changed' command .
2009-08-17 07:29:32 +00:00
*
* This command instructs the client to mark each of the elements matched by the
* given selector as 'ajax-changed' .
*
* This command is implemented by Drupal . ajax . prototype . commands . changed ()
* defined in misc / ajax . js .
*
* @ param $selector
* A jQuery selector string . If the command is a response to a request from
* an #ajax form element then this value can be NULL.
* @ param $asterisk
* An optional CSS selector which must be inside $selector . If specified ,
* an asterisk will be appended to the HTML inside the $asterisk selector .
*
* @ return
* An array suitable for use with the ajax_render () function .
*/
function ajax_command_changed ( $selector , $asterisk = '' ) {
return array (
'command' => 'changed' ,
'selector' => $selector ,
2009-11-22 02:48:37 +00:00
'asterisk' => $asterisk ,
2009-08-17 07:29:32 +00:00
);
}
/**
2011-02-19 00:09:11 +00:00
* Creates a Drupal Ajax 'css' command .
2009-08-17 07:29:32 +00:00
*
* The 'css' command will instruct the client to use the jQuery css () method
* to apply the CSS arguments to elements matched by the given selector .
*
2010-11-29 03:00:50 +00:00
* This command is implemented by Drupal . ajax . prototype . commands . css ()
2009-08-17 07:29:32 +00:00
* defined in misc / ajax . js .
*
* @ param $selector
* A jQuery selector string . If the command is a response to a request from
* an #ajax form element then this value can be NULL.
* @ param $argument
* An array of key / value pairs to set in the CSS for the selector .
*
* @ return
* An array suitable for use with the ajax_render () function .
*
* @ see http :// docs . jquery . com / CSS / css #properties
*/
function ajax_command_css ( $selector , $argument ) {
return array (
'command' => 'css' ,
'selector' => $selector ,
'argument' => $argument ,
);
}
/**
2011-02-19 00:09:11 +00:00
* Creates a Drupal Ajax 'settings' command .
2009-08-17 07:29:32 +00:00
*
2010-01-12 06:31:22 +00:00
* The 'settings' command instructs the client either to use the given array as
* the settings for ajax - loaded content or to extend Drupal . settings with the
* given array , depending on the value of the $merge parameter .
2009-08-17 07:29:32 +00:00
*
* This command is implemented by Drupal . ajax . prototype . commands . settings ()
* defined in misc / ajax . js .
*
* @ param $argument
* An array of key / value pairs to add to the settings . This will be utilized
* for all commands after this if they do not include their own settings
* array .
2010-01-12 06:31:22 +00:00
* @ param $merge
* Whether or not the passed settings in $argument should be merged into the
* global Drupal . settings on the page . By default ( FALSE ), the settings that
* are passed to Drupal . attachBehaviors will not include the global
* Drupal . settings .
2009-08-17 07:29:32 +00:00
*
* @ return
* An array suitable for use with the ajax_render () function .
*/
2010-01-12 06:31:22 +00:00
function ajax_command_settings ( $argument , $merge = FALSE ) {
2009-08-17 07:29:32 +00:00
return array (
'command' => 'settings' ,
2009-10-18 05:14:39 +00:00
'settings' => $argument ,
2010-01-12 06:31:22 +00:00
'merge' => $merge ,
2009-08-17 07:29:32 +00:00
);
}
/**
2011-02-19 00:09:11 +00:00
* Creates a Drupal Ajax 'data' command .
2009-08-17 07:29:32 +00:00
*
* The 'data' command instructs the client to attach the name = value pair of
* data to the selector via jQuery ' s data cache .
*
* This command is implemented by Drupal . ajax . prototype . commands . data ()
* defined in misc / ajax . js .
*
* @ param $selector
* A jQuery selector string . If the command is a response to a request from
* an #ajax form element then this value can be NULL.
* @ param $name
* The name or key ( in the key value pair ) of the data attached to this
* selector .
* @ param $value
2009-12-30 08:16:55 +00:00
* The value of the data . Not just limited to strings can be any format .
2009-08-17 07:29:32 +00:00
*
* @ return
* An array suitable for use with the ajax_render () function .
*
* @ see http :// docs . jquery . com / Core / data #namevalue
*/
function ajax_command_data ( $selector , $name , $value ) {
return array (
'command' => 'data' ,
'selector' => $selector ,
'name' => $name ,
'value' => $value ,
);
}
2010-11-29 03:00:50 +00:00
/**
2011-02-19 00:09:11 +00:00
* Creates a Drupal Ajax 'invoke' command .
2010-11-29 03:00:50 +00:00
*
* The 'invoke' command will instruct the client to invoke the given jQuery
* method with the supplied arguments on the elements matched by the given
* selector . Intended for simple jQuery commands , such as attr (), addClass (),
* removeClass (), toggleClass (), etc .
*
* This command is implemented by Drupal . ajax . prototype . commands . invoke ()
* defined in misc / ajax . js .
*
* @ param $selector
* A jQuery selector string . If the command is a response to a request from
* an #ajax form element then this value can be NULL.
* @ param $method
* The jQuery method to invoke .
* @ param $arguments
* ( optional ) A list of arguments to the jQuery $method , if any .
*
* @ return
* An array suitable for use with the ajax_render () function .
*/
function ajax_command_invoke ( $selector , $method , array $arguments = array ()) {
return array (
'command' => 'invoke' ,
'selector' => $selector ,
'method' => $method ,
'arguments' => $arguments ,
);
}
2009-08-17 07:29:32 +00:00
/**
2011-02-19 00:09:11 +00:00
* Creates a Drupal Ajax 'restripe' command .
2009-08-17 07:29:32 +00:00
*
* The 'restripe' command instructs the client to restripe a table . This is
2010-01-25 10:38:35 +00:00
* usually used after a table has been modified by a replace or append command .
2009-08-17 07:29:32 +00:00
*
* This command is implemented by Drupal . ajax . prototype . commands . restripe ()
* defined in misc / ajax . js .
*
* @ param $selector
* A jQuery selector string .
*
* @ return
* An array suitable for use with the ajax_render () function .
*/
function ajax_command_restripe ( $selector ) {
return array (
'command' => 'restripe' ,
'selector' => $selector ,
);
}