コーダーさんに泣いて頼まれたのであのウザいdivをどうにかしてみた
空の値渡した場合の処理&classの貼っつけかたはかなーり適当なので修正必要かもー?
ソース
/app/View/Helper/CustomFormHelper.php
App::uses('FormHelper', 'View/Helper');
class CustomFormHelper extends FormHelper {
public function select($fieldName, $options = array(), $attributes = array()) {
$select = array();
$style = null;
$tag = null;
$attributes += array(
'class' => null,
'escape' => true,
'secure' => true,
'empty' => '',
'showParents' => false,
'hiddenField' => true,
'disabled' => false,
'multipleOptionTag' => 'div'
);
$escapeOptions = $this->_extractOption('escape', $attributes);
$secure = $this->_extractOption('secure', $attributes);
$showEmpty = $this->_extractOption('empty', $attributes);
$showParents = $this->_extractOption('showParents', $attributes);
$hiddenField = $this->_extractOption('hiddenField', $attributes);
unset($attributes['escape'], $attributes['secure'], $attributes['empty'], $attributes['showParents'], $attributes['hiddenField']);
$id = $this->_extractOption('id', $attributes);
$attributes = $this->_initInputField($fieldName, array_merge(
(array)$attributes, array('secure' => self::SECURE_SKIP)
));
if (is_string($options) && isset($this->_options[$options])) {
$options = $this->_generateOptions($options);
} elseif (!is_array($options)) {
$options = array();
}
if (isset($attributes['type'])) {
unset($attributes['type']);
}
if (!empty($attributes['multiple'])) {
$style = ($attributes['multiple'] === 'checkbox') ? 'checkbox' : null;
$template = ($style) ? 'checkboxmultiplestart' : 'selectmultiplestart';
$tag = $template;
if ($hiddenField) {
$hiddenAttributes = array(
'value' => '',
'id' => $attributes['id'] . ($style ? '' : '_'),
'secure' => false,
'name' => $attributes['name']
);
$select[] = $this->hidden(null, $hiddenAttributes);
}
} else {
$tag = 'selectstart';
}
if (!empty($tag) || isset($template)) {
$hasOptions = (count($options) > 0 || $showEmpty);
// Secure the field if there are options, or its a multi select.
// Single selects with no options don't submit, but multiselects do.
if (
(!isset($secure) || $secure) &&
empty($attributes['disabled']) &&
(!empty($attributes['multiple']) || $hasOptions)
) {
$this->_secure(true, $this->_secureFieldName($attributes));
}
$selectAttr = $attributes;
unset($selectAttr['multipleOptionTag']);
$select[] = $this->Html->useTag($tag, $selectAttr['name'], array_diff_key($selectAttr, array('name' => null, 'value' => null)));
}
$emptyMulti = (
$showEmpty !== null && $showEmpty !== false && !(
empty($showEmpty) && (isset($attributes) &&
array_key_exists('multiple', $attributes))
)
);
if ($emptyMulti) {
$showEmpty = ($showEmpty === true) ? '' : $showEmpty;
$options = array('' => $showEmpty) + $options;
}
if (!$id) {
$attributes['id'] = Inflector::camelize($attributes['id']);
}
$select = array_merge($select, $this->_selectOptions(
array_reverse($options, true),
array(),
$showParents,
array(
'escape' => $escapeOptions,
'style' => $style,
'name' => $attributes['name'],
'value' => $attributes['value'],
'class' => $attributes['class'],
'id' => $attributes['id'],
'disabled' => $attributes['disabled'],
'multipleOptionTag' => $attributes['multipleOptionTag']
)
));
$template = ($style === 'checkbox') ? 'checkboxmultipleend' : 'selectend';
$select[] = $this->Html->useTag($template);
return implode("\n", $select);
}
protected function _selectOptions($elements = array(), $parents = array(), $showParents = null, $attributes = array()) {
$select = array();
$attributes = array_merge(
array('escape' => true, 'style' => null, 'value' => null, 'class' => null, 'multipleOptionTag' => 'div'),
$attributes
);
$selectedIsEmpty = ($attributes['value'] === '' || $attributes['value'] === null);
$selectedIsArray = is_array($attributes['value']);
foreach ($elements as $name => $title) {
$htmlOptions = array();
if (is_array($title) && (!isset($title['name']) || !isset($title['value']))) {
if (!empty($name)) {
if ($attributes['style'] === 'checkbox') {
$select[] = $this->Html->useTag('fieldsetend');
} else {
$select[] = $this->Html->useTag('optiongroupend');
}
$parents[] = $name;
}
$select = array_merge($select, $this->_selectOptions(
$title, $parents, $showParents, $attributes
));
if (!empty($name)) {
$name = $attributes['escape'] ? h($name) : $name;
if ($attributes['style'] === 'checkbox') {
$select[] = $this->Html->useTag('fieldsetstart', $name);
} else {
$select[] = $this->Html->useTag('optiongroup', $name, '');
}
}
$name = null;
} elseif (is_array($title)) {
$htmlOptions = $title;
$name = $title['value'];
$title = $title['name'];
unset($htmlOptions['name'], $htmlOptions['value']);
}
if ($name !== null) {
$isNumeric = is_numeric($name);
if (
(!$selectedIsArray && !$selectedIsEmpty && (string)$attributes['value'] == (string)$name) ||
($selectedIsArray && in_array((string)$name, $attributes['value'], !$isNumeric))
) {
if ($attributes['style'] === 'checkbox') {
$htmlOptions['checked'] = true;
} else {
$htmlOptions['selected'] = 'selected';
}
}
if ($showParents || (!in_array($title, $parents))) {
$title = ($attributes['escape']) ? h($title) : $title;
$hasDisabled = !empty($attributes['disabled']);
if ($hasDisabled) {
$disabledIsArray = is_array($attributes['disabled']);
if ($disabledIsArray) {
$disabledIsNumeric = is_numeric($name);
}
}
if (
$hasDisabled &&
$disabledIsArray &&
in_array((string)$name, $attributes['disabled'], !$disabledIsNumeric)
) {
$htmlOptions['disabled'] = 'disabled';
}
if ($hasDisabled && !$disabledIsArray && $attributes['style'] === 'checkbox') {
$htmlOptions['disabled'] = $attributes['disabled'] === true ? 'disabled' : $attributes['disabled'];
}
if ($attributes['style'] === 'checkbox') {
$htmlOptions['value'] = $name;
$tagName = $attributes['id'] . Inflector::camelize(Inflector::slug($name));
$htmlOptions['id'] = $tagName;
$label = array('for' => $tagName);
if (isset($htmlOptions['checked']) && $htmlOptions['checked'] === true) {
$label['class'] = 'selected';
}
$name = $attributes['name'];
if (empty($attributes['class'])) {
$attributes['class'] = 'checkbox';
} elseif ($attributes['class'] === 'form-error') {
$attributes['class'] = 'checkbox ' . $attributes['class'];
}
if (!strstr($attributes['class'], 'selected') && empty($attributes['multipleOptionTag'])) {
$label['class'] = (isset($label['class'])) ? $attributes['class'] . ' ' . $label['class'] : $attributes['class'];
}
$label = $this->label(null, $title, $label);
$item = $this->Html->useTag('checkboxmultiple', $name, $htmlOptions);
$select[] = $this->Html->tag($attributes['multipleOptionTag'], $item . $label, array('class' => $attributes['class']));
} else {
$select[] = $this->Html->useTag('selectoption', $name, $htmlOptions, $title);
}
}
}
}
return array_reverse($select, true);
}
}
/app/Controller/AppController.php
class AppController extends Controller {
public $helpers = array('Form' => array('className' => 'CustomForm'));
}
/app/View/Hoges/index.php
<?php echo $this->Form->input('hoge', array('type' => 'select', 'multiple' => 'checkbox', 'multipleOptionTag' => 'span', 'options' => array(1 => 'ほげ', 2 => 'ふが'))); ?>
結果
<div class="input select">
<label for="hoge">Hoge</label>
<input type="hidden" name="data[hoge]" value="" id="hoge">
<span class="checkbox">
<input type="checkbox" name="data[hoge][]" value="1" id="Hoge1">
<label for="Hoge1">ほげ</label>
</span>
<span class="checkbox">
<input type="checkbox" name="data[hoge][]" value="2" id="Hoge2">
<label for="Hoge2">ふが</label>
</span>
</div>