From 438bf6178ef7af36c63ef8dd039efe76e7c6cd75 Mon Sep 17 00:00:00 2001 From: Vy Hoang Date: Wed, 24 May 2017 19:44:54 +1000 Subject: [PATCH] fixing issue double biding Signed-off-by: Vy Hoang --- core/includes/theme.inc | 27 +++++++++++------- core/lib/Drupal/Core/Field/WidgetBase.php | 31 +++++++++++++++++++- core/misc/form.js | 45 ++++++++++++++++++++++++++++++ core/themes/classy/css/components/form.css | 3 ++ 4 files changed, 95 insertions(+), 11 deletions(-) diff --git a/core/includes/theme.inc b/core/includes/theme.inc index 9b89250fc9..94193284b2 100644 --- a/core/includes/theme.inc +++ b/core/includes/theme.inc @@ -1609,6 +1609,7 @@ function template_preprocess_field_multiple_value_form(&$variables) { 'class' => array('field-label'), ), t('Order', array(), array('context' => 'Sort order')), + t('Operations'), ); $rows = array(); @@ -1630,19 +1631,25 @@ function template_preprocess_field_multiple_value_form(&$variables) { foreach ($items as $item) { $item['_weight']['#attributes']['class'] = array($order_class); - // Remove weight form element from item render array so it can be rendered - // in a separate table column. + // Remove weight and remove form element from item render array so they + // can be rendered in a separate table columns. $delta_element = $item['_weight']; - unset($item['_weight']); - - $cells = array( - array('data' => '', 'class' => array('field-multiple-drag')), - array('data' => $item), - array('data' => $delta_element, 'class' => array('delta-order')), - ); + isset($item['_remove']) ? $remove_element = $item['_remove'] : $remove_element = ''; + unset($item['_weight'], $item['_remove']); + + $cells = [ + ['data' => '', 'class' => ['field-multiple-drag']], + ['data' => $item], + ['data' => $delta_element, 'class' => ['delta-order']], + ['data' => $remove_element, 'class' => ['delta-remove']], + ]; + $class = ['draggable']; + if (!empty($remove_element['check']['#checked'])) { + $class[] = 'removed'; + } $rows[] = array( 'data' => $cells, - 'class' => array('draggable'), + 'class' => $class, ); } diff --git a/core/lib/Drupal/Core/Field/WidgetBase.php b/core/lib/Drupal/Core/Field/WidgetBase.php index 3d0db4ce44..94df280ad7 100644 --- a/core/lib/Drupal/Core/Field/WidgetBase.php +++ b/core/lib/Drupal/Core/Field/WidgetBase.php @@ -202,6 +202,28 @@ protected function formMultipleElements(FieldItemListInterface $items, array &$f '#default_value' => $items[$delta]->_weight ?: $delta, '#weight' => 100, ); + + if ($delta != $max) { + foreach (Element::children($element) as $key) { + $element[$key]['#states'] = [ + 'disabled' => [ + ':input[name="' . $field_name . '[' . $delta . '][_remove][check]"]' => ['checked' => TRUE], + ], + ]; + } + $element['_remove']['check'] = [ + '#title' => $this->t('Remove'), + '#title_display' => 'invisible', + '#type' => 'checkbox', + '#attributes' => ['class' => ['hidden']], + '#weight' => 101, + ]; + $element['_remove']['button'] = [ + '#type' => 'button', + '#value' => t('Remove'), + '#weight' => 102, + ]; + } } $elements[$delta] = $element; @@ -355,6 +377,13 @@ public function extractFormValues(FieldItemListInterface $items, array $form, Fo // Remove the 'value' of the 'add more' button. unset($values['add_more']); + // Filter out removed items. + foreach ($values as $delta => $value) { + if (!empty($value['_remove']['check'])) { + unset($values[$delta]); + } + } + // The original delta, before drag-and-drop reordering, is needed to // route errors to the correct form element. foreach ($values as $delta => &$value) { @@ -377,7 +406,7 @@ public function extractFormValues(FieldItemListInterface $items, array $form, Fo $field_state = static::getWidgetState($form['#parents'], $field_name, $form_state); foreach ($items as $delta => $item) { $field_state['original_deltas'][$delta] = isset($item->_original_delta) ? $item->_original_delta : $delta; - unset($item->_original_delta, $item->_weight); + unset($item->_original_delta, $item->_weight, $item->_remove); } static::setWidgetState($form['#parents'], $field_name, $form_state, $field_state); } diff --git a/core/misc/form.js b/core/misc/form.js index 7ca64fc425..a1032d309e 100644 --- a/core/misc/form.js +++ b/core/misc/form.js @@ -247,4 +247,49 @@ } }; + /** + * Initialize value remove checkboxes. + * + * @type {Drupal~behavior} + * + * @prop {Drupal~behaviorAttach} attach + * Attaches multipleRemove functionality. + */ + Drupal.behaviors.multipleRemove = { + attach: function (context, settings) { + $(context).find('table.field-multiple-table').once('multiple-remove').each(Drupal.multipleRemove); + } + }; + + /** + * Callback used in {@link Drupal.behaviors.multipleRemove}. + */ + Drupal.multipleRemove = function () { + if ($(this).find('td.delta-remove input[type="checkbox"]').length === 0) { + return; + } + + // Keep track of the table, which checkbox is checked and alias the + // settings. + var table = this; + var $table = $(table); + + // For each of the remove buttons within the table. + $table.find('td.delta-remove input[type="submit"]').off('click').on('click', function (e) { + // Either add or remove the removed class based on the state of the + // hidden remove checkbox. + + /** + * @this {HTMLElement} + */ + var $checkbox = $(this).closest('td').find('input[type="checkbox"]'); + var state = $checkbox.prop('checked'); + // Toggle hidden checkbox. + $checkbox.prop('checked', !state); + $checkbox.closest('tr').toggleClass('removed', !state); + + return false; + }); + }; + })(jQuery, Drupal, Drupal.debounce); diff --git a/core/themes/classy/css/components/form.css b/core/themes/classy/css/components/form.css index 15b8ec23c2..78c4323f4e 100644 --- a/core/themes/classy/css/components/form.css +++ b/core/themes/classy/css/components/form.css @@ -6,6 +6,9 @@ form .field-multiple-table { margin: 0; } +form .field-multiple-table tr.removed { + display: none; +} form .field-multiple-table .field-multiple-drag { width: 30px; padding-right: 0; /*LTR*/ -- 2.11.0 (Apple Git-81)