abstract class WebformUiElementTypeFormBase in Webform 6.x
Same name and namespace in other branches
- 8.5 modules/webform_ui/src/Form/WebformUiElementTypeFormBase.php \Drupal\webform_ui\Form\WebformUiElementTypeFormBase
Provides a abstract element type webform for a webform element.
Hierarchy
- class \Drupal\Core\Form\FormBase implements ContainerInjectionInterface, FormInterface uses DependencySerializationTrait, LoggerChannelTrait, MessengerTrait, RedirectDestinationTrait, StringTranslationTrait
- class \Drupal\webform_ui\Form\WebformUiElementTypeFormBase uses WebformDialogFormTrait
Expanded class hierarchy of WebformUiElementTypeFormBase
File
- modules/
webform_ui/ src/ Form/ WebformUiElementTypeFormBase.php, line 22
Namespace
Drupal\webform_ui\FormView source
abstract class WebformUiElementTypeFormBase extends FormBase {
use WebformDialogFormTrait;
/**
* The webform element manager.
*
* @var \Drupal\webform\Plugin\WebformElementManagerInterface
*/
protected $elementManager;
/**
* The current user.
*
* @var \Drupal\Core\Session\AccountInterface
*/
protected $currentUser;
/**
* The user data service.
*
* @var \Drupal\user\UserDataInterface
*/
protected $userData;
/**
* A temp webform.
*
* @var \Drupal\webform\WebformInterface
*/
protected $webform;
/**
* A temp webform submission.
*
* @var \Drupal\webform\WebformSubmissionInterface
*/
protected $webformSubmission;
/**
* {@inheritdoc}
*/
public static function create(ContainerInterface $container) {
$instance = parent::create($container);
$instance->elementManager = $container
->get('plugin.manager.webform.element');
$instance->currentUser = $container
->get('current_user');
$instance->userData = $container
->get('user.data');
$instance->webform = Webform::create([
'id' => '_webform_ui_temp_form',
]);
$instance->webformSubmission = WebformSubmission::create([
'webform' => $instance->webform,
]);
return $instance;
}
/**
* {@inheritdoc}
*/
public function buildForm(array $form, FormStateInterface $form_state, WebformInterface $webform = NULL) {
$form['#prefix'] = '<div id="webform-ui-element-type-ajax-wrapper">';
$form['#suffix'] = '</div>';
$form['#attached']['library'][] = 'webform/webform.admin';
$form['#attached']['library'][] = 'webform/webform.form';
$form['#attached']['library'][] = 'webform/webform.tooltip';
$form['#attached']['library'][] = 'webform_ui/webform_ui';
if (!$this
->isOffCanvasDialog()) {
$form['preview'] = [
'#type' => 'submit',
'#validate' => [
'::noValidate',
],
'#limit_validation_errors' => [],
'#value' => $this
->isPreviewEnabled() ? $this
->t('Hide preview') : $this
->t('Show preview'),
'#attributes' => [
'class' => [
'button--small',
],
'style' => 'float: right;',
],
'#ajax' => [
'callback' => '::submitAjaxForm',
'event' => 'click',
'progress' => [
'type' => 'fullscreen',
],
],
];
}
$form['filter'] = [
'#type' => 'search',
'#title' => $this
->t('Filter'),
'#title_display' => 'invisible',
'#size' => 30,
'#placeholder' => $this
->t('Filter by element name'),
'#attributes' => [
'class' => [
'webform-form-filter-text',
],
'data-element' => '.webform-ui-element-type-table',
'data-item-singlular' => $this
->t('element'),
'data-item-plural' => $this
->t('elements'),
'data-no-results' => '.webform-element-no-results',
'title' => $this
->t('Enter a part of the element name to filter by.'),
'autofocus' => 'autofocus',
],
];
// No results.
$form['no_results'] = [
'#type' => 'webform_message',
'#message_message' => $this
->t('No elements found. Try a different search.'),
'#message_type' => 'info',
'#attributes' => [
'class' => [
'webform-element-no-results',
],
],
'#weight' => 1000,
];
return $form;
}
/**
* Never trigger validation.
*/
public function noValidate(array &$form, FormStateInterface $form_state) {
$form_state
->clearErrors();
}
/**
* {@inheritdoc}
*/
public function submitForm(array &$form, FormStateInterface $form_state) {
$preview = $this->userData
->get('webform_ui', $this->currentUser
->id(), 'element_type_preview') ?: FALSE;
$this->userData
->set('webform_ui', $this->currentUser
->id(), 'element_type_preview', !$preview);
$form_state
->clearErrors();
$form_state
->setRebuild();
}
/**
* Submit form #ajax callback.
*
* @param array $form
* An associative array containing the structure of the form.
* @param \Drupal\Core\Form\FormStateInterface $form_state
* The current state of the form.
*
* @return \Drupal\Core\Ajax\AjaxResponse
* An Ajax response that display validation error messages or redirects
* to a URL
*/
public function submitAjaxForm(array &$form, FormStateInterface $form_state) {
// Remove #id from wrapper so that the form is still wrapped in a <div>
// and triggerable.
// @see js/webform.element.details.toggle.js
$form['#prefix'] = '<div>';
$response = new AjaxResponse();
$response
->addCommand(new HtmlCommand('#webform-ui-element-type-ajax-wrapper', $form));
return $response;
}
/****************************************************************************/
// Table methods.
/****************************************************************************/
/**
* Get table header.
*
* @return array
* An array containing table header.
*/
protected function getHeader() {
$header = [];
$header['type'] = [
'data' => $this
->t('Type'),
'width' => '140',
];
if ($this
->isPreviewEnabled()) {
$header['preview'] = [
'data' => $this
->t('Preview'),
'class' => [
RESPONSIVE_PRIORITY_LOW,
],
];
}
$header['operation'] = [
'width' => '140',
];
return $header;
}
/**
* Build element type row.
*
* @param \Drupal\webform\Plugin\WebformElementInterface $webform_element
* Webform element plugin.
* @param \Drupal\Core\Url $url
* A URL.
* @param string $label
* Operation label.
*
* @return array
* A renderable array containing the element type row.
*/
protected function buildRow(WebformElementInterface $webform_element, Url $url, $label) {
$row = [];
// Type.
$row['type']['link'] = [
'#type' => 'link',
'#title' => $webform_element
->getPluginLabel(),
'#url' => $url,
'#attributes' => WebformDialogHelper::getOffCanvasDialogAttributes($webform_element
->getOffCanvasWidth()),
'#prefix' => '<span class="webform-form-filter-text-source">',
'#suffix' => '</span>',
];
$row['type']['help'] = [
'#type' => 'webform_help',
'#help' => $webform_element
->getPluginDescription(),
'#help_title' => $webform_element
->getPluginLabel(),
];
// Preview.
if ($this
->isPreviewEnabled()) {
$row['preview'] = $this
->buildElementPreview($webform_element);
}
// Operation.
$row['operation'] = [
'#type' => 'link',
'#title' => $label,
// Must clone the URL object to prevent the above 'label' link attributes
// (i.e. webform-tooltip-link) from being copied to 'operation' link.
'#url' => clone $url,
'#attributes' => WebformDialogHelper::getOffCanvasDialogAttributes($webform_element
->getOffCanvasWidth(), [
'button',
'button--primary',
'button--small',
]),
];
// Issue #2741877 Nested modals don't work: when using CKEditor in a
// modal, then clicking the image button opens another modal,
// which closes the original modal.
// @todo Remove the below workaround once this issue is resolved.
if ($webform_element
->getTypeName() === 'processed_text' && !WebformDialogHelper::useOffCanvas()) {
unset($row['type']['#attributes']);
unset($row['operation']['#attributes']);
if (isset($row['operation'])) {
$row['operation']['#attributes']['class'] = [
'button',
'button--primary',
'button--small',
];
}
$row['type']['#attributes']['class'][] = 'js-webform-tooltip-link';
$row['type']['#attributes']['class'][] = 'webform-tooltip-link';
$row['type']['#attributes']['title'] = $webform_element
->getPluginDescription();
}
return $row;
}
/****************************************************************************/
// Preview methods.
/****************************************************************************/
/**
* Determine if webform element type preview is enabled.
*
* @return bool
* TRUE if webform element type preview is enabled.
*/
protected function isPreviewEnabled() {
if ($this
->isOffCanvasDialog()) {
return FALSE;
}
return $this->userData
->get('webform_ui', $this->currentUser
->id(), 'element_type_preview') ?: FALSE;
}
/**
* Build and fully initialize and prepare a preview of a webform element.
*
* @param \Drupal\webform\Plugin\WebformElementInterface $webform_element
* A webform element plugin.
*
* @return array
* A fully initialized and prepared preview of a webform element.
*/
protected function buildElementPreview(WebformElementInterface $webform_element) {
$element = $webform_element
->preview();
if ($element) {
$webform_element
->initialize($element);
$webform_element
->prepare($element, $this->webformSubmission);
if ($webform_element
->hasProperty('title_display') && $webform_element
->getDefaultProperty('title_display') !== 'after') {
$element['#title_display'] = 'invisible';
}
}
// Placeholders.
switch ($webform_element
->getTypeName()) {
case 'container':
$element = $this
->buildElementPreviewPlaceholder($this
->t('Displays an HTML container. (i.e. @div)', [
'@div' => '<div>',
]));
break;
case 'hidden':
$element = $this
->buildElementPreviewPlaceholder($this
->t('Hidden element (less secure, changeable via JavaScript)'));
break;
case 'label':
$element = $this
->buildElementPreviewPlaceholder($this
->t('Displays a form label without any associated element. (i.e. @label)', [
'@label' => '<label>',
]));
break;
case 'processed_text':
$element = $this
->buildElementPreviewPlaceholder($this
->t('Advanced HTML markup rendered using a text format.'));
break;
case 'table':
$element = $this
->buildElementPreviewPlaceholder($this
->t('Displays a custom table. (i.e. @table).', [
'@table' => '<table>',
]) . '<br/><em>' . $this
->t('Requires understanding <a href=":href">how to build tables using render arrays</a>.', [
':href' => $webform_element
->getPluginApiUrl()
->toString(),
]) . '</em>');
break;
case 'value':
$element = $this
->buildElementPreviewPlaceholder($this
->t('Secure value (changeable via server-side code and tokens).'));
break;
case 'webform_computed_token':
$element = $this
->buildElementPreviewPlaceholder($this
->t('Allows value to be computed using [tokens].'));
break;
case 'webform_computed_twig':
$element = $this
->buildElementPreviewPlaceholder($this
->t('Allows value to be computed using a {{ Twig }} template.'));
break;
case 'webform_markup':
$element = $this
->buildElementPreviewPlaceholder($this
->t('Basic HTML markup.'));
break;
case 'webform_section':
$default_section_title_tag = $this
->config('webform.settings')
->get('element.default_section_title_tag');
$element = $this
->buildElementPreviewPlaceholder($this
->t('Displays a section container (i.e. @section) with a header (i.e. @header).', [
'@section' => '<section>',
'@header' => '<' . $default_section_title_tag . '>',
]));
break;
}
// Disable all file uploads.
if ($webform_element instanceof WebformManagedFileBase) {
$element['#disabled'] = TRUE;
}
// Custom element type specific attributes.
switch ($webform_element
->getTypeName()) {
case 'details':
case 'fieldset':
case 'webform_email_confirm':
// Title needs to be displayed.
unset($element['#title_display']);
break;
case 'textarea':
case 'webform_codemirror':
case 'webform_rating':
// Notice: Undefined index: #value in template_preprocess_textarea()
// (line 382 of core/includes/form.inc).
$element['#value'] = '';
break;
case 'password':
// https://stackoverflow.com/questions/15738259/disabling-chrome-autofill
$element['#attributes']['autocomplete'] = 'new-password';
break;
case 'webform_actions':
$element = [
'#type' => 'button',
'#value' => $this
->t('Submit'),
'#attributes' => [
'onclick' => 'return false;',
],
];
break;
case 'webform_email_multiple':
// Notice: Undefined index: #description_display in
// template_preprocess_form_element()
// (line 476 of core/includes/form.inc).
$element['#description_display'] = 'after';
break;
case 'webform_flexbox':
$element['#type'] = 'webform_flexbox';
$element += [
'element_flex_1' => [
'#type' => 'textfield',
'#title' => $this
->t('Flex: 1'),
'#flex' => 1,
'#prefix' => '<div class="webform-flex webform-flex--1"><div class="webform-flex--container">',
'#suffix' => '</div></div>',
],
'element_flex_2' => [
'#type' => 'textfield',
'#title' => $this
->t('Flex: 2'),
'#flex' => 2,
'#prefix' => '<div class="webform-flex webform-flex--2"><div class="webform-flex--container">',
'#suffix' => '</div></div>',
],
];
break;
case 'webform_toggles':
$element['#options_display'] = 'side_by_side';
break;
case 'webform_terms_of_service':
unset($element['#title_display']);
break;
}
// Add placeholder for empty element.
if (empty($element)) {
$element = $this
->buildElementPreviewPlaceholder($this
->t('No preview available.'));
}
// Required attributes.
$element['#id'] = $webform_element
->getTypeName();
$element['#webform_key'] = $webform_element
->getTypeName();
return $element;
}
/**
* Build preview placeholder for webform element.
*
* @param string $text
* Placeholder text.
*
* @return array
* A preview placeholder for webform element.
*/
protected function buildElementPreviewPlaceholder($text) {
return [
'#markup' => $text,
'#prefix' => '<div class="webform-ui-element-type-placeholder">',
'#suffix' => '</div>',
];
}
/****************************************************************************/
// Helper methods.
/****************************************************************************/
/**
* Gets the sorted definition of all WebformElement plugins.
*
* @return array
* An array of WebformElement plugin definitions. Keys are element types.
*/
protected function getDefinitions() {
$definitions = $this->elementManager
->getDefinitions();
$definitions = $this->elementManager
->getSortedDefinitions($definitions, 'category');
$definitions = $this->elementManager
->removeExcludeDefinitions($definitions);
$grouped_definitions = $this->elementManager
->getGroupedDefinitions($definitions);
$sorted_definitions = [];
foreach ($grouped_definitions as $grouped_definition) {
$sorted_definitions += $grouped_definition;
}
return $sorted_definitions;
}
}
Members
Name | Modifiers | Type | Description | Overrides |
---|---|---|---|---|
DependencySerializationTrait:: |
protected | property | ||
DependencySerializationTrait:: |
protected | property | ||
DependencySerializationTrait:: |
public | function | 2 | |
DependencySerializationTrait:: |
public | function | 2 | |
FormBase:: |
protected | property | The config factory. | 3 |
FormBase:: |
protected | property | The request stack. | 1 |
FormBase:: |
protected | property | The route match. | |
FormBase:: |
protected | function | Retrieves a configuration object. | |
FormBase:: |
protected | function | Gets the config factory for this form. | 3 |
FormBase:: |
private | function | Returns the service container. | |
FormBase:: |
protected | function | Gets the current user. | |
FormBase:: |
protected | function | Gets the request object. | |
FormBase:: |
protected | function | Gets the route match. | |
FormBase:: |
protected | function | Gets the logger for a specific channel. | |
FormBase:: |
protected | function | Returns a redirect response object for the specified route. | |
FormBase:: |
public | function | Resets the configuration factory. | |
FormBase:: |
public | function | Sets the config factory for this form. | |
FormBase:: |
public | function | Sets the request stack object to use. | |
FormBase:: |
public | function |
Form validation handler. Overrides FormInterface:: |
72 |
FormInterface:: |
public | function | Returns a unique string identifying the form. | 264 |
LoggerChannelTrait:: |
protected | property | The logger channel factory service. | |
LoggerChannelTrait:: |
protected | function | Gets the logger for a specific channel. | |
LoggerChannelTrait:: |
public | function | Injects the logger channel factory. | |
MessengerTrait:: |
protected | property | The messenger. | 27 |
MessengerTrait:: |
public | function | Gets the messenger. | 27 |
MessengerTrait:: |
public | function | Sets the messenger. | |
RedirectDestinationTrait:: |
protected | property | The redirect destination service. | 1 |
RedirectDestinationTrait:: |
protected | function | Prepares a 'destination' URL query parameter for use with \Drupal\Core\Url. | |
RedirectDestinationTrait:: |
protected | function | Returns the redirect destination service. | |
RedirectDestinationTrait:: |
public | function | Sets the redirect destination service. | |
StringTranslationTrait:: |
protected | property | The string translation service. | 4 |
StringTranslationTrait:: |
protected | function | Formats a string containing a count of items. | |
StringTranslationTrait:: |
protected | function | Returns the number of plurals supported by a given language. | |
StringTranslationTrait:: |
protected | function | Gets the string translation service. | |
StringTranslationTrait:: |
public | function | Sets the string translation service to use. | 2 |
StringTranslationTrait:: |
protected | function | Translates a string to the current language or to a given language. | |
WebformAjaxFormTrait:: |
protected | function | Queue announcement with Ajax response. | |
WebformAjaxFormTrait:: |
protected | function | Add Ajax support to a form. | |
WebformAjaxFormTrait:: |
protected | function | Create an AjaxResponse or WebformAjaxResponse object. | |
WebformAjaxFormTrait:: |
protected | function | Get announcements. | |
WebformAjaxFormTrait:: |
protected | function | Get default ajax callback settings. | 1 |
WebformAjaxFormTrait:: |
protected | function | Get redirect URL from the form's state. | |
WebformAjaxFormTrait:: |
protected | function | Get the form's Ajax wrapper id. | 1 |
WebformAjaxFormTrait:: |
protected | function | Determine if Ajax callback is callable. | |
WebformAjaxFormTrait:: |
protected | function | Is the current request for an Ajax modal/dialog. | |
WebformAjaxFormTrait:: |
protected | function | Is the current request for an off canvas dialog. | |
WebformAjaxFormTrait:: |
protected | function | Handle missing Ajax callback. | |
WebformAjaxFormTrait:: |
protected | function | Replace form via an Ajax response. | 1 |
WebformAjaxFormTrait:: |
protected | function | Reset announcements. | |
WebformAjaxFormTrait:: |
protected | function | Set announcements. | |
WebformAjaxFormTrait:: |
public | function | Validate form #ajax callback. | 1 |
WebformDialogFormTrait:: |
protected | function | Add modal dialog support to a confirm form. | |
WebformDialogFormTrait:: |
protected | function | Build webform dialog delete link. | |
WebformDialogFormTrait:: |
protected | function | Add modal dialog support to a form. | |
WebformDialogFormTrait:: |
public | function |
Cancel form #ajax callback. Overrides WebformAjaxFormTrait:: |
1 |
WebformDialogFormTrait:: |
public | function | Close dialog. | |
WebformDialogFormTrait:: |
protected | function |
Returns if webform is using Ajax. Overrides WebformAjaxFormTrait:: |
1 |
WebformDialogFormTrait:: |
public | function |
Empty submit callback used to only have the submit button to use an #ajax submit callback. Overrides WebformAjaxFormTrait:: |
|
WebformUiElementTypeFormBase:: |
protected | property | The current user. | |
WebformUiElementTypeFormBase:: |
protected | property | The webform element manager. | |
WebformUiElementTypeFormBase:: |
protected | property | The user data service. | |
WebformUiElementTypeFormBase:: |
protected | property | A temp webform. | |
WebformUiElementTypeFormBase:: |
protected | property | A temp webform submission. | |
WebformUiElementTypeFormBase:: |
protected | function | Build and fully initialize and prepare a preview of a webform element. | |
WebformUiElementTypeFormBase:: |
protected | function | Build preview placeholder for webform element. | |
WebformUiElementTypeFormBase:: |
public | function |
Form constructor. Overrides FormInterface:: |
2 |
WebformUiElementTypeFormBase:: |
protected | function | Build element type row. | |
WebformUiElementTypeFormBase:: |
public static | function |
Instantiates a new instance of this class. Overrides FormBase:: |
|
WebformUiElementTypeFormBase:: |
protected | function | Gets the sorted definition of all WebformElement plugins. | |
WebformUiElementTypeFormBase:: |
protected | function | Get table header. | |
WebformUiElementTypeFormBase:: |
protected | function | Determine if webform element type preview is enabled. | |
WebformUiElementTypeFormBase:: |
public | function |
Never trigger validation. Overrides WebformDialogFormTrait:: |
|
WebformUiElementTypeFormBase:: |
public | function |
Submit form #ajax callback. Overrides WebformAjaxFormTrait:: |
|
WebformUiElementTypeFormBase:: |
public | function |
Form submission handler. Overrides FormInterface:: |