- Patch #181066 by quicksketch et al: drag and drop of table rows on the block adminsitration page.
parent
44373cf0b1
commit
6049f23760
|
@ -46,6 +46,7 @@ Drupal 6.0, xxxx-xx-xx (development version)
|
|||
.info file.
|
||||
* Dynamically check password strength and confirmation.
|
||||
* Refactored poll administration.
|
||||
* Drag and drop of table rows in the block administration page.
|
||||
- Theme system:
|
||||
* Added .info files to themes and made it easier to specify regions and
|
||||
features.
|
||||
|
|
|
@ -1926,6 +1926,113 @@ function drupal_get_js($scope = 'header', $javascript = NULL) {
|
|||
return $output;
|
||||
}
|
||||
|
||||
/**
|
||||
* Assist in adding the tableDrag JavaScript behavior to a themed table.
|
||||
*
|
||||
* Draggable tables should be used wherever an outline or list of sortable items
|
||||
* needs to be arranged by an end-user. Draggable tables are very flexible and
|
||||
* can manipulate the value of form elements placed within individual columns.
|
||||
*
|
||||
* To setup a table to use drag and drop in place of weight select-lists or
|
||||
* in place of a form that contains parent relationships, the form must be
|
||||
* themed into a table. The table must have an id attribute set. If using
|
||||
* theme_table(), the id may be set as such:
|
||||
* @code
|
||||
* $output = theme('table', $header, $rows, array('id' => 'my-module-table'));
|
||||
* return $output;
|
||||
* @endcode
|
||||
*
|
||||
* In the theme function for the form, a special class must be added to each
|
||||
* form element within the same column, "grouping" them together.
|
||||
*
|
||||
* In a situation where a single weight column is being sorted in the table, the
|
||||
* classes could be added like this (in the theme function):
|
||||
* @code
|
||||
* $form['my_elements'][$delta]['weight']['attributes']['class'] = "my-elements-weight";
|
||||
* @endcode
|
||||
*
|
||||
* Calling drupal_add_tabledrag() would then be written as such:
|
||||
* @code
|
||||
* drupal_add_tabledrag('my-module-table', 'sort', 'sibling', 'my-elements-weight');
|
||||
* @endcode
|
||||
*
|
||||
* In a more complex case where there are several groups in one column (such as
|
||||
* the block regions on the admin/build/block page), a separate subgroup class
|
||||
* must also be added to differentiate the groups.
|
||||
* @code
|
||||
* $form['my_elements'][$region][$delta]['weight']['attributes']['class'] = "my-elements-weight my-elements-weight-". $region;
|
||||
* @endcode
|
||||
*
|
||||
* $group is still 'my-element-weight', and the additional $subgroup variable
|
||||
* will be passed in as 'my-elements-weight-'. $region. This also means that
|
||||
* you'll need to call drupal_add_tabledrag() once for every region added.
|
||||
*
|
||||
* @code
|
||||
* foreach ($regions as $region) {
|
||||
* drupal_add_tabledrag('my-module-table', 'sort', 'sibling', 'my-elements-weight', 'my-elements-weight-'. $region);
|
||||
* }
|
||||
* @endcode
|
||||
*
|
||||
* In a situation where tree relationships are present, adding multiple
|
||||
* subgroups is not necessary, because the table will contain indentations that
|
||||
* provide enough information about the sibling and parent relationships.
|
||||
* See theme_menu_overview_form() for an example creating a table containing
|
||||
* parent relationships.
|
||||
*
|
||||
* Please note that this function should be called from the theme layer, such as
|
||||
* in a .tpl.php file, theme_ function, or in a template_preprocess function,
|
||||
* not in a form declartion. Though the same JavaScript could be added to the
|
||||
* page using drupal_add_js() directly, this function helps keep template files
|
||||
* clean and readable. It also prevents tabledrag.js from being added twice
|
||||
* accidentally.
|
||||
*
|
||||
* @param $table_id
|
||||
* String containing the target table's id attribute. If the table does not
|
||||
* have an id, one will need to be set, such as <table id="my-module-table">.
|
||||
* @param $action
|
||||
* String describing the action to be done on the form item. Either 'match' or
|
||||
* 'sort'. Match is typically used for parent relationships, sort is typically
|
||||
* used to set weights on other form elements with the same group.
|
||||
* @param $relationship
|
||||
* String describing where the $action variable should be performed. Either
|
||||
* 'parent' or 'sibling'. Parent will only look for fields up the tree.
|
||||
* Sibling will look for fields in the same group in rows above and below it.
|
||||
* @param $group
|
||||
* A class name applied on all related form elements for this action.
|
||||
* @param $subgroup
|
||||
* (optional) If the group has several subgroups within it, this string should
|
||||
* contain the class name identifying fields in the same subgroup.
|
||||
* @param $source
|
||||
* (optional) If the $action is 'match', this string should contain the class
|
||||
* name identifying what field will be used as the source value when matching
|
||||
* the value in $subgroup.
|
||||
* @param $hidden
|
||||
* (optional) The column containing the field elements may be entirely hidden
|
||||
* from view dynamically when the JavaScript is loaded. Set to FALSE if the
|
||||
* column should not be hidden.
|
||||
* @see block-admin-display-form.tpl.php
|
||||
* @see theme_menu_overview_form()
|
||||
*/
|
||||
function drupal_add_tabledrag($table_id, $action, $relationship, $group, $subgroup = NULL, $source = NULL, $hidden = TRUE) {
|
||||
static $js_added = FALSE;
|
||||
if (!$js_added) {
|
||||
drupal_add_js('misc/tabledrag.js', 'core');
|
||||
$js_added = TRUE;
|
||||
}
|
||||
|
||||
// If a subgroup or source isn't set, assume it is the same as the group.
|
||||
$target = isset($subgroup) ? $subgroup : $group;
|
||||
$source = isset($source) ? $source : $target;
|
||||
$settings['tableDrag'][$table_id][$group][] = array(
|
||||
'target' => $target,
|
||||
'source' => $source,
|
||||
'relationship' => $relationship,
|
||||
'action' => $action,
|
||||
'hidden' => $hidden,
|
||||
);
|
||||
drupal_add_js($settings, 'setting');
|
||||
}
|
||||
|
||||
/**
|
||||
* Aggregate JS files, putting them in the files directory.
|
||||
*
|
||||
|
|
Binary file not shown.
After Width: | Height: | Size: 349 B |
File diff suppressed because it is too large
Load Diff
Binary file not shown.
After Width: | Height: | Size: 976 B |
Binary file not shown.
After Width: | Height: | Size: 979 B |
|
@ -6,13 +6,14 @@
|
|||
* Default theme implementation to configure blocks.
|
||||
*
|
||||
* Available variables:
|
||||
* - $block_listing: An array of block controls within regions.
|
||||
* - $block_regions: An array of regions. Keyed by name with the title as value.
|
||||
* - $block_listing: An array of blocks keyed by region and then delta.
|
||||
* - $form_submit: Form submit button.
|
||||
* - $throttle: TRUE or FALSE depending on throttle module being enabled.
|
||||
*
|
||||
* Each $data in $block_listing contains:
|
||||
* - $data->is_region_first: TRUE or FALSE depending on the listed blocks
|
||||
* positioning. Used here to insert a region header.
|
||||
* Each $block_listing[$region] contains an array of blocks for that region.
|
||||
*
|
||||
* Each $data in $block_listing[$region] contains:
|
||||
* - $data->region_title: Region title for the listed block.
|
||||
* - $data->block_title: Block title.
|
||||
* - $data->region_select: Drop-down menu for assigning a region.
|
||||
|
@ -25,9 +26,15 @@
|
|||
* @see theme_block_admin_display()
|
||||
*/
|
||||
?>
|
||||
<?php drupal_add_js('misc/tableheader.js'); ?>
|
||||
<?php print $messages; ?>
|
||||
|
||||
<?php
|
||||
// Add table javascript.
|
||||
drupal_add_js('misc/tableheader.js');
|
||||
drupal_add_js(drupal_get_path('module', 'block') .'/block.js');
|
||||
foreach ($block_regions as $region => $title) {
|
||||
drupal_add_tabledrag('blocks', 'match', 'sibling', 'block-region-select', 'block-region-'. $region, NULL, FALSE);
|
||||
drupal_add_tabledrag('blocks', 'order', 'sibling', 'block-weight', 'block-weight-'. $region);
|
||||
}
|
||||
?>
|
||||
<table id="blocks">
|
||||
<thead>
|
||||
<tr>
|
||||
|
@ -42,15 +49,16 @@
|
|||
</thead>
|
||||
<tbody>
|
||||
<?php $row = 0; ?>
|
||||
<?php foreach ($block_listing as $data): ?>
|
||||
<?php if ($data->is_region_first): ?>
|
||||
<tr class="<?php print $row % 2 == 0 ? 'odd' : 'even'; ?>">
|
||||
<td colspan="<?php print $throttle ? '7' : '6'; ?>" class="region"><?php print $data->region_title; ?></td>
|
||||
<?php foreach ($block_regions as $region => $title): ?>
|
||||
<tr class="region region-<?php print $region?>">
|
||||
<td colspan="<?php print $throttle ? '6' : '5'; ?>" class="region"><?php print $title; ?></td>
|
||||
</tr>
|
||||
<?php $row++; ?>
|
||||
<?php endif; ?>
|
||||
<tr class="<?php print $row % 2 == 0 ? 'odd' : 'even'; ?><?php print $data->row_class ? ' '. $data->row_class : ''; ?>">
|
||||
<td class="block"><?php print $data->block_title; ?><?php print $data->block_modified ? '<span class="warning">*</span>' : ''; ?></td>
|
||||
<tr class="region-message region-<?php print $region?>-message <?php print empty($block_listing[$region]) ? 'region-empty' : 'region-populated'; ?>">
|
||||
<td colspan="<?php print $throttle ? '6' : '5'; ?>"><em><?php print t('No blocks in this region'); ?></em></td>
|
||||
</tr>
|
||||
<?php foreach ($block_listing[$region] as $delta => $data): ?>
|
||||
<tr class="draggable <?php print $row % 2 == 0 ? 'odd' : 'even'; ?><?php print $data->row_class ? ' '. $data->row_class : ''; ?>">
|
||||
<td class="block"><?php print $data->block_title; ?></td>
|
||||
<td><?php print $data->region_select; ?></td>
|
||||
<td><?php print $data->weight_select; ?></td>
|
||||
<?php if ($throttle): ?>
|
||||
|
@ -60,6 +68,7 @@
|
|||
<td><?php print $data->delete_link; ?></td>
|
||||
</tr>
|
||||
<?php $row++; ?>
|
||||
<?php endforeach; ?>
|
||||
<?php endforeach; ?>
|
||||
</tbody>
|
||||
</table>
|
||||
|
|
|
@ -1,15 +0,0 @@
|
|||
/* $Id$ */
|
||||
|
||||
#blocks td.block {
|
||||
padding-left: inherit;
|
||||
padding-right: 1.5em;
|
||||
}
|
||||
#blocks select {
|
||||
margin-left: 24px;
|
||||
}
|
||||
#blocks select.progress-disabled {
|
||||
margin-left: 0px;
|
||||
}
|
||||
#blocks .progress .bar {
|
||||
float: right;
|
||||
}
|
|
@ -36,16 +36,14 @@ function block_admin_display_form(&$form_state, $blocks, $theme = NULL) {
|
|||
init_theme();
|
||||
|
||||
$throttle = module_exists('throttle');
|
||||
$block_regions = array(BLOCK_REGION_NONE => '<'. t('none') .'>') + system_region_list($theme_key);
|
||||
$block_regions = system_region_list($theme_key) + array(BLOCK_REGION_NONE => '<'. t('none') .'>');
|
||||
|
||||
// Build form tree
|
||||
$form = array(
|
||||
'#action' => arg(3) ? url('admin/build/block/list/'. $theme_key) : url('admin/build/block'),
|
||||
'#tree' => TRUE,
|
||||
'#cache' => TRUE,
|
||||
'#prefix' => '<div id="block-admin-display-form-wrapper">',
|
||||
'#suffix' => '</div>',
|
||||
);
|
||||
|
||||
foreach ($blocks as $i => $block) {
|
||||
$key = $block['module'] .'_'. $block['delta'];
|
||||
$form[$key]['module'] = array(
|
||||
|
@ -69,7 +67,7 @@ function block_admin_display_form(&$form_state, $blocks, $theme = NULL) {
|
|||
);
|
||||
$form[$key]['region'] = array(
|
||||
'#type' => 'select',
|
||||
'#default_value' => $block['status'] ? (isset($block['region']) ? $block['region'] : system_default_region($theme_key)) : BLOCK_REGION_NONE,
|
||||
'#default_value' => $block['region'],
|
||||
'#options' => $block_regions,
|
||||
);
|
||||
|
||||
|
@ -82,20 +80,9 @@ function block_admin_display_form(&$form_state, $blocks, $theme = NULL) {
|
|||
}
|
||||
}
|
||||
|
||||
// Attach the AHAH events to the submit button. Set the AHAH selector to every
|
||||
// select element in the form. The AHAH event could be attached to every select
|
||||
// element individually, but using the selector is more efficient, especially
|
||||
// on a page where hundreds of AHAH enabled elements may be present.
|
||||
$form['submit'] = array(
|
||||
'#type' => 'submit',
|
||||
'#value' => t('Save blocks'),
|
||||
'#ahah' => array(
|
||||
'path' => 'admin/build/block/list/js/'. $theme_key,
|
||||
'selector' => '#block-admin-display-form-wrapper select',
|
||||
'wrapper' => 'block-admin-display-form-wrapper',
|
||||
'event' => 'change',
|
||||
'effect' => 'fade',
|
||||
),
|
||||
);
|
||||
|
||||
return $form;
|
||||
|
@ -114,91 +101,6 @@ function block_admin_display_form_submit($form, &$form_state) {
|
|||
cache_clear_all();
|
||||
}
|
||||
|
||||
/**
|
||||
* 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'] = !empty($_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');
|
||||
|
||||
// Create a form in the new order.
|
||||
$form_state = array('submitted' => FALSE);
|
||||
$form = block_admin_display_form($form_state, $blocks, $theme);
|
||||
|
||||
// Maintain classes set on individual blocks.
|
||||
foreach (element_children($form_cache->data) as $key) {
|
||||
if (isset($form_cache->data[$key]['#attributes'])) {
|
||||
$form[$key]['#attributes'] = $form_cache->data[$key]['#attributes'];
|
||||
}
|
||||
}
|
||||
|
||||
// Preserve the order of the new form while merging the previous data.
|
||||
$form_order = array_flip(array_keys($form)); // Save the form order.
|
||||
$form = array_merge($form_cache->data, $form); // Merge the data.
|
||||
$form = array_merge($form_order, $form); // Put back into the correct order.
|
||||
|
||||
// Add a permanent class to the changed block.
|
||||
$form[$changed_block]['#attributes']['class'] = 'block-modified';
|
||||
|
||||
cache_set('form_'. $_POST['form_build_id'], $form, 'cache_form', $form_cache->expire);
|
||||
|
||||
// Add a temporary class to mark the new AHAH content.
|
||||
$form[$changed_block]['#attributes']['class'] = empty($form[$changed_block]['#attributes']['class']) ? 'ahah-new-content' : $form[$changed_block]['#attributes']['class'] .' ahah-new-content';
|
||||
$form['js_modified'] = array(
|
||||
'#type' => 'value',
|
||||
'#value' => TRUE,
|
||||
);
|
||||
|
||||
$form['#post'] = $_POST;
|
||||
$form['#theme'] = 'block_admin_display_form';
|
||||
|
||||
// Add messages to our output.
|
||||
drupal_set_message(t('Your settings will not be saved until you click the <em>Save blocks</em> button.'), 'warning');
|
||||
|
||||
// Render the form.
|
||||
drupal_alter('form', $form, array(), 'block_admin_display_form');
|
||||
$form = form_builder('block_admin_display_form', $form, $form_state);
|
||||
|
||||
// Remove the wrapper from the form to prevent duplicate div IDs.
|
||||
unset($form['#prefix'], $form['#suffix']);
|
||||
|
||||
$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.
|
||||
*
|
||||
|
@ -206,13 +108,22 @@ function block_admin_display_js($theme = NULL) {
|
|||
* Disabled blocks are sorted by name.
|
||||
*/
|
||||
function _block_compare($a, $b) {
|
||||
$status = $b['status'] - $a['status'];
|
||||
global $theme_key;
|
||||
static $regions;
|
||||
|
||||
// We need the region list to correctly order by region.
|
||||
if (!isset($regions)) {
|
||||
$regions = array_flip(array_keys(system_region_list($theme_key)));
|
||||
$regions[BLOCK_REGION_NONE] = count($regions);
|
||||
}
|
||||
|
||||
// Separate enabled from disabled.
|
||||
$status = $b['status'] - $a['status'];
|
||||
if ($status) {
|
||||
return $status;
|
||||
}
|
||||
// Sort by region.
|
||||
$place = strcmp($a['region'], $b['region']);
|
||||
// Sort by region (in the order defined by theme .info file).
|
||||
$place = $regions[$a['region']] - $regions[$b['region']];
|
||||
if ($place) {
|
||||
return $place;
|
||||
}
|
||||
|
@ -442,14 +353,20 @@ function block_box_delete_submit($form, &$form_state) {
|
|||
function template_preprocess_block_admin_display_form(&$variables) {
|
||||
global $theme_key;
|
||||
|
||||
$variables['throttle'] = module_exists('throttle');
|
||||
$block_regions = system_region_list($theme_key);
|
||||
$variables['throttle'] = module_exists('throttle');
|
||||
$variables['block_regions'] = $block_regions + array(BLOCK_REGION_NONE => t('Disabled'));
|
||||
|
||||
// Highlight regions on page to provide visual reference.
|
||||
foreach ($block_regions as $key => $value) {
|
||||
// Highlight regions on page to provide visual reference.
|
||||
drupal_set_content($key, '<div class="block-region">'. $value .'</div>');
|
||||
// Initialize an empty array for the region.
|
||||
$variables['block_listing'][$key] = array();
|
||||
}
|
||||
|
||||
// Initialize disabled blocks array.
|
||||
$variables['block_listing'][BLOCK_REGION_NONE] = array();
|
||||
|
||||
// Setup to track previous region in loop.
|
||||
$last_region = '';
|
||||
foreach (element_children($variables['form']) as $i) {
|
||||
|
@ -460,34 +377,23 @@ function template_preprocess_block_admin_display_form(&$variables) {
|
|||
// Fetch region for current block.
|
||||
$region = $block['region']['#default_value'];
|
||||
|
||||
// Track first block listing to insert region header inside block_admin_display.tpl.php.
|
||||
$is_region_first = FALSE;
|
||||
if ($last_region != $region) {
|
||||
$is_region_first = TRUE;
|
||||
// Set region title. Block regions already translated.
|
||||
if ($region != BLOCK_REGION_NONE) {
|
||||
$region_title = drupal_ucfirst($block_regions[$region]);
|
||||
}
|
||||
else {
|
||||
$region_title = t('Disabled');
|
||||
}
|
||||
}
|
||||
// Set special classes needed for table drag and drop.
|
||||
$variables['form'][$i]['region']['#attributes']['class'] = 'block-region-select block-region-'. $region;
|
||||
$variables['form'][$i]['weight']['#attributes']['class'] = 'block-weight block-weight-'. $region;
|
||||
|
||||
$variables['block_listing'][$i]->is_region_first = $is_region_first;
|
||||
$variables['block_listing'][$i]->row_class = isset($block['#attributes']['class']) ? $block['#attributes']['class'] : '';
|
||||
$variables['block_listing'][$i]->block_modified = isset($block['#attributes']['class']) && strpos($block['#attributes']['class'], 'block-modified') !== FALSE ? TRUE : FALSE;
|
||||
$variables['block_listing'][$i]->region_title = $region_title;
|
||||
$variables['block_listing'][$i]->block_title = drupal_render($block['info']);
|
||||
$variables['block_listing'][$i]->region_select = drupal_render($block['region']) . drupal_render($block['theme']);
|
||||
$variables['block_listing'][$i]->weight_select = drupal_render($block['weight']);
|
||||
$variables['block_listing'][$i]->throttle_check = $variables['throttle'] ? drupal_render($block['throttle']) : '';
|
||||
$variables['block_listing'][$i]->configure_link = drupal_render($block['configure']);
|
||||
$variables['block_listing'][$i]->delete_link = !empty($block['delete']) ? drupal_render($block['delete']) : '';
|
||||
$variables['block_listing'][$region][$i]->row_class = isset($block['#attributes']['class']) ? $block['#attributes']['class'] : '';
|
||||
$variables['block_listing'][$region][$i]->block_modified = isset($block['#attributes']['class']) && strpos($block['#attributes']['class'], 'block-modified') !== FALSE ? TRUE : FALSE;
|
||||
$variables['block_listing'][$region][$i]->block_title = drupal_render($block['info']);
|
||||
$variables['block_listing'][$region][$i]->region_select = drupal_render($block['region']) . drupal_render($block['theme']);
|
||||
$variables['block_listing'][$region][$i]->weight_select = drupal_render($block['weight']);
|
||||
$variables['block_listing'][$region][$i]->throttle_check = $variables['throttle'] ? drupal_render($block['throttle']) : '';
|
||||
$variables['block_listing'][$region][$i]->configure_link = drupal_render($block['configure']);
|
||||
$variables['block_listing'][$region][$i]->delete_link = !empty($block['delete']) ? drupal_render($block['delete']) : '';
|
||||
$variables['block_listing'][$region][$i]->printed = FALSE;
|
||||
|
||||
$last_region = $region;
|
||||
}
|
||||
}
|
||||
|
||||
$variables['messages'] = isset($variables['form']['js_modified']) ? theme('status_messages') : '';
|
||||
$variables['form_submit'] = drupal_render($variables['form']);
|
||||
}
|
||||
|
|
|
@ -3,8 +3,12 @@
|
|||
#blocks td.region {
|
||||
font-weight: bold;
|
||||
}
|
||||
#blocks td.block {
|
||||
padding-left: 1.5em; /* LTR */
|
||||
#blocks tr.region-message {
|
||||
font-weight: normal;
|
||||
color: #999;
|
||||
}
|
||||
#blocks tr.region-populated {
|
||||
display: none;
|
||||
}
|
||||
.block-region {
|
||||
background-color: #ff6;
|
||||
|
@ -12,12 +16,3 @@
|
|||
margin-bottom: 4px;
|
||||
padding: 3px;
|
||||
}
|
||||
#blocks select {
|
||||
margin-right: 24px; /* LTR */
|
||||
}
|
||||
#blocks select.progress-disabled {
|
||||
margin-right: 0px; /* LTR */
|
||||
}
|
||||
#blocks tr.ahah-new-content {
|
||||
background-color: #ffd;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,95 @@
|
|||
// $Id $
|
||||
|
||||
/**
|
||||
* Move a block in the blocks table from one region to another via select list.
|
||||
*
|
||||
* This behavior is dependent on the tableDrag behavior, since it uses the
|
||||
* objects initialized in that behavior to update the row.
|
||||
*/
|
||||
Drupal.behaviors.blockDrag = function(context) {
|
||||
var table = $('table#blocks');
|
||||
var tableDrag = Drupal.tableDrag.blocks; // Get the blocks tableDrag object.
|
||||
|
||||
// Add a handler for when a row is swapped, update empty regions.
|
||||
tableDrag.row.prototype.onSwap = function(swappedRow) {
|
||||
checkEmptyRegions(table, this);
|
||||
};
|
||||
|
||||
// A custom message for the blocks page specifically.
|
||||
Drupal.theme.tableDragChangedWarning = function () {
|
||||
return '<div class="warning">' + Drupal.theme('tableDragChangedMarker') + ' ' + Drupal.t("The changes to these blocks will not be saved until the <em>Save blocks</em> button is clicked.") + '</div>';
|
||||
};
|
||||
|
||||
// Add a handler so when a row is dropped, update fields dropped into new regions.
|
||||
tableDrag.onDrop = function() {
|
||||
dragObject = this;
|
||||
if ($(dragObject.rowObject.element).prev('tr').is('.region-message')) {
|
||||
var regionRow = $(dragObject.rowObject.element).prev('tr').get(0);
|
||||
var regionName = regionRow.className.replace(/([^ ]+[ ]+)*region-([^ ]+)-message([ ]+[^ ]+)*/, '$2');
|
||||
var regionField = $('select.block-region-select', dragObject.rowObject.element);
|
||||
var weightField = $('select.block-weight', dragObject.rowObject.element);
|
||||
var oldRegionName = weightField[0].className.replace(/([^ ]+[ ]+)*block-weight-([^ ]+)([ ]+[^ ]+)*/, '$2');
|
||||
|
||||
if (!regionField.is('.block-region-'+ regionName)) {
|
||||
regionField.removeClass('block-region-' + oldRegionName).addClass('block-region-' + regionName);
|
||||
weightField.removeClass('block-weight-' + oldRegionName).addClass('block-weight-' + regionName);
|
||||
regionField.val(regionName);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// Add the behavior to each region select list.
|
||||
$('select.block-region-select:not(.blockregionselect-processed)', context).each(function() {
|
||||
$(this).change(function(event) {
|
||||
// Make our new row and select field.
|
||||
var row = $(this).parents('tr:first');
|
||||
var select = $(this);
|
||||
tableDrag.rowObject = new tableDrag.row(row);
|
||||
|
||||
// Find the correct region and insert the row as the first in the region.
|
||||
$('tr.region-message', table).each(function() {
|
||||
if ($(this).is('.region-' + select[0].value + '-message')) {
|
||||
// Add the new row and remove the old one.
|
||||
$(this).after(row);
|
||||
// Manually update weights and restripe.
|
||||
tableDrag.updateFields(row.get(0));
|
||||
tableDrag.rowObject.changed = true;
|
||||
if (tableDrag.oldRowElement) {
|
||||
$(tableDrag.oldRowElement).removeClass('drag-previous');
|
||||
}
|
||||
tableDrag.oldRowElement = row.get(0);
|
||||
tableDrag.restripeTable();
|
||||
tableDrag.rowObject.markChanged();
|
||||
tableDrag.oldRowElement = row;
|
||||
$(row).addClass('drag-previous');
|
||||
}
|
||||
});
|
||||
|
||||
// Modify empty regions with added or removed fields.
|
||||
checkEmptyRegions(table, row);
|
||||
// Remove focus from selectbox.
|
||||
select.get(0).blur();
|
||||
});
|
||||
$(this).addClass('blockregionselect-processed');
|
||||
});
|
||||
|
||||
var checkEmptyRegions = function(table, rowObject) {
|
||||
$('tr.region-message', table).each(function() {
|
||||
// If the dragged row is in this region, but above the message row, swap it down one space.
|
||||
if ($(this).prev('tr').get(0) == rowObject.element) {
|
||||
// Prevent a recursion problem when using the keyboard to move rows up.
|
||||
if ((rowObject.method != 'keyboard' || rowObject.direction == 'down')) {
|
||||
rowObject.swap('after', this);
|
||||
}
|
||||
}
|
||||
// This region has become empty
|
||||
if ($(this).next('tr').is(':not(.draggable)') || $(this).next('tr').size() == 0) {
|
||||
$(this).removeClass('region-populated').addClass('region-empty');
|
||||
}
|
||||
// This region has become populated.
|
||||
else if ($(this).is('.region-empty')) {
|
||||
$(this).removeClass('region-empty').addClass('region-populated');
|
||||
}
|
||||
});
|
||||
};
|
||||
};
|
|
@ -248,6 +248,9 @@ function _block_rehash() {
|
|||
}
|
||||
// Add defaults and save it into the database.
|
||||
drupal_write_record('blocks', $block);
|
||||
// Set region to none if not enabled.
|
||||
$block['region'] = $block['status'] ? $block['region'] : BLOCK_REGION_NONE;
|
||||
// Add to the list of blocks we return.
|
||||
$blocks[] = $block;
|
||||
}
|
||||
else {
|
||||
|
@ -257,7 +260,9 @@ function _block_rehash() {
|
|||
// do not need to update the database here.
|
||||
// Add 'info' to this block.
|
||||
$old_blocks[$module][$delta]['info'] = $block['info'];
|
||||
// Add this block to the list of blocks we return
|
||||
// Set region to none if not enabled.
|
||||
$old_blocks[$module][$delta]['region'] = $old_blocks[$module][$delta]['status'] ? $old_blocks[$module][$delta]['region'] : BLOCK_REGION_NONE;
|
||||
// Add this block to the list of blocks we return.
|
||||
$blocks[] = $old_blocks[$module][$delta];
|
||||
// Remove this block from the list of blocks to be deleted.
|
||||
unset($old_blocks[$module][$delta]);
|
||||
|
|
|
@ -3,6 +3,9 @@
|
|||
/*
|
||||
** HTML elements
|
||||
*/
|
||||
body.drag {
|
||||
cursor: move;
|
||||
}
|
||||
th.active img {
|
||||
display: inline;
|
||||
}
|
||||
|
@ -11,6 +14,12 @@ tr.even, tr.odd {
|
|||
border-bottom: 1px solid #ccc;
|
||||
padding: 0.1em 0.6em;
|
||||
}
|
||||
tr.drag {
|
||||
background-color: #fffff0;
|
||||
}
|
||||
tr.drag-previous {
|
||||
background-color: #ffd;
|
||||
}
|
||||
td.active {
|
||||
background-color: #ddd;
|
||||
}
|
||||
|
@ -32,6 +41,21 @@ thead th {
|
|||
.breadcrumb {
|
||||
padding-bottom: .5em
|
||||
}
|
||||
div.indentation {
|
||||
width: 20px;
|
||||
margin: -0.4em 0.2em -0.4em -0.4em;
|
||||
padding: 0.4em 0 0.4em 0.6em;
|
||||
float: left;
|
||||
}
|
||||
div.tree-child {
|
||||
background: url(../../misc/tree.png) no-repeat 11px center;
|
||||
}
|
||||
div.tree-child-last {
|
||||
background: url(../../misc/tree-bottom.png) no-repeat 11px center;
|
||||
}
|
||||
div.tree-child-horizontal {
|
||||
background: url(../../misc/tree.png) no-repeat -11px center;
|
||||
}
|
||||
.error {
|
||||
color: #e55;
|
||||
}
|
||||
|
@ -333,6 +357,30 @@ html.js .resizable-textarea textarea {
|
|||
display: block;
|
||||
}
|
||||
|
||||
/*
|
||||
** Table drag and drop.
|
||||
*/
|
||||
a.tabledrag-handle {
|
||||
cursor: move;
|
||||
float: left;
|
||||
height: 1.7em;
|
||||
margin: -0.42em 0 -0.42em -0.5em;
|
||||
padding: 0.42em 1.5em 0.42em 0.5em;
|
||||
text-decoration: none;
|
||||
}
|
||||
a.tabledrag-handle:hover {
|
||||
text-decoration: none;
|
||||
}
|
||||
a.tabledrag-handle .handle {
|
||||
margin-top: 4px;
|
||||
height: 13px;
|
||||
width: 13px;
|
||||
background: url(../../misc/draggable.png) no-repeat 0 0;
|
||||
}
|
||||
a.tabledrag-handle-hover .handle {
|
||||
background-position: 0 -20px;
|
||||
}
|
||||
|
||||
/*
|
||||
** Teaser splitter
|
||||
*/
|
||||
|
|
|
@ -226,6 +226,14 @@ tr.even {
|
|||
background-color: #fff;
|
||||
}
|
||||
|
||||
tr.drag {
|
||||
background-color: #fffff0;
|
||||
}
|
||||
|
||||
tr.drag-previous {
|
||||
background-color: #ffd;
|
||||
}
|
||||
|
||||
tr.odd td.active {
|
||||
background-color: #ddecf5;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue