mirror of
https://github.com/silverstripe/silverstripe-framework
synced 2024-10-22 14:05:37 +02:00
261 lines
6.6 KiB
PHP
261 lines
6.6 KiB
PHP
<?php
|
|
|
|
namespace SilverStripe\Forms;
|
|
|
|
use SilverStripe\Core\Convert;
|
|
use SilverStripe\ORM\FieldType\DBHTMLText;
|
|
use SilverStripe\View\Requirements;
|
|
use InvalidArgumentException;
|
|
|
|
/**
|
|
* Defines a set of tabs in a form.
|
|
* The tabs are build with our standard tabstrip javascript library.
|
|
* By default, the HTML is generated using FieldHolder.
|
|
*
|
|
* <b>Usage</b>
|
|
*
|
|
* <code>
|
|
* new TabSet(
|
|
* $name = "TheTabSetName",
|
|
* new Tab(
|
|
* $title='Tab one',
|
|
* new HeaderField("A header"),
|
|
* new LiteralField("Lipsum","Lorem ipsum dolor sit amet enim.")
|
|
* ),
|
|
* new Tab(
|
|
* $title='Tab two',
|
|
* new HeaderField("A second header"),
|
|
* new LiteralField("Lipsum","Ipsum dolor sit amet enim.")
|
|
* )
|
|
* )
|
|
* </code>
|
|
*
|
|
* Caution: The form field does not include any JavaScript or CSS when used outside of the CMS context,
|
|
* since the required frontend dependencies are included through CMS bundling.
|
|
*/
|
|
class TabSet extends CompositeField
|
|
{
|
|
|
|
/**
|
|
* Use custom react component
|
|
*
|
|
* @var string
|
|
*/
|
|
protected $schemaComponent = 'Tabs';
|
|
|
|
/**
|
|
* @var TabSet
|
|
*/
|
|
protected $tabSet;
|
|
|
|
/**
|
|
* @var string
|
|
*/
|
|
protected $id;
|
|
|
|
/**
|
|
* @param string $name Identifier
|
|
* @param string|Tab|TabSet $titleOrTab Natural language title of the tabset, or first tab.
|
|
* If its left out, the class uses {@link FormField::name_to_label()} to produce a title
|
|
* from the {@link $name} parameter.
|
|
* @param Tab|TabSet ...$tabs All further parameters are inserted as children into the TabSet
|
|
*/
|
|
public function __construct($name, $titleOrTab = null, $tabs = null)
|
|
{
|
|
if (!is_string($name)) {
|
|
throw new InvalidArgumentException('Invalid string parameter for $name');
|
|
}
|
|
|
|
// Get following arguments
|
|
$tabs = func_get_args();
|
|
array_shift($tabs);
|
|
|
|
// Detect title from second argument, if it is a string
|
|
if ($titleOrTab && is_string($titleOrTab)) {
|
|
$title = $titleOrTab;
|
|
array_shift($tabs);
|
|
} else {
|
|
$title = static::name_to_label($name);
|
|
}
|
|
|
|
// Normalise children list
|
|
if (count($tabs) === 1 && (is_array($tabs[0]) || $tabs[0] instanceof FieldList)) {
|
|
$tabs = $tabs[0];
|
|
}
|
|
|
|
// Ensure tabs are assigned to this tabset
|
|
if ($tabs) {
|
|
foreach ($tabs as $tab) {
|
|
if ($tab instanceof Tab || $tab instanceof TabSet) {
|
|
$tab->setTabSet($this);
|
|
} else {
|
|
throw new InvalidArgumentException("TabSet can only contain instances of other Tab or Tabsets");
|
|
}
|
|
}
|
|
}
|
|
|
|
parent::__construct($tabs);
|
|
|
|
// Assign name and title (not assigned by parent constructor)
|
|
$this->setName($name);
|
|
$this->setTitle($title);
|
|
$this->setID(Convert::raw2htmlid($name));
|
|
}
|
|
|
|
public function ID()
|
|
{
|
|
if ($this->tabSet) {
|
|
return $this->tabSet->ID() . '_' . $this->id . '_set';
|
|
}
|
|
return $this->id;
|
|
}
|
|
|
|
/**
|
|
* Set custom HTML ID to use for this tabset
|
|
*
|
|
* @param string $id
|
|
* @return $this
|
|
*/
|
|
public function setID($id)
|
|
{
|
|
$this->id = $id;
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* Returns a tab-strip and the associated tabs.
|
|
* The HTML is a standardised format, containing a <ul;
|
|
*
|
|
* @param array $properties
|
|
* @return DBHTMLText|string
|
|
*/
|
|
public function FieldHolder($properties = array())
|
|
{
|
|
$obj = $properties ? $this->customise($properties) : $this;
|
|
|
|
return $obj->renderWith($this->getTemplates());
|
|
}
|
|
|
|
/**
|
|
* Return a set of all this classes tabs
|
|
*
|
|
* @return FieldList
|
|
*/
|
|
public function Tabs()
|
|
{
|
|
return $this->children;
|
|
}
|
|
|
|
/**
|
|
* @param FieldList $children Assign list of tabs
|
|
*/
|
|
public function setTabs($children)
|
|
{
|
|
$this->children = $children;
|
|
}
|
|
|
|
/**
|
|
* Assign to a TabSet instance
|
|
*
|
|
* @param TabSet $val
|
|
* @return $this
|
|
*/
|
|
public function setTabSet($val)
|
|
{
|
|
$this->tabSet = $val;
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* Get parent tabset
|
|
*
|
|
* @return TabSet
|
|
*/
|
|
public function getTabSet()
|
|
{
|
|
return $this->tabSet;
|
|
}
|
|
|
|
public function getAttributes()
|
|
{
|
|
return array_merge(
|
|
$this->attributes,
|
|
array(
|
|
'id' => $this->ID(),
|
|
'class' => $this->extraClass()
|
|
)
|
|
);
|
|
}
|
|
|
|
/**
|
|
* Add a new child field to the end of the set.
|
|
*
|
|
* @param FormField $field
|
|
*/
|
|
public function push(FormField $field)
|
|
{
|
|
if ($field instanceof Tab || $field instanceof TabSet) {
|
|
$field->setTabSet($this);
|
|
}
|
|
parent::push($field);
|
|
}
|
|
|
|
/**
|
|
* Add a new child field to the beginning of the set.
|
|
*
|
|
* @param FormField $field
|
|
*/
|
|
public function unshift(FormField $field)
|
|
{
|
|
if ($field instanceof Tab || $field instanceof TabSet) {
|
|
$field->setTabSet($this);
|
|
}
|
|
parent::unshift($field);
|
|
}
|
|
|
|
/**
|
|
* Inserts a field before a particular field in a FieldList.
|
|
*
|
|
* @param string $insertBefore Name of the field to insert before
|
|
* @param FormField $field The form field to insert
|
|
* @return FormField|null
|
|
*/
|
|
public function insertBefore($insertBefore, $field, $appendIfMissing = true)
|
|
{
|
|
if ($field instanceof Tab || $field instanceof TabSet) {
|
|
$field->setTabSet($this);
|
|
}
|
|
return parent::insertBefore($insertBefore, $field, $appendIfMissing);
|
|
}
|
|
|
|
/**
|
|
* Inserts a field after a particular field in a FieldList.
|
|
*
|
|
* @param string $insertAfter Name of the field to insert after
|
|
* @param FormField $field The form field to insert
|
|
* @return FormField|null
|
|
*/
|
|
public function insertAfter($insertAfter, $field, $appendIfMissing = true)
|
|
{
|
|
if ($field instanceof Tab || $field instanceof TabSet) {
|
|
$field->setTabSet($this);
|
|
}
|
|
return parent::insertAfter($insertAfter, $field, $appendIfMissing);
|
|
}
|
|
|
|
/**
|
|
* 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
|
|
* {@link setSchemaData()}
|
|
* It allows hiding of the navigation in the Tabs.js React component.
|
|
*
|
|
* @return array
|
|
*/
|
|
public function getSchemaStateDefaults()
|
|
{
|
|
$defaults = parent::getSchemaStateDefaults();
|
|
$defaults['hideNav'] = false;
|
|
return $defaults;
|
|
}
|
|
}
|