Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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'));
}
}
Loading