1<?php 2 3namespace Drupal\Core\Render\Element; 4 5use Drupal\Core\Form\FormStateInterface; 6use Drupal\Core\Render\Element; 7 8/** 9 * Provides an action button form element. 10 * 11 * When the button is pressed, the form will be submitted to Drupal, where it is 12 * validated and rebuilt. The submit handler is not invoked. 13 * 14 * Properties: 15 * - #limit_validation_errors: An array of form element keys that will block 16 * form submission when validation for these elements or any child elements 17 * fails. Specify an empty array to suppress all form validation errors. 18 * - #value: The text to be shown on the button. 19 * 20 * 21 * Usage Example: 22 * @code 23 * $form['actions']['preview'] = array( 24 * '#type' => 'button', 25 * '#value' => $this->t('Preview'), 26 * ); 27 * @endcode 28 * 29 * @see \Drupal\Core\Render\Element\Submit 30 * 31 * @FormElement("button") 32 */ 33class Button extends FormElement { 34 35 /** 36 * {@inheritdoc} 37 */ 38 public function getInfo() { 39 $class = static::class; 40 return [ 41 '#input' => TRUE, 42 '#name' => 'op', 43 '#is_button' => TRUE, 44 '#executes_submit_callback' => FALSE, 45 '#limit_validation_errors' => FALSE, 46 '#process' => [ 47 [$class, 'processButton'], 48 [$class, 'processAjaxForm'], 49 ], 50 '#pre_render' => [ 51 [$class, 'preRenderButton'], 52 ], 53 '#theme_wrappers' => ['input__submit'], 54 ]; 55 } 56 57 /** 58 * Processes a form button element. 59 */ 60 public static function processButton(&$element, FormStateInterface $form_state, &$complete_form) { 61 // If this is a button intentionally allowing incomplete form submission 62 // (e.g., a "Previous" or "Add another item" button), then also skip 63 // client-side validation. 64 if (isset($element['#limit_validation_errors']) && $element['#limit_validation_errors'] !== FALSE) { 65 $element['#attributes']['formnovalidate'] = 'formnovalidate'; 66 } 67 return $element; 68 } 69 70 /** 71 * Prepares a #type 'button' render element for input.html.twig. 72 * 73 * @param array $element 74 * An associative array containing the properties of the element. 75 * Properties used: #attributes, #button_type, #name, #value. The 76 * #button_type property accepts any value, though core themes have CSS that 77 * styles the following button_types appropriately: 'primary', 'danger'. 78 * 79 * @return array 80 * The $element with prepared variables ready for input.html.twig. 81 */ 82 public static function preRenderButton($element) { 83 $element['#attributes']['type'] = 'submit'; 84 Element::setAttributes($element, ['id', 'name', 'value']); 85 86 $element['#attributes']['class'][] = 'button'; 87 if (!empty($element['#button_type'])) { 88 $element['#attributes']['class'][] = 'button--' . $element['#button_type']; 89 } 90 $element['#attributes']['class'][] = 'js-form-submit'; 91 $element['#attributes']['class'][] = 'form-submit'; 92 93 if (!empty($element['#attributes']['disabled'])) { 94 $element['#attributes']['class'][] = 'is-disabled'; 95 } 96 97 return $element; 98 } 99 100} 101