diff --git a/src/View/Widget/Radio.php b/src/View/Widget/Radio.php index e384e79d363..ca42f67fd52 100644 --- a/src/View/Widget/Radio.php +++ b/src/View/Widget/Radio.php @@ -78,6 +78,8 @@ public function __construct($templates, $label) { * - `val` - A string of the option to mark as selected. * - `label` - Either false to disable label generation, or * an array of attributes for all labels. + * - `required` - Set to true to add the required attribute + * on all generated radios. * * @param array $data The data to build radio buttons with. * @return string @@ -152,6 +154,10 @@ protected function _renderInput($val, $text, $data) { $radio['id'] = $this->_id($radio); } + if (isset($data['val']) && is_bool($data['val'])) { + $data['val'] = $data['val'] ? 1 : 0; + } + if (isset($data['val']) && strval($data['val']) === strval($radio['value'])) { $radio['checked'] = true; } @@ -159,6 +165,9 @@ protected function _renderInput($val, $text, $data) { if ($this->_isDisabled($radio, $data['disabled'])) { $radio['disabled'] = true; } + if (!empty($data['required'])) { + $radio['required'] = true; + } $input = $this->_templates->format('radio', [ 'name' => $radio['name'], diff --git a/tests/TestCase/View/Helper/FormHelperTest.php b/tests/TestCase/View/Helper/FormHelperTest.php index 09f3b2ebd50..ba3f88ad2d6 100644 --- a/tests/TestCase/View/Helper/FormHelperTest.php +++ b/tests/TestCase/View/Helper/FormHelperTest.php @@ -4274,139 +4274,17 @@ public function testRadio() { $result = $this->Form->radio('Model.field', array('option A', 'option B'), array('name' => 'Model[custom]')); $expected = array( - 'input' => array('type' => 'hidden', 'name' => 'Model[custom]', 'value' => ''), - array('input' => array('type' => 'radio', 'name' => 'Model[custom]', 'value' => '0', 'id' => 'model-field-0')), - array('label' => array('for' => 'model-field-0')), + array('input' => array('type' => 'hidden', 'name' => 'Model[custom]', 'value' => '')), + array('input' => array('type' => 'radio', 'name' => 'Model[custom]', 'value' => '0', 'id' => 'model-custom-0')), + array('label' => array('for' => 'model-custom-0')), 'option A', '/label', - array('input' => array('type' => 'radio', 'name' => 'Model[custom]', 'value' => '1', 'id' => 'model-field-1')), - array('label' => array('for' => 'model-field-1')), + array('input' => array('type' => 'radio', 'name' => 'Model[custom]', 'value' => '1', 'id' => 'model-custom-1')), + array('label' => array('for' => 'model-custom-1')), 'option B', '/label', ); $this->assertTags($result, $expected); - - $result = $this->Form->radio( - 'Model.field', - array('a>b' => 'first', 'a 'second', 'a"b' => 'third') - ); - $expected = array( - 'input' => array( - 'type' => 'hidden', 'name' => 'data[Model][field]', - 'value' => '', - ), - array('input' => array('type' => 'radio', 'name' => 'data[Model][field]', - 'id' => 'model-field-a-b', 'value' => 'a>b')), - array('label' => array('for' => 'model-field-a-b')), - 'first', - '/label', - array('input' => array('type' => 'radio', 'name' => 'data[Model][field]', - 'id' => 'ModelFieldAB1', 'value' => 'a<b')), - array('label' => array('for' => 'model-field-ab2')), - 'second', - '/label', - array('input' => array('type' => 'radio', 'name' => 'data[Model][field]', - 'id' => 'model-field-ab2', 'value' => 'a"b')), - array('label' => array('for' => 'model-field-ab2')), - 'third', - '/label', - ); - $this->assertTags($result, $expected); - } - -/** - * Test marking radio buttons as required. - * - * @return void - */ - public function testRadioRequired() { - $this->article['required'] = [ - 'published' => true, - ]; - $this->Form->create($this->article); - - $result = $this->Form->radio('published', array('option A', 'optionB')); - $expected = array( - 'input' => array('type' => 'hidden', 'name' => 'published', 'value' => ''), - array('input' => array('type' => 'radio', 'name' => 'published', 'value' => '0', 'id' => 'published-0', 'required' => 'required')), - 'label' => array('for' => 'published-0'), - 'option A', - '/label', - array('input' => array('type' => 'radio', 'name' => 'published', 'value' => '1', 'id' => 'published-1', 'required' => 'required')), - 'label' => array('for' => 'published-1'), - 'option B', - '/label', - ); - $this->assertTags($result, $expected); - } - -/** - * Test that radios with a 0 value are selected under the correct conditions. - * Also ensure that values that are booleanish are handled correctly. - * - * @return void - */ - public function testRadioOptionWithBooleanishValues() { - $expected = array( - array('input' => array('type' => 'radio', 'name' => 'Model[field]', 'value' => '1', 'id' => 'model-field-1')), - array('label' => array('for' => 'model-field-1')), - 'Yes', - '/label', - array('input' => array('type' => 'radio', 'name' => 'Model[field]', 'value' => '0', 'id' => 'model-field-0', 'checked' => 'checked')), - array('label' => array('for' => 'model-field-0')), - 'No', - '/label', - '/fieldset' - ); - $result = $this->Form->radio('Model.field', array('1' => 'Yes', '0' => 'No'), array('value' => '0')); - $this->assertTags($result, $expected); - - $result = $this->Form->radio('Model.field', array('1' => 'Yes', '0' => 'No'), array('value' => 0)); - $this->assertTags($result, $expected); - - $result = $this->Form->radio('Model.field', array('1' => 'Yes', '0' => 'No'), array('value' => false)); - $this->assertTags($result, $expected); - - $expected = array( - 'input' => array('type' => 'hidden', 'name' => 'Model[field]', 'value' => ''), - array('input' => array('type' => 'radio', 'name' => 'Model[field]', 'value' => '1', 'id' => 'model-field-1')), - array('label' => array('for' => 'model-field-1')), - 'Yes', - '/label', - array('input' => array('type' => 'radio', 'name' => 'Model[field]', 'value' => '0', 'id' => 'model-field-0')), - array('label' => array('for' => 'ModelField0')), - 'No', - '/label', - '/fieldset' - ); - $result = $this->Form->radio('Model.field', array('1' => 'Yes', '0' => 'No'), array('value' => null)); - $this->assertTags($result, $expected); - - $result = $this->Form->radio('Model.field', array('1' => 'Yes', '0' => 'No'), array('value' => '')); - $this->assertTags($result, $expected); - - $result = $this->Form->radio('Model.field', array('1' => 'Yes', '0' => 'No')); - $this->assertTags($result, $expected); - - $expected = array( - array('input' => array('type' => 'radio', 'name' => 'Model[field]', 'checked' => 'checked', 'value' => '1', 'id' => 'model-field-1')), - array('label' => array('for' => 'model-field-1')), - 'Yes', - '/label', - array('input' => array('type' => 'radio', 'name' => 'Model[field]', 'value' => '0', 'id' => 'model-field-0')), - array('label' => array('for' => 'model-field-0')), - 'No', - '/label', - '/fieldset' - ); - $result = $this->Form->radio('Model.field', array('1' => 'Yes', '0' => 'No'), array('value' => 1)); - $this->assertTags($result, $expected); - - $result = $this->Form->radio('Model.field', array('1' => 'Yes', '0' => 'No'), array('value' => '1')); - $this->assertTags($result, $expected); - - $result = $this->Form->radio('Model.field', array('1' => 'Yes', '0' => 'No'), array('value' => true)); - $this->assertTags($result, $expected); } /** diff --git a/tests/TestCase/View/Widget/RadioTest.php b/tests/TestCase/View/Widget/RadioTest.php index 4d30235e9b6..ad17241d46a 100644 --- a/tests/TestCase/View/Widget/RadioTest.php +++ b/tests/TestCase/View/Widget/RadioTest.php @@ -150,15 +150,117 @@ public function testRenderIdSuffixGeneration() { 'type' => 'radio', 'name' => 'Thing[value]', 'value' => 'a<b', - 'id' => 'thing-value-a-b2', + 'id' => 'thing-value-a-b1', ]], - ['label' => ['for' => 'thing-value-a-b2']], + ['label' => ['for' => 'thing-value-a-b1']], 'Second', '/label', ]; $this->assertTags($result, $expected); } +/** + * Test rendering checks the right option with booleanish values. + * + * @return void + */ + public function testRenderBooleanishValues() { + $label = new Label($this->templates); + $radio = new Radio($this->templates, $label); + $data = [ + 'name' => 'Model[field]', + 'options' => ['1' => 'Yes', '0' => 'No'], + 'val' => '0' + ]; + $result = $radio->render($data); + $expected = array( + array('input' => array('type' => 'radio', 'name' => 'Model[field]', 'value' => '1', 'id' => 'model-field-1')), + array('label' => array('for' => 'model-field-1')), + 'Yes', + '/label', + array('input' => array('type' => 'radio', 'name' => 'Model[field]', 'value' => '0', 'id' => 'model-field-0', 'checked' => 'checked')), + array('label' => array('for' => 'model-field-0')), + 'No', + '/label', + ); + $this->assertTags($result, $expected); + + $data['val'] = 0; + $result = $radio->render($data); + $this->assertTags($result, $expected); + + $data['val'] = false; + $result = $radio->render($data); + $this->assertTags($result, $expected); + + $expected = array( + array('input' => array('type' => 'radio', 'name' => 'Model[field]', 'value' => '1', 'id' => 'model-field-1')), + array('label' => array('for' => 'model-field-1')), + 'Yes', + '/label', + array('input' => array('type' => 'radio', 'name' => 'Model[field]', 'value' => '0', 'id' => 'model-field-0')), + array('label' => array('for' => 'model-field-0')), + 'No', + '/label', + ); + $data['val'] = null; + $result = $radio->render($data); + $this->assertTags($result, $expected); + + $data['val'] = ''; + $result = $radio->render($data); + $this->assertTags($result, $expected); + + $expected = array( + array('input' => array('type' => 'radio', 'name' => 'Model[field]', 'value' => '1', 'id' => 'model-field-1', 'checked' => 'checked')), + array('label' => array('for' => 'model-field-1')), + 'Yes', + '/label', + array('input' => array('type' => 'radio', 'name' => 'Model[field]', 'value' => '0', 'id' => 'model-field-0')), + array('label' => array('for' => 'model-field-0')), + 'No', + '/label', + ); + $data['val'] = '1'; + $result = $radio->render($data); + $this->assertTags($result, $expected); + + $data['val'] = 1; + $result = $radio->render($data); + $this->assertTags($result, $expected); + + $data['val'] = true; + $result = $radio->render($data); + $this->assertTags($result, $expected); + } + +/** + * Test that render() works with the required attribute. + * + * @return void + */ + public function testRenderRequired() { + $label = new Label($this->templates); + $radio = new Radio($this->templates, $label); + $data = [ + 'name' => 'published', + 'options' => ['option A', 'option B'], + 'required' => true + ]; + $result = $radio->render($data); + $expected = [ + ['input' => ['type' => 'radio', 'name' => 'published', 'value' => '0', 'id' => 'published-0', 'required' => 'required']], + ['label' => ['for' => 'published-0']], + 'option A', + '/label', + ['input' => ['type' => 'radio', 'name' => 'published', 'value' => '1', 'id' => 'published-1', 'required' => 'required']], + ['label' => ['for' => 'published-1']], + 'option B', + '/label', + ]; + $this->assertTags($result, $expected); + } + /** * Test rendering the empty option. *