Problem/Motivation
By default, the tabledrag weights only range from -10 to 10, which means menus with 21 or more items can't always be sorted correctly.
Steps to reproduce
Make more than 21 sub-pages on a menu (I suggest easy-to-see sample menu titles like A-Z). Use the "Reorder menu" tab to sort them in reverse-alphanumeric order (I discovered this issue in an archive section where I wanted to sort the most recent years to the top, and oldest to the bottom).
The first 20 items will stay sorted as you like (in our case, newest-to-oldest), but anything beyond that will share a weight value (10) and will resort to alphanumeric sorting (oldest-to-newest).
Proposed resolution
A solution like the one on
Rules weights drag-n-drop don't work with more than 10 actions β
will work. On src/Form/ReorderMenuForm.php:
if ($menu_link_id != "") {
foreach ($menu['#items'] as $item) {
+ $count = count($item['below']);
foreach ($item['below'] as $menu_val) {
// Load the node for the current child menu item in the loop.
$nid = Node::load($menu_val['url']->getRouteParameters()['node']);
// Check the node is published
// If it isn't published add a message next to the title
// on the display to say its unpublished.
$isPublished = $nid->status->value;
if ($isPublished) {
$title = $menu_val['title'];
}
else {
$title = $menu_val['title'] . ' (UNPUBLISHED)';
}
// Set the current child menu items menu link id.
$mlid = $menu_val['original_link']->getPluginDefinition()['metadata']['entity_id'];
// Set up draggable rows.
$form['tabledrag'][$mlid] = [
// Set the draggable class.
'#attributes' => ['class' => ['draggable']],
// Set the first column value to the title of the menu item.
'item' => ['#plain_text' => $title],
// Set the weight column.
'weight' => [
'#type' => 'weight',
'#title_display' => 'invisible',
'#value' => $menu_val['original_link']->getPluginDefinition()['weight'],
'#default_value' => 0,
+ '#delta' => $count + 10,
'#attributes' => ['class' => ['table-order-weight']],
],
];
}
}
// Submit button.
$form['actions']['submit'] = [
'#type' => 'submit',
'#value' => $this->t('Save'),
'#button_type' => 'primary',
];
}
Remaining tasks
I'll make a patch which does the above.
User interface changes
None.
API changes
None.
Data model changes
None.