FormElement.php in Drupal 8
Same filename in this branch
Same filename and directory in other branches
Namespace
Drupal\Core\Render\ElementFile
core/lib/Drupal/Core/Render/Element/FormElement.phpView source
<?php
namespace Drupal\Core\Render\Element;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Render\BubbleableMetadata;
use Drupal\Core\Url;
/**
* Provides a base class for form element plugins.
*
* Form elements are a subset of render elements, representing elements for
* HTML forms, which can be referenced in form arrays. See the
* @link theme_render Render API topic @endlink for an overview of render
* arrays and render elements, and the @link form_api Form API topic @endlink
* for an overview of forms and form arrays.
*
* The elements of form arrays are divided up into properties (whose keys
* start with #) and children (whose keys do not start with #). The properties
* provide data or settings that are used in rendering and form processing.
* Some properties are specific to a particular type of form/render element,
* some are available for any render element, and some are available for any
* form input element. A list of the properties that are available for all form
* elements follows; see \Drupal\Core\Render\Element\RenderElement for some
* additional information, as well as a list of properties that are common to
* all render elements (including form elements). Properties specific to a
* particular element are documented on that element's class.
*
* Here is a list of properties that are used during the rendering and form
* processing of form elements:
* - #after_build: (array) Array of callables or function names, which are
* called after the element is built. Arguments: $element, $form_state.
* - #ajax: (array) Array of elements to specify Ajax behavior. See
* the @link ajax Ajax API topic @endlink for more information.
* - #array_parents: (string[], read-only) Array of names of all the element's
* parents (including itself) in the render array. See also #parents, #tree.
* - #default_value: Default value for the element. See also #value.
* - #description: (string) Help or description text for the element. In an
* ideal user interface, the #title should be enough to describe the element,
* so most elements should not have a description; if you do need one, make
* sure it is translated. If it is not already wrapped in a safe markup
* object, it will be filtered for XSS safety.
* - #disabled: (bool) If TRUE, the element is shown but does not accept
* user input.
* - #element_validate: (array) Array of callables or function names, which
* are called to validate the input. Arguments: $element, $form_state, $form.
* - #field_prefix: (string) Prefix to display before the HTML input element.
* Should be translated, normally. If it is not already wrapped in a safe
* markup object, will be filtered for XSS safety.
* - #field_suffix: (string) Suffix to display after the HTML input element.
* Should be translated, normally. If it is not already wrapped in a safe
* markup object, will be filtered for XSS safety.
* - #input: (bool, internal) Whether or not the element accepts input.
* - #parents: (string[], read-only) Array of names of the element's parents
* for purposes of getting values out of $form_state. See also
* #array_parents, #tree.
* - #process: (array) Array of callables or function names, which are
* called during form building. Arguments: $element, $form_state, $form.
* - #processed: (bool, internal) Set to TRUE when the element is processed.
* - #required: (bool) Whether or not input is required on the element.
* - #states: (array) Information about JavaScript states, such as when to
* hide or show the element based on input on other elements.
* See \Drupal\Core\Form\FormHelper::processStates() for documentation.
* - #title: (string) Title of the form element. Should be translated.
* - #title_display: (string) Where and how to display the #title. Possible
* values:
* - before: Label goes before the element (default for most elements).
* - after: Label goes after the element (default for radio elements).
* - invisible: Label is there but is made invisible using CSS.
* - attribute: Make it the title attribute (hover tooltip).
* - #tree: (bool) TRUE if the values of this element and its children should
* be hierarchical in $form_state; FALSE if the values should be flat.
* See also #parents, #array_parents.
* - #value_callback: (callable) Callable or function name, which is called
* to transform the raw user input to the element's value. Arguments:
* $element, $input, $form_state.
*
* @see \Drupal\Core\Render\Annotation\FormElement
* @see \Drupal\Core\Render\Element\FormElementInterface
* @see \Drupal\Core\Render\ElementInfoManager
* @see plugin_api
*
* @ingroup theme_render
*/
abstract class FormElement extends RenderElement implements FormElementInterface {
/**
* {@inheritdoc}
*/
public static function valueCallback(&$element, $input, FormStateInterface $form_state) {
return NULL;
}
/**
* #process callback for #pattern form element property.
*
* @param array $element
* An associative array containing the properties and children of the
* generic input element.
* @param \Drupal\Core\Form\FormStateInterface $form_state
* The current state of the form.
* @param array $complete_form
* The complete form structure.
*
* @return array
* The processed element.
*/
public static function processPattern(&$element, FormStateInterface $form_state, &$complete_form) {
if (isset($element['#pattern']) && !isset($element['#attributes']['pattern'])) {
$element['#attributes']['pattern'] = $element['#pattern'];
$element['#element_validate'][] = [
get_called_class(),
'validatePattern',
];
}
return $element;
}
/**
* #element_validate callback for #pattern form element property.
*
* @param $element
* An associative array containing the properties and children of the
* generic form element.
* @param $form_state
* The current state of the form.
* @param array $complete_form
* The complete form structure.
*/
public static function validatePattern(&$element, FormStateInterface $form_state, &$complete_form) {
if ($element['#value'] !== '') {
// The pattern must match the entire string and should have the same
// behavior as the RegExp object in ECMA 262.
// - Use bracket-style delimiters to avoid introducing a special delimiter
// character like '/' that would have to be escaped.
// - Put in brackets so that the pattern can't interfere with what's
// prepended and appended.
$pattern = '{^(?:' . $element['#pattern'] . ')$}';
if (!preg_match($pattern, $element['#value'])) {
$form_state
->setError($element, t('%name field is not in the right format.', [
'%name' => $element['#title'],
]));
}
}
}
/**
* Adds autocomplete functionality to elements.
*
* This sets up autocomplete functionality for elements with an
* #autocomplete_route_name property, using the #autocomplete_route_parameters
* property if present.
*
* For example, suppose your autocomplete route name is
* 'mymodule.autocomplete' and its path is
* '/mymodule/autocomplete/{a}/{b}'. In a form array, you would create a text
* field with properties:
* @code
* '#autocomplete_route_name' => 'mymodule.autocomplete',
* '#autocomplete_route_parameters' => array('a' => $some_key, 'b' => $some_id),
* @endcode
* If the user types "keywords" in that field, the full path called would be:
* 'mymodule_autocomplete/$some_key/$some_id?q=keywords'
*
* @param array $element
* The form element to process. Properties used:
* - #autocomplete_route_name: A route to be used as callback URL by the
* autocomplete JavaScript library.
* - #autocomplete_route_parameters: The parameters to be used in
* conjunction with the route name.
* @param \Drupal\Core\Form\FormStateInterface $form_state
* The current state of the form.
* @param array $complete_form
* The complete form structure.
*
* @return array
* The form element.
*/
public static function processAutocomplete(&$element, FormStateInterface $form_state, &$complete_form) {
$url = NULL;
$access = FALSE;
if (!empty($element['#autocomplete_route_name'])) {
$parameters = isset($element['#autocomplete_route_parameters']) ? $element['#autocomplete_route_parameters'] : [];
$url = Url::fromRoute($element['#autocomplete_route_name'], $parameters)
->toString(TRUE);
/** @var \Drupal\Core\Access\AccessManagerInterface $access_manager */
$access_manager = \Drupal::service('access_manager');
$access = $access_manager
->checkNamedRoute($element['#autocomplete_route_name'], $parameters, \Drupal::currentUser(), TRUE);
}
if ($access) {
$metadata = BubbleableMetadata::createFromRenderArray($element);
if ($access
->isAllowed()) {
$element['#attributes']['class'][] = 'form-autocomplete';
$metadata
->addAttachments([
'library' => [
'core/drupal.autocomplete',
],
]);
// Provide a data attribute for the JavaScript behavior to bind to.
$element['#attributes']['data-autocomplete-path'] = $url
->getGeneratedUrl();
$metadata = $metadata
->merge($url);
}
$metadata
->merge(BubbleableMetadata::createFromObject($access))
->applyTo($element);
}
return $element;
}
}
Classes
Name | Description |
---|---|
FormElement | Provides a base class for form element plugins. |