core/includes/common.inc | 161 +++++++------------- core/includes/theme.inc | 25 +-- core/misc/tabledrag.js | 6 +- core/modules/book/book.admin.inc | 44 +++--- core/modules/field/field.form.inc | 17 +-- .../lib/Drupal/field_ui/DisplayOverviewBase.php | 34 ++--- .../field_ui/lib/Drupal/field_ui/OverviewBase.php | 20 ++- core/modules/file/file.field.inc | 18 +-- core/modules/image/image.admin.inc | 14 +- core/modules/language/language.admin.inc | 16 +- core/modules/menu/menu.admin.inc | 36 +++-- core/modules/system/system.module | 8 +- 12 files changed, 181 insertions(+), 218 deletions(-) diff --git a/core/includes/common.inc b/core/includes/common.inc index bee6085..7d997b1 100644 --- a/core/includes/common.inc +++ b/core/includes/common.inc @@ -2800,7 +2800,7 @@ function drupal_get_library($module, $name = NULL) { } /** - * Assists in adding the tableDrag JavaScript behavior to a themed table. + * Assists in attaching 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 @@ -2839,9 +2839,13 @@ function drupal_get_library($module, $name = NULL) { * - Rows with the 'tabledrag-leaf' class cannot have child rows. * - Rows with the 'tabledrag-root' class cannot be nested under a parent row. * - * Calling drupal_add_tabledrag() would then be written as such: + * Calling drupal_attach_tabledrag() would then be written as such: * @code - * drupal_add_tabledrag('my-module-table', 'order', 'sibling', 'my-elements-weight'); + * drupal_attach_tabledrag('my-module-table', array( + * 'action' => 'order', + * 'relationship' => 'sibling', + * 'group' => 'my-elements-weight', + * ); * @endcode * * In a more complex case where there are several groups in one column (such as @@ -2851,13 +2855,19 @@ function drupal_get_library($module, $name = NULL) { * $form['my_elements'][$region][$delta]['weight']['#attributes']['class'] = array('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. + * The 'group' option is still 'my-element-weight', and the additional + * 'subgroup' option will be passed in as 'my-elements-weight-' . $region. This + * also means that you'll need to call drupal_attach_tabledrag() once for every + * region added. * * @code * foreach ($regions as $region) { - * drupal_add_tabledrag('my-module-table', 'order', 'sibling', 'my-elements-weight', 'my-elements-weight-' . $region); + * drupal_attach_tabledrag('my-module-table', array( + * 'action' => 'order', + * 'relationship' => sibling', + * 'group' => 'my-elements-weight', + * 'subgroup' => my-elements-weight-' . $region, + * )); * } * @endcode * @@ -2867,114 +2877,51 @@ function drupal_get_library($module, $name = NULL) { * theme_menu_overview_form() for an example creating a table containing parent * relationships. * - * Note that this function should be called from the theme layer, such as in a - * .html.twig file, theme_ function, or in a template_preprocess function, not - * in a form declaration. 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 . - * @param $action - * String describing the action to be done on the form item. Either 'match' - * 'depth', or 'order'. Match is typically used for parent relationships. - * Order is typically used to set weights on other form elements with the same - * group. Depth updates the target element with the current indentation. - * @param $relationship - * String describing where the $action variable should be performed. Either - * 'parent', 'sibling', 'group', or 'self'. Parent will only look for fields - * up the tree. Sibling will look for fields in the same group in rows above - * and below it. Self affects the dragged row itself. Group affects the - * dragged row, plus any children below it (the entire dragged group). - * @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. - * @param $limit - * (optional) Limit the maximum amount of parenting in this table. - * @see theme_menu_overview_form() - */ -function drupal_add_tabledrag($table_id, $action, $relationship, $group, $subgroup = NULL, $source = NULL, $hidden = TRUE, $limit = 0) { - $js_added = &drupal_static(__FUNCTION__, FALSE); - $tabledrag_id = &drupal_static(__FUNCTION__ . '_setting', FALSE); - $tabledrag_id = (!isset($tabledrag_id)) ? 0 : $tabledrag_id + 1; - - if (!$js_added) { - // Add the table drag JavaScript to the page before the module JavaScript - // to ensure that table drag behaviors are registered before any module - // uses it. - drupal_add_library('system', 'drupal.tabledrag'); - $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][$tabledrag_id] = array( - 'target' => $target, - 'source' => $source, - 'relationship' => $relationship, - 'action' => $action, - 'hidden' => $hidden, - 'limit' => $limit, - ); - drupal_add_js($settings, 'setting'); -} - -/** - * Assists in attaching the tableDrag JavaScript behavior to a themed table. - * - * * @param $element - * A form element to attach the tableDrag. - * + * A form element to attach the tableDrag behavior to. * @param array $options - * An associative array containing: - * - table_id: String containing the target table's id attribute. + * These options are used to generate JavaScript settings necessary to + * configure the tableDrag behavior appropriately for this particular table. + * An associative array containing the following keys: + * - '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
. - * - action: String describing the action to be done on the form item. Either - * 'match' 'depth', or 'order'. Match is typically used for parent - * relationships. Order is typically used to set weights on other form - * elements with the same group. Depth updates the target element - * with the current indentation. - * - relationship: String describing where the $action variable - * should be performed. Either 'parent', 'sibling', 'group', or 'self'. - * Parent will only look for fields up the tree. Sibling will look for - * fields in the same group in rows above and below it. - * Self affects the dragged row itself. Group affects the dragged row, - * plus any children below it (the entire dragged group). - * - group: A class name applied on all related form elements for this action. - * - subgroup: (optional) If the group has several subgroups within it, - * this string should contain the class name identifying fields - * in the same subgroup. - * - source: (optional) If the $action is 'match', this string should - * contain the classname identifying what field will be used as the source - * value when matching the value in $subgroup. - * - 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. - * - limit: (optional) Limit the maximum amount of parenting in this table. + * - 'action': String describing the action to be done on the form item. + * Either 'match' 'depth', or 'order': + * - 'match' is typically used for parent relationships. + * - 'order' is typically used to set weights on other form elements with + * the same group. + * - 'depth' updates the target element with the current indentation. + * - 'relationship': String describing where the "action" option + * should be performed. Either 'parent', 'sibling', 'group', or 'self': + * - 'parent' will only look for fields up the tree. + * - 'sibling' will look for fields in the same group in rows above and + * below it. + * - 'self' affects the dragged row itself. + * - 'group' affects the dragged row, plus any children below it (the entire + * dragged group). + * - 'group': A class name applied on all related form elements for this action. + * - 'subgroup': (optional) If the group has several subgroups within it, this + * string should contain the class name identifying fields in the same + * subgroup. + * - 'source': (optional) If the $action is 'match', this string should contain + * the classname identifying what field will be used as the source value + * when matching the value in $subgroup. + * - '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. + * - 'limit': (optional) Limit the maximum amount of parenting in this table. + * + * @see theme_menu_overview_form() */ function drupal_attach_tabledrag(&$element, array $options) { // Add default values to elements. $options = $options + array( - 'subgroup' => NULL, - 'source' => NULL, - 'hidden' => TRUE, - 'limit' => 0 - ); + 'subgroup' => NULL, + 'source' => NULL, + 'hidden' => TRUE, + 'limit' => 0 + ); $group = $options['group']; diff --git a/core/includes/theme.inc b/core/includes/theme.inc index d25e730..629f866 100644 --- a/core/includes/theme.inc +++ b/core/includes/theme.inc @@ -1372,7 +1372,11 @@ function theme_image($variables) { * '#header' => array(t('Title'), array('data' => t('Operations'), 'colspan' => '1')), * // Optionally, to add tableDrag support: * '#tabledrag' => array( - * array('order', 'sibling', 'thing-weight'), + * array( + * 'action' => 'order', + * 'relationship' => 'sibling', + * 'group' => 'thing-weight', + * ), * ), * ); * foreach ($things as $row => $thing) { @@ -1406,14 +1410,14 @@ function theme_image($variables) { * * @param array $element * A structured array containing two sub-levels of elements. Properties used: - * - #tabledrag: The value is a list of arrays that are passed to - * drupal_add_tabledrag(). The HTML ID of the table is prepended to each set - * of arguments. + * - #tabledrag: The value is a list of $options arrays that are passed to + * drupal_attach_tabledrag(). The HTML ID of the table is added to each + * $options array. * * @see system_element_info() * @see theme_table() * @see drupal_process_attached() - * @see drupal_add_tabledrag() + * @see drupal_attach_tabledrag() */ function drupal_pre_render_table(array $element) { foreach (element_children($element) as $first) { @@ -1444,14 +1448,13 @@ function drupal_pre_render_table(array $element) { // Take over $element['#id'] as HTML ID attribute, if not already set. element_set_attributes($element, array('id')); - // If the custom #tabledrag is set and there is a HTML ID, inject the table's - // HTML ID as first callback argument and attach the behavior. + // If the custom #tabledrag is set and there is a HTML ID, add the table's + // HTML ID to the options and attach the behavior. if (!empty($element['#tabledrag']) && isset($element['#attributes']['id'])) { - foreach ($element['#tabledrag'] as &$args) { - $args['table_id'] = $element['#attributes']['id']; - drupal_attach_tabledrag($element, $args); + foreach ($element['#tabledrag'] as $options) { + $options['table_id'] = $element['#attributes']['id']; + drupal_attach_tabledrag($element, $options); } - } return $element; diff --git a/core/misc/tabledrag.js b/core/misc/tabledrag.js index f8dc614..ae2dec0 100644 --- a/core/misc/tabledrag.js +++ b/core/misc/tabledrag.js @@ -11,9 +11,9 @@ var showWeight = JSON.parse(localStorage.getItem('Drupal.tableDrag.showWeight')) /** * Drag and drop table rows with field manipulation. * - * Using the drupal_add_tabledrag() function, any table with weights or parent - * relationships may be made into draggable tables. Columns containing a field - * may optionally be hidden, providing a better user experience. + * Using the drupal_attach_tabledrag() function, any table with weights or + * parent relationships may be made into draggable tables. Columns containing a + * field may optionally be hidden, providing a better user experience. * * Created tableDrag instances may be modified with custom behaviors by * overriding the .onDrag, .onDrop, .row.onSwap, and .row.onIndent methods. diff --git a/core/modules/book/book.admin.inc b/core/modules/book/book.admin.inc index d207490..f74c196 100644 --- a/core/modules/book/book.admin.inc +++ b/core/modules/book/book.admin.inc @@ -22,26 +22,6 @@ function theme_book_admin_table($variables) { $form = $variables['form']; - $match_options = array( - 'table_id' => 'book-outline', - 'action' => 'match', - 'relationship' => 'parent', - 'group' => 'book-plid', - 'subgroup' => 'book-plid', - 'source' => 'book-mlid', - 'hidden' => TRUE, - 'limit' => MENU_MAX_DEPTH - 2, - ); - $order_options = array( - 'table_id' => 'book-outline', - 'action' => 'order', - 'relationship' => 'sibling', - 'group' => 'book-weight', - ); - - drupal_attach_tabledrag($form, $match_options); - drupal_attach_tabledrag($form, $order_options); - $header = array(t('Title'), t('Weight'), t('Parent'), t('Operations')); $rows = array(); @@ -94,6 +74,28 @@ function theme_book_admin_table($variables) { $row['class'][] = 'draggable'; $rows[] = $row; } - $table = array('#theme' => 'table', '#header' => $header, '#rows' => $rows, '#attributes' => array('id' => 'book-outline'), '#empty' => t('No book content available.')); + $table = array( + '#type' => 'table', + '#header' => $header, + '#rows' => $rows, + '#attributes' => array('id' => 'book-outline'), + '#empty' => t('No book content available.'), + '#tabledrag' => array( + array( + 'action' => 'match', + 'relationship' => 'parent', + 'group' => 'book-plid', + 'subgroup' => 'book-plid', + 'source' => 'book-mlid', + 'hidden' => TRUE, + 'limit' => MENU_MAX_DEPTH - 2, + ), + array( + 'action' => 'order', + 'relationship' => 'sibling', + 'group' => 'book-weight', + ), + ), + ); return drupal_render($table); } diff --git a/core/modules/field/field.form.inc b/core/modules/field/field.form.inc index 382beda..c7c2e05 100644 --- a/core/modules/field/field.form.inc +++ b/core/modules/field/field.form.inc @@ -70,22 +70,21 @@ function theme_field_multiple_value_form($variables) { } $table = array( - '#theme' => 'table', + '#type' => 'table', '#header' => $header, '#rows' => $rows, '#attributes' => array( 'id' => $table_id, 'class' => array('field-multiple-table'), ), + '#tabledrag' => array( + array( + 'action' => 'order', + 'relationship' => 'sibling', + 'group' => $order_class, + ), + ), ); - - $options = array( - 'table_id' => $table_id, - 'action' => 'order', - 'relationship' => 'sibling', - 'group' => $order_class, - ); - drupal_attach_tabledrag($table, $options); $output = '
'; $output .= drupal_render($table); $output .= $element['#description'] ? '
' . $element['#description'] . '
' : ''; diff --git a/core/modules/field_ui/lib/Drupal/field_ui/DisplayOverviewBase.php b/core/modules/field_ui/lib/Drupal/field_ui/DisplayOverviewBase.php index e137f9a..f375ef9 100644 --- a/core/modules/field_ui/lib/Drupal/field_ui/DisplayOverviewBase.php +++ b/core/modules/field_ui/lib/Drupal/field_ui/DisplayOverviewBase.php @@ -124,6 +124,22 @@ public function buildForm(array $form, array &$form_state, $entity_type = NULL, // Add Ajax wrapper. '#prefix' => '
', '#suffix' => '
', + '#tabledrag' => array( + array( + 'table_id' => $table_id, + 'action' => 'order', + 'relationship' => 'sibling', + 'group' => 'field-weight', + ), + array( + 'table_id' => $table_id, + 'action' => 'match', + 'relationship' => 'parent', + 'group' => 'field-parent', + 'subgroup' => 'field-parent', + 'source' => 'field-name', + ), + ), ); // Field rows. @@ -195,24 +211,6 @@ public function buildForm(array $form, array &$form_state, $entity_type = NULL, $form['#attached']['library'][] = array('field_ui', 'drupal.field_ui'); - // Add tabledrag behavior. - $order_options = array( - 'table_id' => 'field-display-overview', - 'action' => 'order', - 'relationship' => 'sibling', - 'group' => 'field-weight', - ); - $match_options = array( - 'table_id' => 'field-display-overview', - 'action' => 'match', - 'relationship' => 'parent', - 'group' => 'field-parent', - 'subgroup' => 'field-parent', - 'source' => 'field-name', - ); - drupal_attach_tabledrag($form, $order_options); - drupal_attach_tabledrag($form, $match_options); - return $form; } diff --git a/core/modules/field_ui/lib/Drupal/field_ui/OverviewBase.php b/core/modules/field_ui/lib/Drupal/field_ui/OverviewBase.php index aad6599..272d807 100644 --- a/core/modules/field_ui/lib/Drupal/field_ui/OverviewBase.php +++ b/core/modules/field_ui/lib/Drupal/field_ui/OverviewBase.php @@ -136,7 +136,15 @@ public function getRegionOptions() { * This function is assigned as a #pre_render callback in * field_ui_element_info(). * - * @see drupal_render(). + * @param array $element + * A structured array containing two sub-levels of elements. Properties + * used: + * - #tabledrag: The value is a list of $options arrays that are passed to + * drupal_attach_tabledrag(). The HTML ID of the table is added to each + * $options array. + * + * @see drupal_render() + * @see drupal_pre_render_table() */ public function tablePreRender($elements) { $js_settings = array(); @@ -207,6 +215,16 @@ public function tablePreRender($elements) { 'data' => array('fieldUIRowsData' => $js_settings), ); + // If the custom #tabledrag is set and there is a HTML ID, add the table's + // HTML ID to the options and attach the behavior. + // @see drupal_pre_render_table() + if (!empty($elements['#tabledrag']) && isset($elements['#attributes']['id'])) { + foreach ($elements['#tabledrag'] as $options) { + $options['table_id'] = $elements['#attributes']['id']; + drupal_attach_tabledrag($elements, $options); + } + } + return $elements; } diff --git a/core/modules/file/file.field.inc b/core/modules/file/file.field.inc index 73c9dc7..dee5b4e 100644 --- a/core/modules/file/file.field.inc +++ b/core/modules/file/file.field.inc @@ -413,24 +413,22 @@ function theme_file_widget_multiple($variables) { ); } - $build = array( - '#theme' => 'table', + '#type' => 'table', '#header' => $headers, '#rows' => $rows, '#attributes' => array( 'id' => $table_id, ), + '#tabledrag' => array( + array( + 'action' => 'order', + 'relationship' => 'sibling', + 'group' => $weight_class, + ), + ), ); - $options = array( - 'table_id' => $table_id, - 'action' => 'order', - 'relationship' => 'sibling', - 'group' => $weight_class, - ); - drupal_attach_tabledrag($build, $options); - $output = empty($rows) ? '' : drupal_render($build); $output .= drupal_render_children($element); return $output; diff --git a/core/modules/image/image.admin.inc b/core/modules/image/image.admin.inc index d3246f6..1d13ba8 100644 --- a/core/modules/image/image.admin.inc +++ b/core/modules/image/image.admin.inc @@ -58,14 +58,14 @@ function theme_image_style_effects($variables) { '#header' => $header, '#rows' => $rows, '#attributes' => array('id' => 'image-style-effects'), + '#tabledrag' => array( + array( + 'action' => 'order', + 'relationship' => 'sibling', + 'group' => 'image-effect-order-weight', + ), + ), ); - $options = array( - 'table_id' => 'image-style-effects', - 'action' => 'order', - 'relationship' => 'sibling', - 'group' => 'image-effect-order-weight', - ); - drupal_attach_tabledrag($table, $options); return drupal_render($table); } diff --git a/core/modules/language/language.admin.inc b/core/modules/language/language.admin.inc index 97ed1c2..f02d7bd 100644 --- a/core/modules/language/language.admin.inc +++ b/core/modules/language/language.admin.inc @@ -214,18 +214,18 @@ function theme_language_negotiation_configure_form($variables) { } $build = array( - '#theme' => 'table', + '#type' => 'table', '#header' => $header, '#rows' => $rows, '#attributes' => array('id' => "language-negotiation-methods-$type"), + '#tabledrag' => array( + array( + 'action' => 'order', + 'relationship' => 'sibling', + 'group' => "language-method-weight-$type", + ), + ), ); - $options = array( - 'table_id' => "language-negotiation-methods-$type", - 'action' => 'order', - 'relationship' => 'sibling', - 'group' => "language-method-weight-$type", - ); - drupal_attach_tabledrag($build, $options); $table = drupal_render($form[$type]['configurable']); $table .= drupal_render($build); diff --git a/core/modules/menu/menu.admin.inc b/core/modules/menu/menu.admin.inc index d34f71e..57bba6d 100644 --- a/core/modules/menu/menu.admin.inc +++ b/core/modules/menu/menu.admin.inc @@ -59,31 +59,29 @@ function theme_menu_overview_form($variables) { } $table = array( - '#theme' => 'table', + '#type' => 'table', '#header' => $header, '#rows' => $rows, '#attributes' => array( 'id' => 'menu-overview', ), + '#tabledrag' => array( + array( + 'action' => 'match', + 'relationship' => 'parent', + 'group' => 'menu-plid', + 'subgroup' => 'menu-plid', + 'source' => 'menu-mlid', + 'hidden' => TRUE, + 'limit' => MENU_MAX_DEPTH - 1, + ), + array( + 'action' => 'order', + 'relationship' => 'sibling', + 'group' => 'menu-weight', + ), + ), ); - $match_options = array( - 'table_id' => 'book-outline', - 'action' => 'match', - 'relationship' => 'parent', - 'group' => 'menu-plid', - 'subgroup' => 'menu-plid', - 'source' => 'menu-mlid', - 'hidden' => TRUE, - 'limit' => MENU_MAX_DEPTH - 1, - ); - $order_options = array( - 'table_id' => 'book-outline', - 'action' => 'order', - 'relationship' => 'sibling', - 'group' => 'menu-weight', - ); - drupal_attach_tabledrag($table, $match_options); - drupal_attach_tabledrag($table, $order_options); $output .= drupal_render($form['inline_actions']); $output .= drupal_render($table); diff --git a/core/modules/system/system.module b/core/modules/system/system.module index c0b0f02..6ebe406 100644 --- a/core/modules/system/system.module +++ b/core/modules/system/system.module @@ -586,10 +586,10 @@ function system_element_info() { '#process' => array('form_process_table'), '#element_validate' => array('form_validate_table'), // Properties for tabledrag support. - // The value is a list of arrays that are passed to drupal_add_tabledrag(). - // drupal_pre_render_table() prepends the HTML ID of the table to each set - // of arguments. - // @see drupal_add_tabledrag() + // The value is a list of arrays that are passed to + // drupal_attach_tabledrag(). drupal_pre_render_table() prepends the HTML ID + // of the table to each set of options. + // @see drupal_attach_tabledrag() '#tabledrag' => array(), // Render properties. '#pre_render' => array('drupal_pre_render_table'),