Problem/Motivation
Using nested paragraphs we ran into the the issue that the weights were calculated wrong, after drag and dropping a paragraph that contained other paragraphs. What was wrong about the weights was, that they had the same values.
This occurred because of
first, how the updateField behavior in tabledrag.js is handling ordering, assigning the max value when running out of values
case 'order':
{
var siblings = this.rowObject.findSiblings(rowSettings);
if ($(targetElement).is('select')) {
var values = [];
$(targetElement).find('option').each(function () {
values.push(this.value);
});
// only takes into account the values count on one level
var maxVal = values[values.length - 1];
// targetClass is field_name-delta-order and this function takes into account all values on every level
$(siblings).find(targetClass).each(function () {
if (values.length > 0) {
this.value = values.shift();
} else {
this.value = maxVal;
}
});
and second, of how the order class is set in theme.inc inside the template_preprocess_field_multiple_value_form function
function template_preprocess_field_multiple_value_form(&$variables) {
$element = $variables['element'];
$variables['multiple'] = $element['#cardinality_multiple'];
$variables['attributes'] = $element['#attributes'];
if ($variables['multiple']) {
$table_id = Html::getUniqueId($element['#field_name'] . '_values');
// setting it up like doesn't take into account that multiple values on the same content could have the same field name
$order_class = $element['#field_name'] . '-delta-order';
this leaves room for same name order errors, because we choose a popular name like 'field_body' for a paragraph field that contained other paragraphs.
Proposed resolution
Assigning a unique name to the order class using the unique table id instead of the field_name only, like
if ($variables['multiple']) {
$table_id = Html::getUniqueId($element['#field_name'] . '_values');
$order_class = table_id . '-delta-order';
The reason behind this approach is that the table id already contains the field_name and also adds a unique part if the content is already on the view.
Remaining tasks
Is this a good approach or have I missed something similar in the issue queue?