Issue #1174938 by ericduran, aspilicious, voxpelli, David_Rothstein, effulgentsia: Added Natively support the HTML5 #required FAPI property.
parent
97674b9f05
commit
d672bcc401
|
@ -3104,6 +3104,19 @@ function form_pre_render_conditional_form_element($element) {
|
|||
return $element;
|
||||
}
|
||||
|
||||
/**
|
||||
* Processes a form button element.
|
||||
*/
|
||||
function form_process_button($element, $form_state) {
|
||||
// If this is a button intentionally allowing incomplete form submission
|
||||
// (e.g., a "Previous" or "Add another item" button), then also skip
|
||||
// client-side validation.
|
||||
if (isset($element['#limit_validation_errors']) && $element['#limit_validation_errors'] !== FALSE) {
|
||||
$element['#attributes']['formnovalidate'] = 'formnovalidate';
|
||||
}
|
||||
return $element;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the #checked property of a checkbox element.
|
||||
*/
|
||||
|
@ -4312,6 +4325,10 @@ function _form_set_class(&$element, $class = array()) {
|
|||
// form_builder().
|
||||
if (!empty($element['#required'])) {
|
||||
$element['#attributes']['class'][] = 'required';
|
||||
// @todo Rename the _form_set_class() function to reflect that we're setting
|
||||
// non-class attributes too.
|
||||
$element['#attributes']['required'] = 'required';
|
||||
$element['#attributes']['aria-required'] = 'true';
|
||||
}
|
||||
if (isset($element['#parents']) && form_get_error($element)) {
|
||||
$element['#attributes']['class'][] = 'error';
|
||||
|
|
|
@ -451,6 +451,29 @@ class FormsTestCase extends DrupalWebTestCase {
|
|||
$this->drupalPost(NULL, array('checkboxes[one]' => TRUE, 'checkboxes[two]' => TRUE), t('Submit'));
|
||||
$this->assertText('An illegal choice has been detected.', t('Input forgery was detected.'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests required attribute.
|
||||
*/
|
||||
function testRequiredAttribute() {
|
||||
$this->drupalGet('form-test/required-attribute');
|
||||
$expected = 'required';
|
||||
// Test to make sure the elements have the proper required attribute.
|
||||
foreach (array('textfield', 'password') as $type) {
|
||||
$element = $this->xpath('//input[@id=:id and @required=:expected]', array(
|
||||
':id' => 'edit-' . $type,
|
||||
':expected' => $expected,
|
||||
));
|
||||
$this->assertTrue(!empty($element), t('The @type has the proper required attribute.', array('@type' => $type)));
|
||||
}
|
||||
|
||||
// Test to make sure textarea has the proper required attribute.
|
||||
$element = $this->xpath('//textarea[@id=:id and @required=:expected]', array(
|
||||
':id' => 'edit-textarea',
|
||||
':expected' => $expected,
|
||||
));
|
||||
$this->assertTrue(!empty($element), t('The textarea has the proper required attribute.'));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -633,6 +656,25 @@ class FormValidationTestCase extends DrupalWebTestCase {
|
|||
);
|
||||
$path = 'form-test/limit-validation-errors';
|
||||
|
||||
// Render the form, and verify that the buttons with limited server-side
|
||||
// validation have the proper 'formnovalidate' attribute (to prevent
|
||||
// client-side validation by the browser).
|
||||
$this->drupalGet($path);
|
||||
$expected = 'formnovalidate';
|
||||
foreach (array('partial', 'partial-numeric-index', 'substring') as $type) {
|
||||
$element = $this->xpath('//input[@id=:id and @formnovalidate=:expected]', array(
|
||||
':id' => 'edit-' . $type,
|
||||
':expected' => $expected,
|
||||
));
|
||||
$this->assertTrue(!empty($element), t('The @type button has the proper formnovalidate attribute.', array('@type' => $type)));
|
||||
}
|
||||
// The button with full server-side validation should not have the
|
||||
// 'formnovalidate' attribute.
|
||||
$element = $this->xpath('//input[@id=:id and not(@formnovalidate)]', array(
|
||||
':id' => 'edit-full',
|
||||
));
|
||||
$this->assertTrue(!empty($element), t('The button with full server-side validation does not have the formnovalidate attribute.'));
|
||||
|
||||
// Submit the form by pressing the 'Partial validate' button (uses
|
||||
// #limit_validation_errors) and ensure that the title field is not
|
||||
// validated, but the #element_validate handler for the 'test' field
|
||||
|
|
|
@ -229,6 +229,13 @@ function form_test_menu() {
|
|||
'type' => MENU_CALLBACK,
|
||||
);
|
||||
|
||||
$items['form-test/required-attribute'] = array(
|
||||
'title' => 'Required',
|
||||
'page callback' => 'drupal_get_form',
|
||||
'page arguments' => array('form_test_required_attribute'),
|
||||
'access callback' => TRUE,
|
||||
);
|
||||
|
||||
return $items;
|
||||
}
|
||||
|
||||
|
@ -1830,3 +1837,18 @@ function form_test_checkboxes_zero($form, &$form_state, $json = TRUE) {
|
|||
function _form_test_checkboxes_zero_no_redirect($form, &$form_state) {
|
||||
$form_state['redirect'] = FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds a form to test the required attribute.
|
||||
*/
|
||||
function form_test_required_attribute($form, &$form_state) {
|
||||
foreach (array('textfield', 'textarea', 'password') as $type) {
|
||||
$form[$type] = array(
|
||||
'#type' => $type,
|
||||
'#required' => TRUE,
|
||||
'#title' => $type,
|
||||
);
|
||||
}
|
||||
|
||||
return $form;
|
||||
}
|
||||
|
|
|
@ -333,7 +333,7 @@ function system_element_info() {
|
|||
'#button_type' => 'submit',
|
||||
'#executes_submit_callback' => TRUE,
|
||||
'#limit_validation_errors' => FALSE,
|
||||
'#process' => array('ajax_process_form'),
|
||||
'#process' => array('form_process_button', 'ajax_process_form'),
|
||||
'#theme_wrappers' => array('button'),
|
||||
);
|
||||
$types['button'] = array(
|
||||
|
@ -342,7 +342,7 @@ function system_element_info() {
|
|||
'#button_type' => 'submit',
|
||||
'#executes_submit_callback' => FALSE,
|
||||
'#limit_validation_errors' => FALSE,
|
||||
'#process' => array('ajax_process_form'),
|
||||
'#process' => array('form_process_button', 'ajax_process_form'),
|
||||
'#theme_wrappers' => array('button'),
|
||||
);
|
||||
$types['image_button'] = array(
|
||||
|
@ -350,7 +350,7 @@ function system_element_info() {
|
|||
'#button_type' => 'submit',
|
||||
'#executes_submit_callback' => TRUE,
|
||||
'#limit_validation_errors' => FALSE,
|
||||
'#process' => array('ajax_process_form'),
|
||||
'#process' => array('form_process_button', 'ajax_process_form'),
|
||||
'#return_value' => TRUE,
|
||||
'#has_garbage_value' => TRUE,
|
||||
'#src' => NULL,
|
||||
|
|
Loading…
Reference in New Issue