Issue #1838114 by ry5n, swentel, sun: change node form’s vertical tabs into details elements.

8.0.x
Dries 2013-01-17 15:43:29 -05:00
parent fe15dd23de
commit 9b7bdba101
10 changed files with 143 additions and 38 deletions

View File

@ -2832,10 +2832,15 @@ function theme_fieldset($variables) {
$element['#attributes']['aria-describedby'] = $description_id;
}
$legend_attributes = array();
if (isset($element['#title_display']) && $element['#title_display'] == 'invisible') {
$legend_attributes['class'][] = 'element-invisible';
}
$output = '<fieldset' . new Attribute($element['#attributes']) . '>';
if (!empty($element['#title'])) {
// Always wrap fieldset legends in a SPAN for CSS positioning.
$output .= '<legend><span class="fieldset-legend">' . $element['#title'] . '</span></legend>';
$output .= '<legend' . new Attribute($legend_attributes) . '><span class="fieldset-legend">' . $element['#title'] . '</span></legend>';
}
$output .= '<div class="fieldset-wrapper">';
if (!empty($element['#description'])) {
@ -4670,12 +4675,18 @@ function theme_form_element($variables) {
'#title_display' => 'before',
);
// Take over any #wrapper_attributes defined by the element.
// @todo Temporary hack for #type 'item'.
// @see http://drupal.org/node/1829202
if (isset($element['#wrapper_attributes'])) {
$attributes = $element['#wrapper_attributes'];
}
// Add element #id for #type 'item'.
if (isset($element['#markup']) && !empty($element['#id'])) {
$attributes['id'] = $element['#id'];
}
// Add element's #type and #name as class to aid with JS/CSS selectors.
$attributes['class'] = array('form-item');
$attributes['class'][] = 'form-item';
if (!empty($element['#type'])) {
$attributes['class'][] = 'form-type-' . strtr($element['#type'], '_', '-');
}
@ -4798,8 +4809,7 @@ function theme_form_element_label($variables) {
$attributes['for'] = $element['#id'];
}
// The leading whitespace helps visually separate fields from inline labels.
return ' <label' . new Attribute($attributes) . '>' . $t('!title !required', array('!title' => $title, '!required' => $required)) . "</label>\n";
return '<label' . new Attribute($attributes) . '>' . $t('!title!required', array('!title' => $title, '!required' => $required)) . '</label>';
}
/**

View File

@ -425,7 +425,7 @@ function _book_add_form_elements(&$form, &$form_state, Node $node) {
'#weight' => 10,
'#collapsible' => TRUE,
'#collapsed' => TRUE,
'#group' => 'additional_settings',
'#group' => 'advanced',
'#attributes' => array(
'class' => array('book-outline-form'),
),

View File

@ -1114,7 +1114,7 @@ function comment_form_node_form_alter(&$form, $form_state) {
'#title' => t('Comment settings'),
'#collapsible' => TRUE,
'#collapsed' => TRUE,
'#group' => 'additional_settings',
'#group' => 'advanced',
'#attributes' => array(
'class' => array('comment-node-settings-form'),
),

View File

@ -581,7 +581,7 @@ function menu_form_node_form_alter(&$form, $form_state) {
'#access' => user_access('administer menu'),
'#collapsible' => TRUE,
'#collapsed' => !$link['link_title'],
'#group' => 'additional_settings',
'#group' => 'advanced',
'#attached' => array(
'library' => array(array('menu', 'drupal.menu')),
),

View File

@ -56,6 +56,20 @@ class NodeFormController extends EntityFormController {
* Overrides Drupal\Core\Entity\EntityFormController::form().
*/
public function form(array $form, array &$form_state, EntityInterface $node) {
// Visual representation of the node content form depends on following
// parameters:
// - the current user has access to view the administration theme.
// - the current path is an admin path.
// - the node/add / edit pages are configured to be represented in the
// administration theme.
$container_type = 'vertical_tabs';
$request = drupal_container()->get('request');
$path = $request->attributes->get('system_path');
if (user_access('view the administration theme') && path_is_admin($path)) {
$container_type = 'container';
}
$user_config = config('user.settings');
// Some special stuff when previewing a node.
if (isset($form_state['node_preview'])) {
@ -109,20 +123,47 @@ class NodeFormController extends EntityFormController {
'#access' => isset($language_configuration['language_show']) && $language_configuration['language_show'],
);
$form['additional_settings'] = array(
'#type' => 'vertical_tabs',
$form['advanced'] = array(
'#type' => $container_type,
'#attributes' => array('class' => array('entity-meta')),
'#weight' => 99,
);
$form['meta'] = array (
'#type' => 'fieldset',
'#attributes' => array('class' => array('entity-meta-header')),
'#type' => 'container',
'#group' => 'advanced',
'#weight' => -100,
'#access' => $container_type == 'container',
// @todo Geez. Any .status is styled as OK icon? Really?
'published' => array(
'#type' => 'item',
'#wrapper_attributes' => array('class' => array('published')),
'#markup' => !empty($node->status) ? t('Published') : t('Not published'),
'#access' => !empty($node->nid),
),
'changed' => array(
'#type' => 'item',
'#wrapper_attributes' => array('class' => array('changed', 'container-inline')),
'#title' => t('Last saved'),
'#markup' => !$node->isNew() ? format_date($node->changed, 'short') : t('Not saved yet'),
),
'author' => array(
'#type' => 'item',
'#wrapper_attributes' => array('class' => array('author', 'container-inline')),
'#title' => t('Author'),
'#markup' => user_format_name(user_load($node->uid)),
),
);
// Add a log field if the "Create new revision" option is checked, or if the
// current user has the ability to check that option.
$form['revision_information'] = array(
'#type' => 'details',
'#type' => $container_type == 'container' ? 'container' : 'details',
'#group' => $container_type == 'container' ? 'meta' : 'advanced',
'#title' => t('Revision information'),
'#collapsible' => TRUE,
// Collapsed by default when "Create new revision" is unchecked.
'#collapsed' => !$node->isNewRevision(),
'#group' => 'additional_settings',
'#attributes' => array(
'class' => array('node-form-revision-information'),
),
@ -133,30 +174,24 @@ class NodeFormController extends EntityFormController {
'#access' => $node->isNewRevision() || user_access('administer nodes'),
);
$form['revision_information']['revision'] = array(
$form['revision_information']['revision']['revision'] = array(
'#type' => 'checkbox',
'#title' => t('Create new revision'),
'#default_value' => $node->isNewRevision(),
'#access' => user_access('administer nodes'),
);
// Check the revision log checkbox when the log textarea is filled in.
// This must not happen if "Create new revision" is enabled by default,
// since the state would auto-disable the checkbox otherwise.
if (!$node->isNewRevision()) {
$form['revision_information']['revision']['#states'] = array(
'checked' => array(
'textarea[name="log"]' => array('empty' => FALSE),
),
);
}
$form['revision_information']['log'] = array(
$form['revision_information']['revision']['log'] = array(
'#type' => 'textarea',
'#title' => t('Revision log message'),
'#rows' => 4,
'#default_value' => !empty($node->log) ? $node->log : '',
'#description' => t('Briefly describe the changes you have made.'),
'#states' => array(
'visible' => array(
':input[name="revision"]' => array('checked' => TRUE),
),
),
);
// Node author information for administrators.
@ -166,7 +201,7 @@ class NodeFormController extends EntityFormController {
'#title' => t('Authoring information'),
'#collapsible' => TRUE,
'#collapsed' => TRUE,
'#group' => 'additional_settings',
'#group' => 'advanced',
'#attributes' => array(
'class' => array('node-form-author'),
),
@ -207,7 +242,7 @@ class NodeFormController extends EntityFormController {
'#title' => t('Publishing options'),
'#collapsible' => TRUE,
'#collapsed' => TRUE,
'#group' => 'additional_settings',
'#group' => 'advanced',
'#attributes' => array(
'class' => array('node-form-options'),
),

View File

@ -234,4 +234,5 @@ class Node extends Entity implements ContentEntityInterface {
public function getRevisionId() {
return $this->vid;
}
}

View File

@ -500,12 +500,12 @@ class OptionsWidgetsTest extends FieldTestBase {
$this->drupalGet($fieldEditUrl);
$this->assertText(
'Use field label instead of the "On value" as label ',
'Use field label instead of the "On value" as label',
t('Display setting checkbox available.')
);
$this->assertFieldByXPath(
'*//label[@for="edit-' . $this->bool['field_name'] . '-und" and text()="MyOnValue "]',
'*//label[@for="edit-' . $this->bool['field_name'] . '-und" and text()="MyOnValue"]',
TRUE,
t('Default case shows "On value"')
);
@ -519,7 +519,7 @@ class OptionsWidgetsTest extends FieldTestBase {
// is stored and has the expected effect
$this->drupalGet($fieldEditUrl);
$this->assertText(
'Use field label instead of the "On value" as label ',
'Use field label instead of the "On value" as label',
t('Display setting checkbox is available')
);
$this->assertFieldChecked(
@ -527,7 +527,7 @@ class OptionsWidgetsTest extends FieldTestBase {
t('Display settings checkbox checked')
);
$this->assertFieldByXPath(
'*//label[@for="edit-' . $this->bool['field_name'] . '-und" and text()="' . $this->bool['field_name'] . ' "]',
'*//label[@for="edit-' . $this->bool['field_name'] . '-und" and text()="' . $this->bool['field_name'] . '"]',
TRUE,
t('Display label changes label of the checkbox')
);

View File

@ -124,7 +124,7 @@ function path_form_node_form_alter(&$form, $form_state) {
'#title' => t('URL path settings'),
'#collapsible' => TRUE,
'#collapsed' => empty($path['alias']),
'#group' => 'additional_settings',
'#group' => 'advanced',
'#attributes' => array(
'class' => array('path-form'),
),

View File

@ -147,6 +147,9 @@ abbr.form-required, abbr.tabledrag-changed, abbr.ajax-changed {
/**
* Inline items.
*/
.container-inline label:after {
content: ':';
}
.container-inline .form-actions,
.container-inline.form-actions {
margin-top: 0;

View File

@ -506,12 +506,6 @@ details summary {
padding-top: 0.5em;
padding-bottom: 0.5em;
}
details details {
background-color: #fff;
}
details details details {
background-color: #f8f8f8;
}
/**
* Form elements.
@ -1406,3 +1400,65 @@ details.fieldset-no-legend {
/* @end */
/* @end */
/**
* Entity meta settings.
*/
.entity-meta {
background-color: #e2e2e2;
border-bottom: 0;
border-left: 1px solid #a5a5a5;
border-right: 1px solid #a5a5a5;
border-top: 0;
-webkit-box-shadow: inset 0 0 5px rgba(0, 0, 0, .15);
box-shadow: inset 0 0 5px rgba(0, 0, 0, .15);
margin-top: 0;
padding-top: 0;
}
.entity-meta-header,
.entity-meta details {
background-color: #f2f2f2;
border-top: 1px solid #a5a5a5;
border-bottom: 1px solid #a5a5a5;
}
.entity-meta-header {
padding: 1em 1.5em;
}
.entity-meta-header .published {
font-size: 1.231em;
font-weight: bold;
text-shadow: 0 1px 0 #fff;
}
.entity-meta-header .changed {
font-style: italic; /* As-designed, but really: why is this italic? */
}
.entity-meta details {
border-left: 0;
border-right: 0;
border-top: 1px solid #fff;
margin: 0;
}
.entity-meta details[open] {
background-color: transparent;
background-image: -webkit-linear-gradient(top, rgba(0, 0, 0, .15), transparent 5px);
background-image: -moz-linear-gradient(top, rgba(0, 0, 0, .15), transparent 5px);
background-image: -o-linear-gradient(top, rgba(0, 0, 0, .15), transparent 5px);
background-image: linear-gradient(to bottom, rgba(0, 0, 0, .15), transparent 5px);
border-top-width: 0;
padding-top: 1px;
}
.entity-meta details[open] + [open] {
background-image: none;
border-top-width: 1px;
padding-top: 0;
}
.entity-meta details > .details-wrapper {
padding-top: 0;
}
.entity-meta details > summary {
padding: 0.85em 1.25em;
text-shadow: 0 1px 0 white;
}
.entity-meta details .summary {
display: none; /* Hide JS summaries. @todo Rethink summaries. */
}