-
Notifications
You must be signed in to change notification settings - Fork 3.4k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add simple multi-checkbox rendering like 2.x had.
- Loading branch information
Showing
2 changed files
with
253 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,138 @@ | ||
<?php | ||
/** | ||
* CakePHP(tm) : Rapid Development Framework (http://cakephp.org) | ||
* Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) | ||
* | ||
* Licensed under The MIT License | ||
* For full copyright and license information, please see the LICENSE.txt | ||
* Redistributions of files must retain the above copyright notice. | ||
* | ||
* @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) | ||
* @link http://cakephp.org CakePHP(tm) Project | ||
* @since CakePHP(tm) v3.0 | ||
* @license http://www.opensource.org/licenses/mit-license.php MIT License | ||
*/ | ||
namespace Cake\View\Input; | ||
|
||
use Cake\Utility\Inflector; | ||
|
||
class MultiCheckbox { | ||
|
||
protected $_templates; | ||
|
||
/** | ||
* Render multi-checkbox widget. | ||
* | ||
* @param Cake\View\StringTemplate $templates | ||
*/ | ||
public function __construct($templates) { | ||
$this->_templates = $templates; | ||
} | ||
|
||
/** | ||
* Render multi-checkbox widget. | ||
* | ||
* @param array $data | ||
* @return string | ||
*/ | ||
public function render($data) { | ||
$data += [ | ||
'name' => '', | ||
'escape' => true, | ||
'options' => [], | ||
'disabled' => null, | ||
'val' => null, | ||
]; | ||
$out= []; | ||
foreach ($data['options'] as $key => $val) { | ||
$checkbox = [ | ||
'value' => $key, | ||
'text' => $val, | ||
]; | ||
if (is_array($val) && isset($val['text'], $val['value'])) { | ||
$checkbox = $val; | ||
} | ||
$checkbox['name'] = $data['name']; | ||
$checkbox['escape'] = $data['escape']; | ||
|
||
if ($this->_isSelected($key, $data['val'])) { | ||
$checkbox['selected'] = true; | ||
} | ||
if ($this->_isDisabled($key, $data['disabled'])) { | ||
$checkbox['disabled'] = true; | ||
} | ||
if (empty($checkbox['id'])) { | ||
$checkbox['id'] = mb_strtolower(Inflector::slug($checkbox['name'] . $checkbox['value'], '-')); | ||
} | ||
|
||
$out[] = $this->_renderInput($checkbox); | ||
} | ||
return implode('', $out); | ||
} | ||
|
||
/** | ||
* Render a single checkbox & wrapper. | ||
* | ||
* @return string | ||
*/ | ||
protected function _renderInput($checkbox) { | ||
$input = $this->_templates->format('checkbox', [ | ||
'name' => $checkbox['name'] . '[]', | ||
'value' => $checkbox['value'], | ||
'attrs' => $this->_templates->formatAttributes( | ||
$checkbox, | ||
['name', 'value', 'text'] | ||
) | ||
]); | ||
|
||
$labelAttrs = [ | ||
'for' => $checkbox['id'], | ||
'escape' => $checkbox['escape'] | ||
]; | ||
$label = $this->_templates->format('label', [ | ||
'text' => $checkbox['escape'] ? h($checkbox['text']) : $checkbox['text'], | ||
'input' => $input, | ||
'attrs' => $this->_templates->formatAttributes($labelAttrs) | ||
]); | ||
|
||
return $this->_templates->format('checkboxContainer', [ | ||
'label' => $label, | ||
'input' => $input | ||
]); | ||
} | ||
|
||
/** | ||
* Helper method for deciding what options are selected. | ||
* | ||
* @param string $key The key to test. | ||
* @param array|string|null The selected values. | ||
* @return boolean | ||
*/ | ||
protected function _isSelected($key, $selected) { | ||
if ($selected === null) { | ||
return false; | ||
} | ||
$isArray = is_array($selected); | ||
if (!$isArray) { | ||
return (string)$key === (string)$selected; | ||
} | ||
$strict = !is_numeric($key); | ||
return in_array((string)$key, $selected, $strict); | ||
} | ||
|
||
/** | ||
* Helper method for deciding what options are disabled. | ||
* | ||
* @param string $key The key to test. | ||
* @param array|null The disabled values. | ||
* @return boolean | ||
*/ | ||
protected function _isDisabled($key, $disabled) { | ||
if ($disabled === null) { | ||
return false; | ||
} | ||
$strict = !is_numeric($key); | ||
return in_array((string)$key, $disabled, $strict); | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,115 @@ | ||
<?php | ||
/** | ||
* CakePHP(tm) : Rapid Development Framework (http://cakephp.org) | ||
* Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) | ||
* | ||
* Licensed under The MIT License | ||
* For full copyright and license information, please see the LICENSE.txt | ||
* Redistributions of files must retain the above copyright notice. | ||
* | ||
* @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) | ||
* @link http://cakephp.org CakePHP(tm) Project | ||
* @since CakePHP(tm) v3.0 | ||
* @license http://www.opensource.org/licenses/mit-license.php MIT License | ||
*/ | ||
namespace Cake\Test\TestCase\View\Input; | ||
|
||
use Cake\TestSuite\TestCase; | ||
use Cake\View\Input\MultiCheckbox; | ||
use Cake\View\StringTemplate; | ||
|
||
/** | ||
* MultiCheckbox test case. | ||
*/ | ||
class MultiCheckboxTest extends TestCase { | ||
|
||
public function setUp() { | ||
parent::setUp(); | ||
$templates = [ | ||
'checkbox' => '<input type="checkbox" name="{{name}}" value="{{value}}"{{attrs}}>', | ||
'label' => '<label{{attrs}}>{{text}}</label>', | ||
'checkboxContainer' => '<div class="checkbox">{{input}}{{label}}</div>', | ||
]; | ||
$this->templates = new StringTemplate(); | ||
$this->templates->add($templates); | ||
} | ||
|
||
/** | ||
* Test render simple option sets. | ||
* | ||
* @return void | ||
*/ | ||
public function testRenderSimple() { | ||
$input = new MultiCheckbox($this->templates); | ||
$data = [ | ||
'name' => 'Tags[id]', | ||
'options' => [ | ||
1 => 'CakePHP', | ||
2 => 'Development', | ||
] | ||
]; | ||
$result = $input->render($data); | ||
$expected = [ | ||
['div' => ['class' => 'checkbox']], | ||
['input' => [ | ||
'type' => 'checkbox', | ||
'name' => 'Tags[id][]', | ||
'value' => 1, | ||
'id' => 'tags-id-1', | ||
]], | ||
['label' => ['for' => 'tags-id-1']], | ||
'CakePHP', | ||
'/label', | ||
'/div', | ||
['div' => ['class' => 'checkbox']], | ||
['input' => [ | ||
'type' => 'checkbox', | ||
'name' => 'Tags[id][]', | ||
'value' => 2, | ||
'id' => 'tags-id-2', | ||
]], | ||
['label' => ['for' => 'tags-id-2']], | ||
'Development', | ||
'/label', | ||
'/div', | ||
]; | ||
$this->assertTags($result, $expected); | ||
} | ||
|
||
/** | ||
* Test render escpaing options. | ||
* | ||
* @return void | ||
*/ | ||
public function testRenderEscaping() { | ||
$this->markTestIncomplete(); | ||
} | ||
|
||
/** | ||
* Test render complex options. | ||
* | ||
* @return void | ||
*/ | ||
public function testRenderComplex() { | ||
$this->markTestIncomplete(); | ||
} | ||
|
||
/** | ||
* Test render selected checkboxes. | ||
* | ||
* @return void | ||
*/ | ||
public function testRenderSelected() { | ||
$this->markTestIncomplete(); | ||
} | ||
|
||
/** | ||
* Test render disabled checkboxes. | ||
* | ||
* @return void | ||
*/ | ||
public function testRenderDisabled() { | ||
$this->markTestIncomplete(); | ||
} | ||
|
||
} |