mirror of
https://github.com/silverstripe/silverstripe-framework
synced 2024-10-22 14:05:37 +02:00
Tabs docs for CMS
This commit is contained in:
parent
3214a0a756
commit
ada42103ed
@ -110,7 +110,46 @@ before the form itself is layouted with its sibling panels to avoid incorrect di
|
||||
SilverStripe constructs forms and its fields within PHP,
|
||||
mainly through the `[getCMSFields()](api:DataObject->getCMSFields())` method.
|
||||
This in turn means that the CMS loads these forms as HTML via Ajax calls,
|
||||
e.g. after saving a record (which requires a form refresh), or switching the section in the CMS>
|
||||
e.g. after saving a record (which requires a form refresh), or switching the section in the CMS.
|
||||
|
||||
Depending on where in the DOM hierarchy you want to use a form,
|
||||
custom templates and additional CSS classes might be required for correct operation.
|
||||
For example, the "EditForm" has specific view and logic JavaScript behaviour
|
||||
which can be enabled via adding the "cms-edit-form" class.
|
||||
In order to set the correct layout classes, we also need a custom template.
|
||||
To obey the inheritance chain, we use `$this->getTemplatesWithSuffix('_EditForm')` for
|
||||
selecting the most specific template (so `MyAdmin_EditForm.ss`, if it exists).
|
||||
|
||||
Basic example form in a CMS controller subclass:
|
||||
|
||||
:::php
|
||||
class MyAdmin extends LeftAndMain {
|
||||
function getEditForm() {
|
||||
$form = new Form(
|
||||
$this,
|
||||
'EditForm',
|
||||
new FieldSet(
|
||||
TabSet::create(
|
||||
'Root',
|
||||
Tab::create('Main',
|
||||
TextField::create('MyText')
|
||||
)
|
||||
)->setTemplate('CMSTabset')
|
||||
),
|
||||
new FieldSet(
|
||||
FormAction::create('doSubmit')
|
||||
)
|
||||
);
|
||||
// Required for correct CMS layout
|
||||
$form->addExtraClass('cms-edit-form');
|
||||
$form->setTemplate($this->getTemplatesWithSuffix('_EditForm'));
|
||||
return $form;
|
||||
}
|
||||
}
|
||||
|
||||
Note: Usually you don't need to worry about these settings,
|
||||
and will simply call `parent::getEditForm()` to modify an existing,
|
||||
correctly configured form.
|
||||
|
||||
## JavaScript through jQuery.entwine
|
||||
|
||||
@ -351,6 +390,103 @@ Note that a similar tree logic is also used for the
|
||||
form fields to select one or more entries from those hierarchies
|
||||
(`[api:TreeDropdownField]` and `[api:TreeMultiselectField]`).
|
||||
|
||||
## Tabs
|
||||
|
||||
We're using [jQuery UI tabs](http://jqueryui.com/), but in a customized fashion.
|
||||
HTML with tabs can be created either directly through HTML templates in the CMS,
|
||||
or indirectly through a `[api:TabSet]` form field. Since tabsets are useable
|
||||
outside of the CMS as well, the baseline application of tabs happens via
|
||||
a small wrapper around `jQuery.tabs()` stored in `TabSet.js`.
|
||||
|
||||
In the CMS however, tabs need to do more: They memorize their active tab
|
||||
in the user's browser, and lazy load content via ajax once they're activated.
|
||||
|
||||
They also need to work across different "layout containers" (see above),
|
||||
meaning a tab navigation might be in a layout header, while the tab
|
||||
content is occupied by the main content area. jQuery assumes a common
|
||||
parent in the DOM for both the tab navigation and its target DOM elements.
|
||||
In order to achieve this level of flexibility, most tabsets in the CMS
|
||||
use a custom template which leaves rendering the tab navigation to
|
||||
a separate template: `CMSMain.ss`. See the "Forms" section above
|
||||
for an example form.
|
||||
|
||||
Here's how you would apply this template to your own tabsets used in the CMS.
|
||||
Note that you usually only need to apply it to the outermost tabset,
|
||||
since all others should render with their tab navigation inline.
|
||||
|
||||
Form template with custom tab navigation (trimmed down):
|
||||
|
||||
:::ss
|
||||
<form $FormAttributes data-layout-type="border">
|
||||
|
||||
<div class="cms-content-header north">
|
||||
<% if Fields.hasTabset %>
|
||||
<% with Fields.fieldByName('Root') %>
|
||||
<div class="cms-content-header-tabs">
|
||||
<ul>
|
||||
<% loop Tabs %>
|
||||
<li><a href="#$id">$Title</a></li>
|
||||
<% end_loop %>
|
||||
</ul>
|
||||
</div>
|
||||
<% end_with %>
|
||||
<% end_if %>
|
||||
</div>
|
||||
|
||||
<div class="cms-content-fields center">
|
||||
<fieldset>
|
||||
<% loop Fields %>$FieldHolder<% end_loop %>
|
||||
</fieldset>
|
||||
</div>
|
||||
|
||||
</form>
|
||||
|
||||
Tabset template without tab navigation (e.g. `CMSTabset.ss`)
|
||||
|
||||
:::ss
|
||||
<div $AttributesHTML>
|
||||
<% loop Tabs %>
|
||||
<% if Tabs %>
|
||||
$FieldHolder
|
||||
<% else %>
|
||||
<div $AttributesHTML>
|
||||
<% loop Fields %>
|
||||
$FieldHolder
|
||||
<% end_loop %>
|
||||
</div>
|
||||
<% end_if %>
|
||||
<% end_loop %>
|
||||
</div>
|
||||
|
||||
Lazy loading works based on the `href` attribute of the tab navigation.
|
||||
The base behaviour is applied through adding a class `.cms-tabset` to a container.
|
||||
Assuming that each tab has its own URL which is tracked in the HTML5 history,
|
||||
the current tab display also has to work when loaded directly without Ajax.
|
||||
This is achieved by template conditionals (see "MyActiveCondition").
|
||||
The `.cms-panel-link` class will automatically trigger the ajax loading,
|
||||
and load the HTML content into the main view. Example:
|
||||
|
||||
:::ss
|
||||
<div id="my-tab-id" class="cms-tabset" data-ignore-tab-state="true">
|
||||
<ul>
|
||||
<li class="<% if MyActiveCondition %> ui-tabs-active<% end_if %>">
|
||||
<a href="admin/mytabs/tab1" class="cms-panel-link">
|
||||
Tab1
|
||||
</a>
|
||||
</li>
|
||||
<li class="<% if MyActiveCondition %> ui-tabs-active<% end_if %>">
|
||||
<a href="admin/mytabs/tab2" class="cms-panel-link">
|
||||
Tab2
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
The URL endpoints `admin/mytabs/tab1` and `admin/mytabs/tab2`
|
||||
should return HTML fragments suitable for inserting into the content area,
|
||||
through the `PjaxResponseNegotiator` class (see above).
|
||||
|
||||
|
||||
## Related
|
||||
|
||||
* [Howto: Extend the CMS Interface](../howto/extend-cms-interface)
|
||||
|
Loading…
Reference in New Issue
Block a user