Commit 34a95571 authored by jrockowitz's avatar jrockowitz Committed by jrockowitz

Issue #3182414 by jrockowitz: Details save functionality is incompatible with Vertical tabs panes

parent 360ea44e
......@@ -36,7 +36,6 @@
$('details > summary', context).once('webform-details-summary-save').click(function () {
var $details = $(this).parent();
// @see https://css-tricks.com/snippets/jquery/make-an-jquery-hasattr/
if ($details[0].hasAttribute('data-webform-details-nosave')) {
return;
......@@ -90,6 +89,11 @@
return '';
}
// Ignore details that are vertical tabs pane.
if ($details.hasClass('vertical-tabs__pane')) {
return '';
}
// Any details element not included a webform must have define its own id.
var webformId = $details.attr('data-webform-element-id');
if (webformId) {
......
......@@ -42,13 +42,15 @@
var $toggle = $(options.button)
.attr('title', Drupal.t('Toggle details widget state.'))
.on('click', function (e) {
// Get details that are not vertical tabs pane.
var $details = $form.find('details:not(.vertical-tabs__pane)');
var open;
if (Drupal.webform.detailsToggle.isFormDetailsOpen($form)) {
$form.find('details').removeAttr('open');
$details.removeAttr('open');
open = 0;
}
else {
$form.find('details').attr('open', 'open');
$details.attr('open', 'open');
open = 1;
}
Drupal.webform.detailsToggle.setDetailsToggleLabel($form);
......@@ -56,7 +58,7 @@
// Set the saved states for all the details elements.
// @see webform.element.details.save.js
if (Drupal.webformDetailsSaveGetName) {
$form.find('details').each(function () {
$details.each(function () {
// Note: Drupal.webformDetailsSaveGetName checks if localStorage
// exists and is enabled.
// @see webform.element.details.save.js
......
<?php
namespace Drupal\webform\Plugin\WebformElement;
use Drupal\Core\Form\FormState;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Render\Element\VerticalTabs as VerticalTabsElement;
use Drupal\webform\Element\WebformMessage as WebformMessageElement;
use Drupal\webform\Plugin\WebformElementBase;
use Drupal\webform\Plugin\WebformElementDisplayOnInterface;
use Drupal\webform\WebformSubmissionInterface;
/**
* Provides a hidden 'vertical_tabs' element.
*
* @WebformElement(
* id = "vertical_tabs",
* label = @Translation("Vertical tabs"),
* description = @Translation("Provides a vertical tabs element."),
* category = @Translation("Markup elements"),
* hidden = TRUE
* )
*/
class VerticalTabs extends WebformElementBase {
/**
* {@inheritdoc}
*/
protected function defineDefaultProperties() {
return [
// Element settings.
'title' => $this->t('Vertical Tabs'),
// Description/Help.
'help' => '',
'help_title' => '',
'description' => '',
'more' => '',
'more_title' => '',
// Form display.
'title_display' => 'invisible',
'description_display' => '',
'help_display' => '',
// Form validation.
'required' => FALSE,
// Attributes.
'wrapper_attributes' => [],
'label_attributes' => [],
// Vertical tabs.
'default_tab' => '',
] + $this->defineDefaultBaseProperties();
}
/**
* {@inheritdoc}
*/
protected function defineDefaultBaseProperties() {
$properties = parent::defineDefaultBaseProperties();
unset(
$properties['prepopulate'],
$properties['states_clear']
);
return $properties;
}
/****************************************************************************/
/**
* {@inheritdoc}
*/
public function isInput(array $element) {
return FALSE;
}
/**
* {@inheritdoc}
*/
public function isContainer(array $element) {
return FALSE;
}
/**
* {@inheritdoc}
*/
public function prepare(array &$element, WebformSubmissionInterface $webform_submission = NULL) {
parent::prepare($element, $webform_submission);
$element += ['#title_display' => 'invisible'];
return $element;
}
/**
* {@inheritdoc}
*/
public function buildHtml(array $element, WebformSubmissionInterface $webform_submission, array $options = []) {
// Vertical tab are not rendered when a submission is viewed.
return [];
}
/**
* {@inheritdoc}
*/
public function buildText(array $element, WebformSubmissionInterface $webform_submission, array $options = []) {
// Vertical tab are not rendered when a submission is viewed.
return [];
}
/**
* {@inheritdoc}
*/
public function getRelatedTypes(array $element) {
return [];
}
/**
* {@inheritdoc}
*/
public function getElementSelectorOptions(array $element) {
return [];
}
/**
* {@inheritdoc}
*/
public function form(array $form, FormStateInterface $form_state) {
$form = parent::form($form, $form_state);
unset($form['element']['title']['#required']);
$form['vertical_tabs'] = [
'#type' => 'fieldset',
'#title' => $this->t('Vertical tabs settings'),
'#open' => TRUE,
];
$form['vertical_tabs']['vertical_tabs_message'] = [
'#type' => 'webform_message',
'#message_type' => 'info',
'#access' => TRUE,
'#message_message' => $this->t("To add details and fieldsets this vertical tabs element, you must defined a custom <code>'#group': vertical_tab_key</code> property in the details or fieldset element with this vertical tabs' element key."),
'#message_close' => TRUE,
'#message_storage' => WebformMessageElement::STORAGE_SESSION,
];
$form['vertical_tabs']['default_tab'] = [
'#type' => 'textfield',
'#title' => $this->t('Default tab'),
'#description' => $this->t('The default tab must be the [id] attributes of the details or fieldset element.'),
];
return $form;
}
/**
* {@inheritdoc}
*/
public function preview() {
return [];
}
}
uuid: null
langcode: en
status: open
dependencies:
enforced:
module:
- webform_test
open: null
close: null
weight: 0
uid: null
template: false
archive: false
id: test_element_vertical_tabs
title: 'Test: Element: Vertical tabs'
description: 'Test Vertical tabs support'
category: 'Test: Element'
elements: |
vertical_tabs:
'#type': vertical_tabs
vertical_tabs_details_01:
'#type': details
'#title': vertical_tabs_details_01
'#group': vertical_tabs
vertical_tabs_textfield_01:
'#type': textfield
'#title': vertical_tabs_textfield_01
vertical_tabs_details_02:
'#type': details
'#title': vertical_tabs_details_02
'#group': vertical_tabs
vertical_tabs_textfield_02:
'#type': textfield
'#title': vertical_tabs_textfield_02
vertical_tabs_details_03:
'#type': details
'#title': vertical_tabs_details_03
'#group': vertical_tabs
vertical_tabs_textfield_03:
'#type': textfield
'#title': vertical_tabs_textfield_03
vertical_tabs_advanced:
'#type': vertical_tabs
'#title': 'My Vertical Tabs'
'#title_display': before
'#require': TRUE
'#description': 'This is a description'
'#help': 'This is a help'
'#more': 'This is a more'
'#default_tab': edit-vertical-tabs-advanced-details-03
'#wrapper_attributes':
style: 'border: 1px solid red; padding: 10px'
'#label_attributes':
style: 'color: green'
vertical_tabs_advanced_details_01:
'#type': details
'#title': vertical_tabs_advanced_details_01
'#group': vertical_tabs_advanced
vertical_tabs_advanced_textfield_01:
'#type': textfield
'#title': vertical_tabs_advanced_textfield_01
vertical_tabs_advanced_details_02:
'#type': details
'#title': vertical_tabs_advanced_details_02
'#group': vertical_tabs_advanced
vertical_tabs_advanced_textfield_02:
'#type': textfield
'#title': vertical_tabs_advanced_textfield_02
vertical_tabs_advanced_details_03:
'#type': details
'#title': vertical_tabs_advanced_details_03
'#group': vertical_tabs_advanced
vertical_tabs_advanced_textfield_03:
'#type': textfield
'#title': vertical_tabs_advanced_textfield_03
details_01:
'#type': details
'#title': details_01
textfield_01:
'#type': textfield
'#title': textfield_01
details_02:
'#type': details
'#title': details_02
textfield_02:
'#type': textfield
'#title': textfield_02
details_03:
'#type': details
'#title': details_03
textfield_03:
'#type': textfield
'#title': textfield_03
css: ''
javascript: ''
settings:
ajax: false
ajax_scroll_top: form
ajax_progress_type: ''
ajax_effect: ''
ajax_speed: null
page: true
page_submit_path: ''
page_confirm_path: ''
page_theme_name: ''
form_title: source_entity_webform
form_submit_once: false
form_exception_message: ''
form_open_message: ''
form_close_message: ''
form_previous_submissions: true
form_confidential: false
form_confidential_message: ''
form_remote_addr: true
form_convert_anonymous: false
form_prepopulate: false
form_prepopulate_source_entity: false
form_prepopulate_source_entity_required: false
form_prepopulate_source_entity_type: ''
form_reset: false
form_disable_autocomplete: false
form_novalidate: false
form_disable_inline_errors: false
form_required: false
form_unsaved: false
form_disable_back: false
form_submit_back: false
form_autofocus: false
form_details_toggle: false
form_access_denied: default
form_access_denied_title: ''
form_access_denied_message: ''
form_access_denied_attributes: { }
form_file_limit: ''
share: false
share_node: false
share_theme_name: ''
share_title: true
share_page_body_attributes: { }
submission_label: ''
submission_log: false
submission_views: { }
submission_views_replace: { }
submission_user_columns: { }
submission_user_duplicate: false
submission_access_denied: default
submission_access_denied_title: ''
submission_access_denied_message: ''
submission_access_denied_attributes: { }
submission_exception_message: ''
submission_locked_message: ''
submission_excluded_elements: { }
submission_exclude_empty: false
submission_exclude_empty_checkbox: false
previous_submission_message: ''
previous_submissions_message: ''
autofill: false
autofill_message: ''
autofill_excluded_elements: { }
wizard_progress_bar: true
wizard_progress_pages: false
wizard_progress_percentage: false
wizard_progress_link: false
wizard_progress_states: false
wizard_auto_forward: true
wizard_auto_forward_hide_next_button: false
wizard_keyboard: true
wizard_start_label: ''
wizard_preview_link: false
wizard_confirmation: true
wizard_confirmation_label: ''
wizard_track: ''
wizard_prev_button_label: ''
wizard_next_button_label: ''
wizard_toggle: false
wizard_toggle_show_label: ''
wizard_toggle_hide_label: ''
preview: 0
preview_label: ''
preview_title: ''
preview_message: ''
preview_attributes: { }
preview_excluded_elements: { }
preview_exclude_empty: true
preview_exclude_empty_checkbox: false
draft: none
draft_multiple: false
draft_auto_save: false
draft_saved_message: ''
draft_loaded_message: ''
draft_pending_single_message: ''
draft_pending_multiple_message: ''
confirmation_type: page
confirmation_title: ''
confirmation_message: ''
confirmation_url: ''
confirmation_attributes: { }
confirmation_back: true
confirmation_back_label: ''
confirmation_back_attributes: { }
confirmation_exclude_query: false
confirmation_exclude_token: false
confirmation_update: false
limit_total: null
limit_total_interval: null
limit_total_message: ''
limit_total_unique: false
limit_user: null
limit_user_interval: null
limit_user_message: ''
limit_user_unique: false
entity_limit_total: null
entity_limit_total_interval: null
entity_limit_user: null
entity_limit_user_interval: null
purge: none
purge_days: null
results_disabled: false
results_disabled_ignore: false
results_customize: false
token_view: false
token_update: false
token_delete: false
serial_disabled: false
access:
create:
roles:
- anonymous
- authenticated
users: { }
permissions: { }
view_any:
roles: { }
users: { }
permissions: { }
update_any:
roles: { }
users: { }
permissions: { }
delete_any:
roles: { }
users: { }
permissions: { }
purge_any:
roles: { }
users: { }
permissions: { }
view_own:
roles: { }
users: { }
permissions: { }
update_own:
roles: { }
users: { }
permissions: { }
delete_own:
roles: { }
users: { }
permissions: { }
administer:
roles: { }
users: { }
permissions: { }
test:
roles: { }
users: { }
permissions: { }
configuration:
roles: { }
users: { }
permissions: { }
handlers: { }
variants: { }
......@@ -764,6 +764,25 @@ value:
container: false
root: false
multiple: false
vertical_tabs:
dependencies: { }
default_key: ''
category: 'Markup elements'
description: 'Provides a vertical tabs element.'
hidden: true
multiline: false
composite: false
states_wrapper: false
deprecated: false
deprecated_message: ''
id: vertical_tabs
label: 'Vertical tabs'
class: Drupal\webform\Plugin\WebformElement\VerticalTabs
provider: webform
input: false
container: false
root: false
multiple: false
view:
dependencies: { }
default_key: ''
......@@ -1896,7 +1915,6 @@ webform_wizard_page:
root: true
multiple: false
YAML;
return Yaml::decode($yaml);
}
......
......@@ -1849,6 +1849,41 @@ url:
value:
title: ''
value: ''
vertical_tabs:
access: true
access_create_permissions: { }
access_create_roles:
- anonymous
- authenticated
access_create_users: { }
access_update_permissions: { }
access_update_roles:
- anonymous
- authenticated
access_update_users: { }
access_view_permissions: { }
access_view_roles:
- anonymous
- authenticated
access_view_users: { }
admin_notes: ''
admin_title: ''
default_tab: ''
description: ''
description_display: ''
flex: 1
help: ''
help_display: ''
help_title: ''
label_attributes: { }
more: ''
more_title: ''
private: false
required: false
states: { }
title: 'Vertical Tabs'
title_display: invisible
wrapper_attributes: { }
view:
access: true
access_create_permissions: { }
......
<?php
namespace Drupal\Tests\webform\Functional\Element;
/**
* Tests for vertical tabs element.
*
* @group webform
*/
class WebformElementVerticalTabsTest extends WebformElementBrowserTestBase {
/**
* Webforms to load.
*
* @var array
*/
protected static $testWebforms = ['test_element_vertical_tabs'];
/**
* Test vertical tabs element.
*/
public function testVerticalTabs() {
$this->drupalGet('/webform/test_element_vertical_tabs');
// Check vertical_tabs element.
$this->assertRaw('<div data-drupal-selector="edit-vertical-tabs" data-vertical-tabs-panes>');
$this->assertRaw('<input class="vertical-tabs__active-tab" data-drupal-selector="edit-vertical-tabs-active-tab" type="hidden" name="vertical_tabs__active_tab" value="" />');
// Check vertical_tabs advanced element.
$this->assertRaw('<div data-drupal-selector="edit-vertical-tabs-advanced" aria-describedby="edit-vertical-tabs-advanced--description" data-vertical-tabs-panes>');
$this->assertRaw('<input class="vertical-tabs__active-tab" data-drupal-selector="edit-vertical-tabs-advanced-active-tab" type="hidden" name="vertical_tabs_advanced__active_tab" value="edit-vertical-tabs-advanced-details-03" />');
}
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment