Index: includes/form.inc =================================================================== RCS file: /cvs/drupal/drupal/includes/form.inc,v retrieving revision 1.214 diff -u -p -r1.214 form.inc --- includes/form.inc 4 Jul 2007 15:45:37 -0000 1.214 +++ includes/form.inc 9 Jul 2007 15:31:20 -0000 @@ -1469,15 +1469,16 @@ function form_expand_ahah($element) { // Adding the same javascript settings twice will cause a recursion error, // we avoid the problem by checking if the javascript has already been added. if (!isset($js_added[$element['#id']]) && isset($element['#ahah_event']) && isset($element['#ahah_path'])) { + drupal_add_js('misc/jquery.form.js'); drupal_add_js('misc/ahah.js'); drupal_add_js('misc/progress.js'); $ahah_binding = array( - 'id' => $element['#id'], - 'uri' => url($element['#ahah_path']), + 'uri' => url($element['#ahah_path']), 'event' => $element['#ahah_event'], - 'effect' => empty($element['#ahah_effect']) ? 'none' : $element['#ahah_effect'], - 'method' => empty($element['#ahah_method']) ? 'replace' : $element['#ahah_method'], + 'selector' => empty($element['#ahah_selector']) ? '#'. $element['#id'] : $element['#ahah_selector'], + 'effect' => empty($element['#ahah_effect']) ? 'none' : $element['#ahah_effect'], + 'method' => empty($element['#ahah_method']) ? 'replace' : $element['#ahah_method'], ); if (!empty($element['#ahah_wrapper'])) { Index: misc/ahah.js =================================================================== RCS file: /cvs/drupal/drupal/misc/ahah.js,v retrieving revision 1.1 diff -u -p -r1.1 ahah.js --- misc/ahah.js 4 Jul 2007 15:42:38 -0000 1.1 +++ misc/ahah.js 9 Jul 2007 15:31:20 -0000 @@ -31,6 +31,7 @@ Drupal.behaviors.ahah = function(context Drupal.ahah = function(base, element) { // Set the properties for this object. this.id = '#' + base; + this.selector = element.selector; this.event = element.event; this.uri = element.uri; this.wrapper = '#'+ element.wrapper; @@ -39,47 +40,73 @@ Drupal.ahah = function(base, element) { if (this.effect == 'none') { this.showEffect = 'show'; this.hideEffect = 'hide'; + this.showSpeed = ''; } else if (this.effect == 'fade') { this.showEffect = 'fadeIn'; this.hideEffect = 'fadeOut'; + this.showSpeed = 'slow'; } else { this.showEffect = this.effect + 'Toggle'; this.hideEffect = this.effect + 'Toggle'; + this.showSpeed = 'slow'; } - Drupal.redirectFormButton(this.uri, $(this.id).get(0), this); + + // Set the options for the ajaxSubmit function. + // The 'this' variable will not persist inside of the options object. + var ahah = this; + var options = { + url: ahah.uri, + beforeSubmit: function(form_values, element, options) { + return ahah.onsubmit(form_values, element, options); + }, + success: function(response, status) { + return ahah.oncomplete(response, status); + }, + complete: function(response, status) { + if (status == 'error') { + return ahah.onerror(response.responseText); + } + }, + dataType: 'json', + type: 'POST' + }; + + // Bind the ajaxSubmit function to the element event. + $(ahah.selector).bind(ahah.event, function() { + options.element = this; + $(ahah.id).parents('form').ajaxSubmit(options); + return false; + }); + }; /** * Handler for the form redirection submission. */ -Drupal.ahah.prototype.onsubmit = function () { +Drupal.ahah.prototype.onsubmit = function (form_values, element, options) { // Insert progressbar and stretch to take the same space. this.progress = new Drupal.progressBar('ahah_progress'); this.progress.setProgress(-1, Drupal.t('Please wait...')); var wrapper = $(this.wrapper); - var button = $(this.id); + var element = $(options.element); var progress_element = $(this.progress.element); - progress_element.css('float', 'left').css({ - display: 'none', - width: '10em', - margin: '0 0 0 20px' - }); - button.css('float', 'left').attr('disabled', true).after(progress_element); - eval('progress_element.' + this.showEffect + '()'); + progress_element.css('float', 'left').css('display', 'none'); + element.css('float', 'left').attr('disabled', true).after(progress_element); + progress_element.show(); }; /** * Handler for the form redirection completion. */ -Drupal.ahah.prototype.oncomplete = function (data) { +Drupal.ahah.prototype.oncomplete = function (response, status) { var wrapper = $(this.wrapper); var button = $(this.id); var progress_element = $(this.progress.element); - var new_content = $('
' + data + '
'); + var new_content = $('
' + response.data + '
'); Drupal.freezeHeight(); @@ -89,14 +116,24 @@ Drupal.ahah.prototype.oncomplete = funct // Hide the new content before adding to page. new_content.hide(); - // Add the form and re-attach behavior. + // Add the new content to the page. if (this.method == 'replace') { wrapper.empty().append(new_content); } else { eval('wrapper.' + this.method + '(new_content)'); } - eval('new_content.' + this.showEffect + '()'); + + // Determine what effect use and what content will receive the effect, + // then show the new content. + if ($('.ahah-new-content', new_content).size() > 0) { + $('.ahah-new-content', new_content).hide(); + new_content.show(); + eval('$(".ahah-new-content", new_content).' + this.showEffect + '("' + this.showSpeed +'")'); + } + else { + eval('new_content.' + this.showEffect + '("' + this.showSpeed +'")'); + } button.css('float', 'none').attr('disabled', false); Drupal.attachBehaviors(new_content); Index: misc/drupal.js =================================================================== RCS file: /cvs/drupal/drupal/misc/drupal.js,v retrieving revision 1.35 diff -u -p -r1.35 drupal.js --- misc/drupal.js 1 Jul 2007 15:37:08 -0000 1.35 +++ misc/drupal.js 9 Jul 2007 15:31:20 -0000 @@ -195,69 +195,6 @@ Drupal.theme = function(func) { }; /** - * Redirects a button's form submission to a hidden iframe and displays the result - * in a given wrapper. The iframe should contain a call to - * window.parent.iframeHandler() after submission. - */ -Drupal.redirectFormButton = function (uri, button, handler) { - // Trap the button - button.onmouseover = button.onfocus = function() { - button.onclick = function() { - // Create target iframe - Drupal.createIframe(); - - // Prepare variables for use in anonymous function. - var button = this; - var action = button.form.action; - var target = button.form.target; - - // Redirect form submission to iframe - this.form.action = uri; - this.form.target = 'redirect-target'; - - handler.onsubmit(); - - // Set iframe handler for later - window.iframeHandler = function () { - var iframe = $('#redirect-target').get(0); - // Restore form submission - button.form.action = action; - button.form.target = target; - - // Get response from iframe body - try { - response = (iframe.contentWindow || iframe.contentDocument || iframe).document.body.innerHTML; - // Firefox 1.0.x hack: Remove (corrupted) control characters - response = response.replace(/[\f\n\r\t]/g, ' '); - if (window.opera) { - // Opera-hack: it returns innerHTML sanitized. - response = response.replace(/"/g, '"'); - } - } - catch (e) { - response = null; - } - - response = Drupal.parseJson(response); - // Check response code - if (response.status == 0) { - handler.onerror(response.data); - return; - } - handler.oncomplete(response.data); - - return true; - }; - - return true; - }; - }; - button.onmouseout = button.onblur = function() { - button.onclick = null; - }; -}; - -/** * Retrieves the absolute position of an element on the screen */ Drupal.absolutePosition = function (el) { @@ -305,41 +242,6 @@ Drupal.parseJson = function (data) { }; /** - * Create an invisible iframe for form submissions. - */ -Drupal.createIframe = function () { - if ($('#redirect-holder').size()) { - return; - } - // Note: some browsers require the literal name/id attributes on the tag, - // some want them set through JS. We do both. - window.iframeHandler = function () {}; - var div = document.createElement('div'); - div.id = 'redirect-holder'; - $(div).html(''); - var iframe = div.firstChild; - $(iframe) - .attr({ - name: 'redirect-target', - id: 'redirect-target' - }) - .css({ - position: 'absolute', - height: '1px', - width: '1px', - visibility: 'hidden' - }); - $('body').append(div); -}; - -/** - * Delete the invisible iframe - */ -Drupal.deleteIframe = function () { - $('#redirect-holder').remove(); -}; - -/** * Freeze the current body height (as minimum height). Used to prevent * unnecessary upwards scrolling when doing DOM manipulations. */ Index: misc/jquery.form.js =================================================================== RCS file: misc/jquery.form.js diff -N misc/jquery.form.js --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ misc/jquery.form.js 9 Jul 2007 15:31:20 -0000 @@ -0,0 +1,14 @@ +// $Id$ + +/* + * jQuery form plugin + * @requires jQuery v1.1 or later + * + * Examples at: http://malsup.com/jquery/form/ + * Dual licensed under the MIT and GPL licenses: + * http://www.opensource.org/licenses/mit-license.php + * http://www.gnu.org/licenses/gpl.html + * + * Version: 1.0.1 Jul-07-2007 + */ + eval(function(p,a,c,k,e,d){e=function(c){return(c35?String.fromCharCode(c+29):c.toString(36))};if(!''.replace(/^/,String)){while(c--){d[e(c)]=k[c]||e(c)}k=[function(e){return d[e]}];e=function(){return'\\w+'};c=1};while(c--){if(k[c]){p=p.replace(new RegExp('\\b'+e(c)+'\\b','g'),k[c])}}return p}('(6($){$.c.1b=6(7){3(G 7==\'6\')7={F:7};7=$.1V({1a:4.W(\'28\')||1n.3m,L:4.W(\'24\')||\'1S\'},7||{});2 a=4.1F(7.O);3(7.1R&&7.1R(a,4,7)===B)8 4;2 19={};$.N.J(\'5.D.2F\',[a,4,7,19]);3(19.19)8 4;2 q=$.1J(a);3(7.L.2G()==\'1S\'){7.1a+=(7.1a.2I(\'?\')>=0?\'&\':\'?\')+q;7.d=r}o 7.d=q;2 $5=4,I=[];3(7.1E)I.u(6(){$5.1E()});3(7.1K)I.u(6(){$5.1K()});3(!7.14&&7.11){2 1Z=7.F;I.u(6(d,12){$(7.11).W("2j",d).2J().H(1Z,[d,12])})}o 3(7.F)I.u(7.F);7.F=6(d,12){C(2 i=0,w=I.z;i\');2 f=$f[0];2 1Y=$.1y.1W&&1n.1W.2R()<9;3($.1y.25||1Y)f.2S=\'2T:B;1D.2U("");\';$f.2V({2W:\'2Y\',1T:\'-2b\',2p:\'-2b\'});2 m={V:r,1e:r,12:0,2Z:\'n/a\',3e:6(){},30:6(){},31:6(){}};2 g=k.32;3(g&&!$.2o++)$.N.J("3a");3(g)$.N.J("34",[m,k]);2 1X=0;2 1B=0;1c(6(){$f.35(\'1r\');f.22?f.22(\'2e\',S):f.36(\'2f\',S,B);2 27=5.23?\'23\':\'37\';2 t=$5.W(\'11\');$5.W({11:K,24:\'38\',27:\'3b/5-d\',28:k.1a});3(k.1s)1c(6(){1B=16;S()},k.1s);5.D();$5.W(\'11\',t)},10);6 S(){3(1X++)8;f.2d?f.2d(\'2e\',S):f.3g(\'2f\',S,B);2 1j=16;3h{3(1B)3i\'1s\';2 d,h;h=f.2h?f.2h.1D:f.2i?f.2i:f.1D;m.V=h.1r?h.1r.2j:r;m.1e=h.2k?h.2k:h;3(k.14==\'2l\'||k.14==\'3l\'){2 1G=h.1z(\'1H\')[0];d=1G?1G.p:m.V;3(k.14==\'2l\')3n("d = "+d);o $.3o(d)}o 3(k.14==\'1O\'){d=m.1e;3(!d&&m.V!=r)d=1L(m.V)}o{d=m.V}}3q(e){1j=B;$.3r(k,m,\'2s\',e)}3(1j){k.F(d,\'F\');3(g)$.N.J("3s",[m,k])}3(g)$.N.J("3t",[m,k]);3(g&&!--$.2o)$.N.J("3v");3(k.2q)k.2q(m,1j?\'F\':\'2s\');1c(6(){$f.3w();m.1e=r},2v)};6 1L(s,h){3(1n.1M){h=1N 1M(\'2w.2x\');h.2y=\'B\';h.2A(s)}o h=(1N 2B()).2C(s,\'1x/1O\');8(h&&h.1Q&&h.1Q.1p!=\'2D\')?h:r}}};$.c.1b.1f=0;$.c.X=6(7){8 4.2c().D(1u).H(6(){4.1v=$.c.X.1f++;$.c.X.1C[4.1v]=7;$(":D,A:U",4).26(1w)})};$.c.X.1f=1;$.c.X.1C={};6 1w(e){2 $5=4.5;$5.M=4;3(4.L==\'U\'){3(e.2t!=1l){$5.T=e.2t;$5.R=e.2H}o 3(G $.c.15==\'6\'){2 15=$(4).15();$5.T=e.1U-15.2p;$5.R=e.2u-15.1T}o{$5.T=e.1U-4.2N;$5.R=e.2u-4.2Q}}1c(6(){$5.M=$5.T=$5.R=r},10)};6 1u(){2 K=4.1v;2 7=$.c.X.1C[K];$(4).1b(7);8 B};$.c.2c=6(){4.21(\'D\',1u);8 4.H(6(){$(":D,A:U",4).21(\'26\',1w)})};$.c.1F=6(O){2 a=[];3(4.z==0)8 a;2 5=4[0];2 1d=O?5.1z(\'*\'):5.39;3(!1d)8 a;C(2 i=0,w=1d.z;i array( - 'arguments' => array('form' => NULL), + 'block_admin_display_form' => array( + 'arguments' => array('blocks' => NULL, 'form' => NULL), ), ); } @@ -70,11 +70,15 @@ function block_perm() { * Implementation of hook_menu(). */ function block_menu() { + $items['admin/build/block/list/js'] = array( + 'title' => 'Javascript List Form', + 'page callback' => 'block_admin_display_js', + 'type' => MENU_CALLBACK, + ); $items['admin/build/block'] = array( 'title' => 'Blocks', 'description' => 'Configure what block content appears in your site\'s sidebars and other regions.', - 'page callback' => 'drupal_get_form', - 'page arguments' => array('block_admin_display'), + 'page callback' => 'block_admin_display', 'access arguments' => array('administer blocks'), ); $items['admin/build/block/list'] = array( @@ -102,7 +106,7 @@ function block_menu() { $items['admin/build/block/list/'. $key] = array( 'title' => '!key settings', 'title arguments' => array('!key' => $theme->info['name']), - 'page arguments' => array('block_admin_display', $key), + 'page arguments' => array($key), 'type' => $key == $default ? MENU_DEFAULT_LOCAL_TASK : MENU_LOCAL_TASK, 'weight' => $key == $default ? -10 : 0, ); @@ -215,9 +219,20 @@ function _block_rehash() { } /** + * Menu callback for admin/build/block. + */ +function block_admin_display($theme = NULL) { + // Fetch and sort blocks + $blocks = _block_rehash(); + usort($blocks, '_block_compare'); + + return drupal_get_form('block_admin_display_form', $blocks, $theme); +} + +/** * Generate main block administration form. */ -function block_admin_display(&$form_state, $theme = NULL) { +function block_admin_display_form(&$form_state, $blocks, $theme = NULL) { global $theme_key, $custom_theme; // Add CSS @@ -232,41 +247,143 @@ function block_admin_display(&$form_stat } init_theme(); - // Fetch and sort blocks - $blocks = _block_rehash(); - usort($blocks, '_block_compare'); - $throttle = module_exists('throttle'); $block_regions = array(BLOCK_REGION_NONE => '<'. t('none') .'>') + system_region_list($theme_key); // Build form tree - $form['#action'] = arg(3) ? url('admin/build/block/list/'. $theme_key) : url('admin/build/block'); - $form['#tree'] = TRUE; + $form = array( + '#action' => arg(3) ? url('admin/build/block/list/'. $theme_key) : url('admin/build/block'), + '#tree' => TRUE, + '#cache' => TRUE, + ); foreach ($blocks as $i => $block) { - $form[$i]['module'] = array('#type' => 'value', '#value' => $block['module']); - $form[$i]['delta'] = array('#type' => 'value', '#value' => $block['delta']); - $form[$i]['info'] = array('#value' => check_plain($block['info'])); - $form[$i]['theme'] = array('#type' => 'hidden', '#value' => $theme_key); - $form[$i]['weight'] = array('#type' => 'weight', '#default_value' => $block['weight']); - $form[$i]['region'] = array('#type' => 'select', + $key = $block['module'] .'_'. $block['delta']; + $form[$key]['module'] = array( + '#type' => 'value', + '#value' => $block['module'], + ); + $form[$key]['delta'] = array( + '#type' => 'value', + '#value' => $block['delta'], + ); + $form[$key]['info'] = array( + '#value' => check_plain($block['info']) + ); + $form[$key]['theme'] = array( + '#type' => 'hidden', + '#value' => $theme_key + ); + $form[$key]['weight'] = array( + '#type' => 'weight', + '#default_value' => $block['weight'], + ); + $form[$key]['region'] = array( + '#type' => 'select', '#default_value' => $block['status'] ? (isset($block['region']) ? $block['region'] : system_default_region($theme_key)) : BLOCK_REGION_NONE, '#options' => $block_regions, ); if ($throttle) { - $form[$i]['throttle'] = array('#type' => 'checkbox', '#default_value' => isset($block['throttle']) ? $block['throttle'] : FALSE); + $form[$key]['throttle'] = array('#type' => 'checkbox', '#default_value' => isset($block['throttle']) ? $block['throttle'] : FALSE); } - $form[$i]['configure'] = array('#value' => l(t('configure'), 'admin/build/block/configure/'. $block['module'] .'/'. $block['delta'])); + $form[$key]['configure'] = array('#value' => l(t('configure'), 'admin/build/block/configure/'. $block['module'] .'/'. $block['delta'])); if ($block['module'] == 'block') { - $form[$i]['delete'] = array('#value' => l(t('delete'), 'admin/build/block/delete/'. $block['delta'])); + $form[$key]['delete'] = array('#value' => l(t('delete'), 'admin/build/block/delete/'. $block['delta'])); } } - $form['submit'] = array('#type' => 'submit', '#value' => t('Save blocks')); + + // Attach the AHAH events to the submit button. Set the form id as the wrapper + // and set the selector to every select item in the form. + $form['submit'] = array( + '#type' => 'submit', + '#value' => t('Save blocks'), + '#ahah_path' => 'admin/build/block/list/js/'. $theme_key, + '#ahah_selector' => '#block-admin-display-form select', + '#ahah_wrapper' => 'block-admin-display-form', + '#ahah_event' => 'change', + '#ahah_effect' => 'fade', + ); return $form; } /** + * Javascript callback for AHAH replacement. Re-generate the form with the + * updated values and return necessary html. + */ +function block_admin_display_js($theme = NULL) { + // Load the cached form. + $form_cache = cache_get('form_'. $_POST['form_build_id'], 'cache_form'); + + // Set the new weights and regions for each block. + $blocks = array(); + foreach (element_children($form_cache->data) as $key) { + $field = $form_cache->data[$key]; + if (isset($field['info'])) { + $block = array( + 'module' => $field['module']['#value'], + 'delta' => $field['delta']['#value'], + 'info' => html_entity_decode($field['info']['#value'], ENT_QUOTES), + 'region' => $_POST[$key]['region'], + 'weight' => $_POST[$key]['weight'], + 'status' => $_POST[$key]['region'] == BLOCK_REGION_NONE ? 0 : 1, + ); + + $throttle = module_exists('throttle'); + if ($throttle) { + $block['throttle'] = $_POST[$key]['throttle']; + } + + if ($block['weight'] != $form_cache->data[$key]['weight']['#default_value'] || $block['region'] != $form_cache->data[$key]['region']['#default_value']) { + $changed_block = $block['module'] .'_'. $block['delta']; + } + + $blocks[] = $block; + } + } + + // Resort the blocks with the new weights. + usort($blocks, '_block_compare'); + + // Update the form in the new order. + $form_state = array('submitted' => FALSE); + $form = block_admin_display_form($form_state, $blocks, $theme); + + // Preserve the order of the new form while merging the previous data. + $form = array_merge($form_cache->data, $form); + + cache_set('form_'. $_POST['form_build_id'], $form, 'cache_form', $form_cache->expire); + + // Add a class to mark the new AHAH content. + if (empty($form[$changed_block]['attributes']['class'])) { + $form[$changed_block]['#attributes']['class'] = 'ahah-new-content'; + } + else { + $form[$changed_block]['#attributes']['class'] .= ' ahah-new-content'; + } + + $form += array( + '#post' => $_POST, + '#theme' => 'block_admin_display_form', + ); + + // Add messages to our output. + drupal_set_message(t('Your settings will not be saved until you click the Save blocks button.')); + $form['status_messages'] = array( + '#value' => theme('status_messages'), + '#weight' => -100, + ); + + // Render the form. + drupal_alter('form', $form, array(), 'block_admin_display_form'); + $form = form_builder('block_admin_display_form', $form, $form_state); + $output = drupal_render($form); + + // Return the output in JSON format. + drupal_json(array('status' => TRUE, 'data' => $output)); +} + +/** * Helper function for sorting blocks on admin/build/block. * * Active blocks are sorted by region, then by weight. @@ -292,7 +409,7 @@ function _block_compare($a, $b) { /** * Process main block administration form submission. */ -function block_admin_display_submit($form, &$form_state) { +function block_admin_display_form_submit($form, &$form_state) { foreach ($form_state['values'] as $block) { $block['status'] = $block['region'] != BLOCK_REGION_NONE; $block['region'] = $block['status'] ? $block['region'] : ''; @@ -308,53 +425,65 @@ function block_admin_display_submit($for * Note: the blocks are already sorted in the right order, * grouped by status, region and weight. */ -function theme_block_admin_display($form) { +function theme_block_admin_display_form($form) { global $theme_key; $throttle = module_exists('throttle'); $block_regions = system_region_list($theme_key); - // Highlight regions on page to provide visual reference. + $table_regions = array(); foreach ($block_regions as $key => $value) { + // Highlight regions on page to provide visual reference. drupal_set_content($key, '
'. $value .'
'); - } + // Create a seperate table section for each region. + $row = array(array('data' => $value, 'class' => 'region', 'colspan' => ($throttle ? 7 : 6))); + $table_regions[$key] = array($row); + } + // Add a final table secton for disabled blocks. + $row = array(array('data' => t('Disabled'), 'class' => 'region', 'colspan' => ($throttle ? 7 : 6))); + $table_regions['disabled'] = array($row); - // Build rows - $rows = array(); - $last_region = ''; - $last_status = 1; + // Build rows. foreach (element_children($form) as $i) { $block = &$form[$i]; // Only take form elements that are blocks. if (isset($block['info'])) { - // Fetch values - $region = $block['region']['#default_value']; + // Fetch values. + $region = $block['region']['#value']; $status = $region != BLOCK_REGION_NONE; - // Output region header - if ($status && $region != $last_region) { - $region_title = t('@region', array('@region' => drupal_ucfirst($block_regions[$region]))); - $rows[] = array(array('data' => $region_title, 'class' => 'region', 'colspan' => ($throttle ? 7 : 6))); - $last_region = $region; - } - // Output disabled header - elseif ($status != $last_status) { - $rows[] = array(array('data' => t('Disabled'), 'class' => 'region', 'colspan' => ($throttle ? 7 : 6))); - $last_status = $status; - } - - // Generate block row + // Generate block row. $row = array( - array('data' => drupal_render($block['info']), 'class' => 'block'), - drupal_render($block['region']) . drupal_render($block['theme']), - drupal_render($block['weight']), + 'data' => array( + array('data' => drupal_render($block['info']), 'class' => 'block'), + drupal_render($block['region']) . drupal_render($block['theme']), + drupal_render($block['weight']), + ), ); if ($throttle) { - $row[] = drupal_render($block['throttle']); + $row['data'][] = drupal_render($block['throttle']); + } + $row['data'][] = drupal_render($block['configure']); + $row['data'][] = !empty($block['delete']) ? drupal_render($block['delete']) : ''; + + if (isset($block['#attributes']['class'])) { + $row['class'] = $block['#attributes']['class']; + } + + if ($status) { + $table_regions[$region][] = $row; + } + else { + $table_regions['disabled'][] = $row; } - $row[] = drupal_render($block['configure']); - $row[] = !empty($block['delete']) ? drupal_render($block['delete']) : ''; - $rows[] = $row; + } + } + + // Output the tables for each region with at least one block. + $rows = array(); + foreach ($table_regions as $key => $region) { + if (count($region) > 1) { + $rows = array_merge($rows, $region); } } @@ -365,8 +494,8 @@ function theme_block_admin_display($form } $header[] = array('data' => t('Operations'), 'colspan' => 2); - $output = theme('table', $header, $rows, array('id' => 'blocks')); - + $output = isset($form['status_messages']) ? drupal_render($form['status_messages']) : ''; + $output .= theme('table', $header, $rows, array('id' => 'blocks')); $output .= drupal_render($form); return $output; Index: modules/system/system.css =================================================================== RCS file: /cvs/drupal/drupal/modules/system/system.css,v retrieving revision 1.32 diff -u -p -r1.32 system.css --- modules/system/system.css 27 Jun 2007 17:54:49 -0000 1.32 +++ modules/system/system.css 9 Jul 2007 15:31:20 -0000 @@ -413,8 +413,9 @@ html.js .no-js { .progress .bar { background: #fff url(../../misc/progress.gif); border: 1px solid #00375a; + width: 5em; height: 1.5em; - margin-top: 0.2em; + margin: 0.2em 0 0 0.2em; } .progress .filled { background: #0072b9; Index: modules/system/system.module =================================================================== RCS file: /cvs/drupal/drupal/modules/system/system.module,v retrieving revision 1.509 diff -u -p -r1.509 system.module --- modules/system/system.module 5 Jul 2007 08:48:58 -0000 1.509 +++ modules/system/system.module 9 Jul 2007 15:31:22 -0000 @@ -103,27 +103,27 @@ function system_elements() { $type['form'] = array('#method' => 'post', '#action' => request_uri()); // Inputs - $type['submit'] = array('#input' => TRUE, '#name' => 'op', '#button_type' => 'submit', '#executes_submit_callback' => TRUE, '#ahah_event' => 'submit', '#process' => array('form_expand_ahah')); - $type['button'] = array('#input' => TRUE, '#name' => 'op', '#button_type' => 'submit', '#executes_submit_callback' => FALSE, '#ahah_event' => 'submit', '#process' => array('form_expand_ahah')); - $type['textfield'] = array('#input' => TRUE, '#size' => 60, '#maxlength' => 128, '#autocomplete_path' => FALSE); - $type['password'] = array('#input' => TRUE, '#size' => 60, '#maxlength' => 128); - $type['password_confirm'] = array('#input' => TRUE, '#process' => array('expand_password_confirm')); - $type['textarea'] = array('#input' => TRUE, '#cols' => 60, '#rows' => 5, '#resizable' => TRUE); + $type['submit'] = array('#input' => TRUE, '#name' => 'op', '#button_type' => 'submit', '#executes_submit_callback' => TRUE, '#ahah_event' => 'click', '#process' => array('form_expand_ahah')); + $type['button'] = array('#input' => TRUE, '#name' => 'op', '#button_type' => 'submit', '#executes_submit_callback' => FALSE, '#ahah_event' => 'click', '#process' => array('form_expand_ahah')); + $type['textfield'] = array('#input' => TRUE, '#size' => 60, '#maxlength' => 128, '#autocomplete_path' => FALSE, '#ahah_event' => 'blur', '#process' => array('form_expand_ahah')); + $type['password'] = array('#input' => TRUE, '#size' => 60, '#maxlength' => 128, '#ahah_event' => 'blur', '#process' => array('form_expand_ahah')); + $type['password_confirm'] = array('#input' => TRUE, '#ahah_event' => 'blur', '#process' => array('expand_password_confirm', 'form_expand_ahah')); + $type['textarea'] = array('#input' => TRUE, '#cols' => 60, '#rows' => 5, '#resizable' => TRUE, '#ahah_event' => 'blur', '#process' => array('form_expand_ahah')); $type['radios'] = array('#input' => TRUE, '#process' => array('expand_radios')); - $type['radio'] = array('#input' => TRUE, '#default_value' => NULL); + $type['radio'] = array('#input' => TRUE, '#default_value' => NULL, '#ahah_event' => 'change', '#process' => array('form_expand_ahah')); $type['checkboxes'] = array('#input' => TRUE, '#process' => array('expand_checkboxes'), '#tree' => TRUE); - $type['checkbox'] = array('#input' => TRUE, '#return_value' => 1); - $type['select'] = array('#input' => TRUE, '#size' => 0, '#multiple' => FALSE); - $type['weight'] = array('#input' => TRUE, '#delta' => 10, '#default_value' => 0, '#process' => array('process_weight')); + $type['checkbox'] = array('#input' => TRUE, '#return_value' => 1, '#ahah_event' => 'change', '#process' => array('form_expand_ahah')); + $type['select'] = array('#input' => TRUE, '#size' => 0, '#multiple' => FALSE, '#ahah_event' => 'change', '#process' => array('form_expand_ahah')); + $type['weight'] = array('#input' => TRUE, '#delta' => 10, '#default_value' => 0, '#ahah_event' => 'change', '#process' => array('process_weight', 'form_expand_ahah')); $type['date'] = array('#input' => TRUE, '#process' => array('expand_date' => array()), '#element_validate' => array('date_validate')); $type['file'] = array('#input' => TRUE, '#size' => 60); // Form structure $type['item'] = array('#value' => ''); - $type['hidden'] = array('#input' => TRUE); + $type['hidden'] = array('#input' => TRUE, '#process' => array('form_expand_ahah')); $type['value'] = array('#input' => TRUE); $type['markup'] = array('#prefix' => '', '#suffix' => ''); - $type['fieldset'] = array('#collapsible' => FALSE, '#collapsed' => FALSE, '#value' => NULL); + $type['fieldset'] = array('#collapsible' => FALSE, '#collapsed' => FALSE, '#value' => NULL, '#process' => array('form_expand_ahah')); $type['token'] = array('#input' => TRUE); return $type; }