Index: css/ctools.css =================================================================== RCS file: /cvs/drupal-contrib/contributions/modules/ctools/css/ctools.css,v retrieving revision 1.3 diff -u -r1.3 ctools.css --- css/ctools.css 22 Apr 2009 22:31:28 -0000 1.3 +++ css/ctools.css 1 Jun 2009 09:04:21 -0000 @@ -12,7 +12,8 @@ } a.ctools-ajaxing, -input.ctools-ajaxing { +input.ctools-ajaxing, +select.ctools-ajaxing { padding-right: 18px !important; background: url(../images/status-active.gif) right center no-repeat; } Index: js/ajax-responder.js =================================================================== RCS file: /cvs/drupal-contrib/contributions/modules/ctools/js/ajax-responder.js,v retrieving revision 1.7 diff -u -r1.7 ajax-responder.js --- js/ajax-responder.js 22 Apr 2009 22:31:28 -0000 1.7 +++ js/ajax-responder.js 1 Jun 2009 09:04:27 -0000 @@ -210,6 +210,16 @@ $.extend(Drupal.settings, data.argument); }, + data: function(data) { + $(data.selector).data(data.name, data.value); + }, + + messages: function(data) { + $('div.messages').remove(); + $('form:not([id*="search"]):first').before(data.data); + Drupal.attachBehaviors($('div.messages')); + }, + restripe: function(data) { // :even and :odd are reversed because jquery counts from 0 and // we count from 1, so we're out of sync. @@ -225,6 +235,43 @@ }; /** + * Generic replacement for drop down select change handler to execute ajax method. + */ +Drupal.CTools.AJAX.changeAJAXSelect = function () { + if ($(this).hasClass('ctools-ajaxing')) { + return false; + } + + if (!$(this).data('url')) { + $(this).data('url', Drupal.settings.CToolsAjaxSelect.url); + } + var object = $(this).addClass('ctools-ajaxing'); + var url = $(this).data('url') + $(this).find('option:selected').attr('value'); + try { + $.ajax({ + type: "POST", + url: url, + data: '', + global: true, + success: Drupal.CTools.AJAX.respond, + error: function() { + alert("An error occurred while attempting to process " + url); + }, + complete: function() { + object.removeClass('ctools-ajaxing'); + }, + dataType: 'json' + }); + } + catch (err) { + alert("An error occurred while attempting to process " + url); + object.removeClass('ctools-ajaxing'); + return false; + } + return false; +}; + +/** * Bind links that will open modals to the appropriate function. */ Drupal.behaviors.CToolsAJAX = function(context) { @@ -237,4 +284,9 @@ $('input.ctools-use-ajax:not(.ctools-use-ajax-processed)', context) .addClass('ctools-use-ajax-processed') .click(Drupal.CTools.AJAX.clickAJAXButton); + + // Bind select + $('select.ctools-use-ajax:not(.ctools-use-ajax-processed)', context) + .addClass('ctools-use-ajax-processed') + .change(Drupal.CTools.AJAX.changeAJAXSelect); }; Index: includes/ajax.inc =================================================================== RCS file: /cvs/drupal-contrib/contributions/modules/ctools/includes/ajax.inc,v retrieving revision 1.7 diff -u -r1.7 ajax.inc --- includes/ajax.inc 11 May 2009 22:09:53 -0000 1.7 +++ includes/ajax.inc 1 Jun 2009 09:04:26 -0000 @@ -58,6 +58,14 @@ * - settings * - argument: An array of settings to add to Drupal.settings via $.extend * + * - data + * - selector: The CSS selector. This can be any selector jquery uses in $(). + * - name: The name or key of the data attached to this selector. + * - value: The value of the data. Not just limited to strings can be any format. + * + * - messages + * - no arguments since content is retrieved from drupal_get_messages(). + * * Commands are usually created with a couple of helper functions, so they * look like this: * @@ -295,6 +303,41 @@ } /** + * Create a data command for the AJAX responder. + * + * This will attach the name=value pair of data to the selector via + * jquery's data cache. + * + * @param $selector + * The CSS selector. This can be any selector jquery uses in $(). + * @param $name + * The name or key: of the data attached to this selector. + * @param $value + * The value of the data. Not just limited to strings can be any format. + */ +function ctools_ajax_command_data($selector, $name, $value) { + return array( + 'command' => 'data', + 'selector' => $selector, + 'name' => $name, + 'value' => $value, + ); +} + +/** + * Create a messages command for the AJAX responder. + * + * This will first remove previous status messages before attempting to add + * the status messages with content from drupal_get_messages(). + */ +function ctools_ajax_command_messages() { + return array( + 'command' => 'messages', + 'data' => theme('status_messages'), + ); +} + +/** * Force a table to be restriped. * * This is usually used after a table has been modifed by a replace or append @@ -336,3 +379,155 @@ ctools_ajax_render($commands); } +/** + * Retrieve a select element compatible with ctools_ajax_select_change(). + * + * This is a helper function to easily populate a select form element + * which can be used for on select change ajax functionality. By assigning + * a destination url to a select form element the selected value will be + * sent to the url via ajax when the element's onchange event fires. + * + * A simple example to append a select item to the end of the first div + * which will call the url some/ajax/url/0..2 when the select field + * changes. + * + * @code + * $element = ctools_ajax_select_change_element('select-1', array('a', 'b', 'c')); + * $output = ctools_ajax_select_change('append', 'div:first', 'some/ajax/url', $element); + * ctools_ajax_render($output); + * @endcode + * + * @param $name + * The name for this element. This is required to have the #name attribute populated and + * to attach the destination url to this unique key. + * @param $options + * The items displayed in the select list. This is an array collection of key: value pairs + * populated as values in the select list. + * @param $title + * The label of the field. Optional label or titel for this field. + * @param $description + * The description of the field. Optional description or help information rendered below the field. + * @param $required + * Whether this value is required. Defaults set to FALSE, not required. + * @param $class + * Any class to apply to the link. Space-delimited string or options array. + * @param $type + * A type to use, in case a different behavior should be attached. Defaults + * to ctools-use-ajax. + * @return Standard select form element which can be used in any drupal form. + */ +function ctools_ajax_select_change_element($name, $options, $title = '', $description = '', $required = FALSE, $class = '', $type = 'ctools-use-ajax') { + $classes = is_array($class) ? implode(' ', $class) : $class; + return array( + '#name' => $name, + '#type' => 'select', + '#title' => $title, + '#options' => $options, + '#description' => $description, + '#required' => $required, + '#attributes' => array('class' => "$classes $type"), + ); +} + +/** + * Inject a new select element into the document and attach an ajax url to it. + * + * This method is used when answering an ajax call and replying with output commands + * via ctools_ajax_render(). + * + * A choice of 5 methods are provided to insert the select element into the document. + * The available options are: + * after - insert the element after the selector element. + * append - insert the element inside the selector element at the end of all its children. + * prepend - insert the element inside the selector element at the start of all its children. + * before - insert the element before the selector element. + * replace - replace the selector element with the select list. + * + * This will attach a destination url to the element which will generate an ajax call when the + * on change event fires. + * + * Requirements: + * The $element['#name'] must be populated and unique. This is used to attach the + * destination url to the element. + * The element should have the class ctools-use-ajax assigned as attribute to allow + * the underlying javasctipt to function. + * + * @param $command + * The injection method/command to use. Either; after, append, prepend, before or replace. + * @param $selector + * The CSS selector. This can be any selector jquery uses in $(). + * @param $dest + * The destination of the ajax call. Add a trailing / allowing the selected value to be + * added at the end of the url. + * @param $element + * The select element to attach the url to. With #name property and class ctools-use-ajax assigned. + * @return 2 commands to forward to ctools_ajax_render(). + */ +function ctools_ajax_select_change($command, $selector, $dest, $element) { + $output = array(); + switch ($command) { + case 'after' : + $output[] = ctools_ajax_command_after($selector, theme('select', $element)); + break; + case 'append' : + $output[] = ctools_ajax_command_append($selector, theme('select', $element)); + break; + case 'prepend' : + $output[] = ctools_ajax_command_prepend($selector, theme('select', $element)); + break; + case 'before' : + $output[] = ctools_ajax_command_before($selector, theme('select', $element)); + break; + case 'replace' : + $output[] = ctools_ajax_command_replace($selector, theme('select', $element)); + break; + } + $output[] = ctools_ajax_command_data("select[name='{$element['#name']}']", 'url', $dest); + return $output; +} + +/** + * Attach a url to a select field to make an ajax call on change event. + * + * This method is used in a normal drupal_get_form callback function when not answering + * an ajax call and normal html will be returned. Adds the required JavaScript files and + * allows for one url to be attached to a select form field element which has the class + * ctools-use-ajax assigned. + * + * Example: + * @code + * function mymodule_drilldown_form() { + * ctools_ajax_select_change_add_js('mymodule/ajax/drill-down/'); + * $form = array(); + * $form['drill'] = ctools_ajax_select_change_element( + * 'drill', + * $options, + * t('Drill down'), + * t('Select an option and more options will be retrieved.'), + * ); + * return $form; + * } + * @endcode + * + * @param $dest + * The destination of the ajax call. Add a trailing / allowing the selected value to be + * added at the end of the url. + */ +function ctools_ajax_select_change_add_js($dest) { + // Provide a gate so we only do this once. + static $done = FALSE; + if ($done) { + return; + } + + $settings = array( + 'CToolsAjaxSelect' => array( + 'url' => $dest, + ), + ); + + drupal_add_js($settings, 'setting'); + ctools_add_js('ajax-responder'); + ctools_add_css('ctools'); + $done = TRUE; +}