Skip to content

Commit

Permalink
NEW Add new method TabSet::changeTabOrder(). (#11329)
Browse files Browse the repository at this point in the history
  • Loading branch information
GuySartorelli authored Aug 11, 2024
1 parent cdde36b commit eee7a84
Show file tree
Hide file tree
Showing 2 changed files with 70 additions and 0 deletions.
33 changes: 33 additions & 0 deletions src/Forms/TabSet.php
Original file line number Diff line number Diff line change
Expand Up @@ -249,6 +249,39 @@ public function insertAfter($insertAfter, $field, $appendIfMissing = true)
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
Expand Down
37 changes: 37 additions & 0 deletions tests/php/Forms/TabSetTest.php
Original file line number Diff line number Diff line change
@@ -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'));
}
}

0 comments on commit eee7a84

Please sign in to comment.