Skip to content

Commit

Permalink
Start multi-checkbox rendering.
Browse files Browse the repository at this point in the history
Add simple multi-checkbox rendering like 2.x had.
  • Loading branch information
markstory committed Jan 15, 2014
1 parent f14aa83 commit 72b9481
Show file tree
Hide file tree
Showing 2 changed files with 253 additions and 0 deletions.
138 changes: 138 additions & 0 deletions src/View/Input/MultiCheckbox.php
@@ -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);
}

}
115 changes: 115 additions & 0 deletions tests/TestCase/View/Input/MultiCheckboxTest.php
@@ -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();
}

}

0 comments on commit 72b9481

Please sign in to comment.