From 33fced8e2c4b43b9471cf5463e0fb28c0b6066c8 Mon Sep 17 00:00:00 2001 From: mark_story Date: Sat, 15 Feb 2014 11:50:25 -0500 Subject: [PATCH] Add id suffix generation to radio buttons. This preserves behavior FormHelper had where it prevents duplicate ids in a single set of radio options. --- src/View/Widget/Radio.php | 19 ++++++++++++- tests/TestCase/View/Widget/RadioTest.php | 36 ++++++++++++++++++++++++ 2 files changed, 54 insertions(+), 1 deletion(-) diff --git a/src/View/Widget/Radio.php b/src/View/Widget/Radio.php index bc459448e24..e384e79d363 100644 --- a/src/View/Widget/Radio.php +++ b/src/View/Widget/Radio.php @@ -40,6 +40,13 @@ class Radio implements WidgetInterface { */ protected $_label; +/** + * A list of id suffixes used in the current rendering. + * + * @var array + */ + protected $_idSuffixes = []; + /** * Constructor * @@ -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, '-'); + } } diff --git a/tests/TestCase/View/Widget/RadioTest.php b/tests/TestCase/View/Widget/RadioTest.php index 58151b6a7f3..4d30235e9b6 100644 --- a/tests/TestCase/View/Widget/RadioTest.php +++ b/tests/TestCase/View/Widget/RadioTest.php @@ -123,6 +123,42 @@ public function testRenderComplex() { $this->assertTags($result, $expected); } +/** + * 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 'Second'] + ]; + $result = $radio->render($data); + $expected = [ + ['input' => [ + 'type' => 'radio', + 'name' => 'Thing[value]', + 'value' => 'a>b', + 'id' => 'thing-value-a-b' + ]], + ['label' => ['for' => 'thing-value-a-b']], + 'First', + '/label', + ['input' => [ + 'type' => 'radio', + 'name' => 'Thing[value]', + 'value' => 'a<b', + 'id' => 'thing-value-a-b2', + ]], + ['label' => ['for' => 'thing-value-a-b2']], + 'Second', + '/label', + ]; + $this->assertTags($result, $expected); + } + /** * Test rendering the empty option. *