Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Loading…

Added "required" attribute to input element based on validation rules fo... #1037

Merged
merged 1 commit into from

4 participants

@ADmad
Collaborator

...r field

@lorenzo
Owner

This is a neat idea

@ceeram
Collaborator
@ADmad
Collaborator

As an alternative way for specifying doctype I was thinking of having View::$docType property which you could change from controller with special var like this: $this->set('_docType', 'xhtml'); if needed.

The benefit of having doctype as a view property is all helpers could access a common property, instead of having it at multiple places as helper settings or function defaults eg. HtmlHelper::docType().

@lorenzo
Owner

Actually, you should just remove the doctype check... we are already outputting html5 markup in the forms without checking (like email and number fields)

@ADmad
Collaborator

The check is necessary as if you are using XHTML and add the required attribute for input element your document won't validate.

@ADmad
Collaborator

Hmm.. using type "email", "number" etc. would also cause document to fail to validate as xhtml.

@lorenzo
Owner
@ADmad
Collaborator

Right. So I guess I will just remove the doctype check.

@ceeram
Collaborator

I think we should keep the check, the email and number types is up to the user to use ot not depending on the doctype. For adding required, the helper needs to decide if it can add it or not. I think defaulting to html5 should be avoided, the user should specifically set the doctype to html5 to get the required added

@ADmad
Collaborator

@ceeram But by default it already generates invalid xhtml.. Eg. if your db field type is integer Form::input() will automatically create a <input type="number" /> which would fail as xhtml.

@markstory
Owner

Including various markup for different doctypes is a pretty big swamp depending how many you use. HTML5 is clearly the path forward, and moving from an XHTML strict to an HTML5 doctype is usually a painless transition. Where possible I think its best to output html5 by default. With that said, we should also update the default layouts as the scaffolded views + bake generated HTML is all invalid :cry:

@ADmad
Collaborator

Agreed, managing markup for multiple doctype can get messy. I removed the doctype check. One can use FormHelper::inputDefaults() to turn off setting the required attribute globally if needed.

@ADmad
Collaborator

@markstory @lorenzo This looks good to be merged now?

@lorenzo lorenzo merged commit 9f5549a into from
@ADmad ADmad deleted the branch
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Dec 21, 2012
  1. @ADmad
This page is out of date. Refresh to see the latest.
View
45 lib/Cake/Test/Case/View/Helper/FormHelperTest.php
@@ -3577,7 +3577,13 @@ public function testRadio() {
$result = $this->Form->radio('Contact.1.imrequired', array('option A'));
$expected = array(
'input' => array('type' => 'hidden', 'name' => 'data[Contact][1][imrequired]', 'value' => '', 'id' => 'Contact1Imrequired_'),
- array('input' => array('type' => 'radio', 'name' => 'data[Contact][1][imrequired]', 'value' => '0', 'id' => 'Contact1Imrequired0')),
+ array('input' => array(
+ 'type' => 'radio',
+ 'name' => 'data[Contact][1][imrequired]',
+ 'value' => '0',
+ 'id' => 'Contact1Imrequired0',
+ 'required' => 'required'
+ )),
'label' => array('for' => 'Contact1Imrequired0'),
'option A',
'/label'
@@ -7185,7 +7191,8 @@ public function testFormInputRequiredDetection() {
'/label',
'input' => array(
'type' => 'text', 'name' => 'data[Contact][imrequired]',
- 'id' => 'ContactImrequired'
+ 'id' => 'ContactImrequired',
+ 'required' => 'required'
),
'/div'
);
@@ -7199,7 +7206,8 @@ public function testFormInputRequiredDetection() {
'/label',
'input' => array(
'type' => 'text', 'name' => 'data[Contact][imalsorequired]',
- 'id' => 'ContactImalsorequired'
+ 'id' => 'ContactImalsorequired',
+ 'required' => 'required'
),
'/div'
);
@@ -7213,7 +7221,8 @@ public function testFormInputRequiredDetection() {
'/label',
'input' => array(
'type' => 'text', 'name' => 'data[Contact][imrequiredtoo]',
- 'id' => 'ContactImrequiredtoo'
+ 'id' => 'ContactImrequiredtoo',
+ 'required' => 'required'
),
'/div'
);
@@ -7227,7 +7236,8 @@ public function testFormInputRequiredDetection() {
'/label',
'input' => array(
'type' => 'text', 'name' => 'data[Contact][required_one]',
- 'id' => 'ContactRequiredOne'
+ 'id' => 'ContactRequiredOne',
+ 'required' => 'required'
),
'/div'
);
@@ -7241,7 +7251,8 @@ public function testFormInputRequiredDetection() {
'/label',
'input' => array(
'type' => 'text', 'name' => 'data[Contact][string_required]',
- 'id' => 'ContactStringRequired'
+ 'id' => 'ContactStringRequired',
+ 'required' => 'required'
),
'/div'
);
@@ -7311,7 +7322,8 @@ public function testFormInputRequiredDetection() {
'/label',
'input' => array(
'type' => 'text', 'name' => 'data[Contact][iamrequiredalways]',
- 'id' => 'ContactIamrequiredalways'
+ 'id' => 'ContactIamrequiredalways',
+ 'required' => 'required'
),
'/div'
);
@@ -8216,7 +8228,8 @@ public function testRequiredOnCreate() {
'/label',
'input' => array(
'type' => 'text', 'name' => 'data[Contact][imrequiredoncreate]',
- 'id' => 'ContactImrequiredoncreate'
+ 'id' => 'ContactImrequiredoncreate',
+ 'required' => 'required'
),
'/div'
);
@@ -8230,12 +8243,14 @@ public function testRequiredOnCreate() {
'/label',
'input' => array(
'type' => 'text', 'name' => 'data[Contact][imrequiredonboth]',
- 'id' => 'ContactImrequiredonboth'
+ 'id' => 'ContactImrequiredonboth',
+ 'required' => 'required'
),
'/div'
);
$this->assertTags($result, $expected);
+ $this->Form->inputDefaults(array('required' => false));
$result = $this->Form->input('Contact.imrequired');
$expected = array(
'div' => array('class' => 'input text required'),
@@ -8249,6 +8264,9 @@ public function testRequiredOnCreate() {
'/div'
);
$this->assertTags($result, $expected);
+
+ $result = $this->Form->input('Contact.imrequired', array('required' => false));
+ $this->assertTags($result, $expected);
}
/**
@@ -8268,7 +8286,8 @@ public function testRequiredOnUpdate() {
'/label',
'input' => array(
'type' => 'text', 'name' => 'data[Contact][imrequiredonupdate]',
- 'id' => 'ContactImrequiredonupdate'
+ 'id' => 'ContactImrequiredonupdate',
+ 'required' => 'required'
),
'/div'
);
@@ -8295,7 +8314,8 @@ public function testRequiredOnUpdate() {
'/label',
'input' => array(
'type' => 'text', 'name' => 'data[Contact][imrequiredonboth]',
- 'id' => 'ContactImrequiredonboth'
+ 'id' => 'ContactImrequiredonboth',
+ 'required' => 'required'
),
'/div'
);
@@ -8309,7 +8329,8 @@ public function testRequiredOnUpdate() {
'/label',
'input' => array(
'type' => 'text', 'name' => 'data[Contact][imrequired]',
- 'id' => 'ContactImrequired'
+ 'id' => 'ContactImrequired',
+ 'required' => 'required'
),
'/div'
);
View
20 lib/Cake/View/Helper.php
@@ -145,7 +145,7 @@ class Helper extends Object {
protected $_minimizedAttributes = array(
'compact', 'checked', 'declare', 'readonly', 'disabled', 'selected',
'defer', 'ismap', 'nohref', 'noshade', 'nowrap', 'multiple', 'noresize',
- 'autoplay', 'controls', 'loop', 'muted'
+ 'autoplay', 'controls', 'loop', 'muted', 'required'
);
/**
@@ -418,22 +418,8 @@ public function clean($output) {
}
/**
- * Returns a space-delimited string with items of the $options array. If a
- * key of $options array happens to be one of:
- *
- * - 'compact'
- * - 'checked'
- * - 'declare'
- * - 'readonly'
- * - 'disabled'
- * - 'selected'
- * - 'defer'
- * - 'ismap'
- * - 'nohref'
- * - 'noshade'
- * - 'nowrap'
- * - 'multiple'
- * - 'noresize'
+ * Returns a space-delimited string with items of the $options array. If a key
+ * of $options array happens to be one of those listed in `Helper::$_minimizedAttributes`
*
* And its value is one of:
*
View
5 lib/Cake/View/Helper/FormHelper.php
@@ -2775,6 +2775,11 @@ protected function _initInputField($field, $options = array()) {
if (!empty($result['disabled']) || $secure === self::SECURE_SKIP) {
return $result;
}
+ if (!isset($result['required']) &&
+ $this->_introspectModel($this->model(), 'validates', $this->field())
+ ) {
+ $result['required'] = true;
+ }
$fieldName = null;
if (!empty($options['name'])) {
Something went wrong with that request. Please try again.