NEW Add new method TabSet::changeTabOrder(). (#11329)

This commit is contained in:
Guy Sartorelli 2024-08-12 09:33:55 +12:00 committed by GitHub
parent cdde36bb9a
commit eee7a84a48
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 70 additions and 0 deletions

View File

@ -249,6 +249,39 @@ class TabSet extends CompositeField
return parent::insertAfter($insertAfter, $field, $appendIfMissing);
}
/**
* Change the order of tabs which are direct children of this TabSet by specifying an ordered list of
* tab names.
*
* This works well in conjunction with SilverStripe's scaffolding functions: take the scaffold, and
* shuffle the tabs around to the order that you want.
*
* Tab names should exclude prefixes. For example if this TabSet is "Root", include "Main" not "Root.Main"
*/
public function changeTabOrder(array $tabNames): static
{
// Build a map of tabs indexed by their name. This will make the 2nd step much easier.
$existingTabs = [];
foreach ($this->children as $tab) {
$existingTabs[$tab->getName()] = $tab;
}
// Iterate through the ordered list of names, building a new array.
// While we're doing this, empty out $existingTabs so that we can keep track of leftovers.
// Unrecognised field names are okay; just ignore them.
$orderedTabs = [];
foreach ($tabNames as $tabName) {
if (isset($existingTabs[$tabName])) {
$orderedTabs[] = $existingTabs[$tabName];
unset($existingTabs[$tabName]);
}
}
// Add the leftover fields to the end of the ordered list.
$this->setTabs(FieldList::create([...$orderedTabs, ...$existingTabs]));
return $this;
}
/**
* Sets an additional default for $schemaData.
* The existing keys are immutable. HideNav is added in this overriding method to ensure it is not ignored by

View File

@ -0,0 +1,37 @@
<?php
namespace SilverStripe\Forms\Tests;
use SilverStripe\Dev\SapphireTest;
use SilverStripe\Forms\FieldList;
use SilverStripe\Forms\TabSet;
class TabSetTest extends SapphireTest
{
protected $usesDatabase = false;
public function testChangeTabOrder(): void
{
$tabSet = new TabSet('Root');
$fieldList = new FieldList([$tabSet]);
$fieldList->findOrMakeTab('Root.Main');
$fieldList->findOrMakeTab('Root.Next');
$fieldList->findOrMakeTab('Root.More');
$fieldList->findOrMakeTab('Root.Extra');
$fieldList->addFieldToTab('Root', new TabSet('SubTabSet'));
$fieldList->findOrMakeTab('Root.SubTabSet.Another');
// Reorder tabs - intentionally leaving some alone, which will be added to the end.
$tabSet->changeTabOrder([
'SubTabSet',
'More',
'Main',
'Non-Existent', // will be ignored
'Another', // will be ignored
]);
// Order is correct
$this->assertSame(['SubTabSet', 'More', 'Main', 'Next', 'Extra'], $tabSet->getChildren()->column('Name'));
// Sub-tab is still there
$this->assertNotNull($fieldList->findTab('Root.SubTabSet.Another'));
}
}