Browse files

Add id suffix generation to radio buttons.

This preserves behavior FormHelper had where it prevents duplicate ids
in a single set of radio options.
  • Loading branch information...
1 parent 912a2ba commit 33fced8e2c4b43b9471cf5463e0fb28c0b6066c8 @markstory markstory committed Feb 15, 2014
Showing with 54 additions and 1 deletion.
  1. +18 −1 src/View/Widget/Radio.php
  2. +36 −0 tests/TestCase/View/Widget/RadioTest.php
View
19 src/View/Widget/Radio.php
@@ -41,6 +41,13 @@ class Radio implements WidgetInterface {
protected $_label;
/**
+ * A list of id suffixes used in the current rendering.
+ *
+ * @var array
+ */
+ protected $_idSuffixes = [];
+
+/**
* Constructor
*
* This class uses a few templates:
@@ -97,6 +104,7 @@ public function render(array $data) {
}
unset($data['empty']);
+ $this->_idSuffixes = [];
$opts = [];
foreach ($options as $val => $text) {
$opts[] = $this->_renderInput($val, $text, $data);
@@ -206,6 +214,15 @@ protected function _renderLabel($radio, $label, $input, $escape) {
* @return string Generated id.
*/
protected function _id($radio) {
- return mb_strtolower(Inflector::slug($radio['name'] . '_' . $radio['value'], '-'));}
+ $value = mb_strtolower(Inflector::slug($radio['name'], '-'));
+ $idSuffix = mb_strtolower(str_replace(array('@', '<', '>', ' ', '"', '\''), '-', $radio['value']));
+ $count = 1;
+ $check = $idSuffix;
+ while (in_array($check, $this->_idSuffixes)) {
+ $check = $idSuffix . $count++;
+ }
+ $this->_idSuffixes[] = $check;
+ return trim($value . '-' . $check, '-');
+ }
}
View
36 tests/TestCase/View/Widget/RadioTest.php
@@ -124,6 +124,42 @@ public function testRenderComplex() {
}
/**
+ * Test that id suffixes are generated to not collide
+ *
+ * @return void
+ */
+ public function testRenderIdSuffixGeneration() {
+ $label = new Label($this->templates);
+ $radio = new Radio($this->templates, $label);
+ $data = [
+ 'name' => 'Thing[value]',
+ 'options' => ['a>b' => 'First', 'a<b' => 'Second']
+ ];
+ $result = $radio->render($data);
+ $expected = [
+ ['input' => [
+ 'type' => 'radio',
+ 'name' => 'Thing[value]',
+ 'value' => 'a&gt;b',
+ 'id' => 'thing-value-a-b'
+ ]],
+ ['label' => ['for' => 'thing-value-a-b']],
+ 'First',
+ '/label',
+ ['input' => [
+ 'type' => 'radio',
+ 'name' => 'Thing[value]',
+ 'value' => 'a&lt;b',
+ 'id' => 'thing-value-a-b2',
+ ]],
+ ['label' => ['for' => 'thing-value-a-b2']],
+ 'Second',
+ '/label',
+ ];
+ $this->assertTags($result, $expected);
+ }
+
+/**
* Test rendering the empty option.
*
* @return void

0 comments on commit 33fced8

Please sign in to comment.