Я хочу знать, как добавить настраиваемый атрибут для опции в поле выбора формы Zend.
PHP:
$option_values = array("multiOptions" => array( "US" => "United States", "CA" => "Canada", )); $type=array('big','small'); $option= new Zend_Form_Element_Select('option', $option_values);
HTML:
<select> <option value='US' type='big'>United States</option> <option value='CA' type='small'>Canada</option> </select>
Как добавить этот атрибут типа в параметр?
Невозможно использовать ZF-реализацию Zend_Form_Element_Select
. Вам нужно создать свой собственный элемент. Я сделал что-то подобное, вот соответствующий код:
<?php require_once 'Zend/Form/Element/Select.php'; /** * Select, but with the possibility to add attributes to <option>s * @author Dominik Marczuk */ class Zend_Form_Element_SelectAttribs extends Zend_Form_Element { public $options = array(); public $helper = 'selectAttribs'; /** * Adds a new <option> * @param string $value value (key) used internally * @param string $label label that is shown to the user * @param array $attribs additional attributes */ public function addOption ($value,$label = '',$attribs = array()) { $value = (string) $value; if (!empty($label)) $label = (string) $label; else $label = $value; $this->options[$value] = array( 'value' => $value, 'label' => $label ) + $attribs; return $this; } }
Поместите это в /library/Zend/Form/Element/SelectAttribs.php. Вам также нужен помощник для визуализации элемента. Поместите его в каталог помощников вашего вида, также назовите его SelectAttribs.php. Вот содержимое моего файла:
<?php require_once 'Zend/View/Helper/FormElement.php'; class Zend_View_Helper_SelectAttribs extends Zend_View_Helper_FormElement { public function selectAttribs($name, $value = null, $attribs = null, $options = null, $listsep = "<br />\n") { $info = $this->_getInfo($name, $value, $attribs, $options, $listsep); extract($info); // name, id, value, attribs, options, listsep, disable // force $value to array so we can compare multiple values to multiple // options; also ensure it's a string for comparison purposes. $value = array_map('strval', (array) $value); // now start building the XHTML. $disabled = ''; if (true === $disable) { $disabled = ' disabled="disabled"'; } // Build the surrounding select element first. $xhtml = '<select' . ' name="' . $this->view->escape($name) . '"' . ' id="' . $this->view->escape($id) . '"' . $disabled . $this->_htmlAttribs($attribs) . ">\n "; // build the list of options $list = array(); $translator = $this->getTranslator(); foreach ($options as $opt_value => $option) { $opt_disable = ''; if (is_array($disable) && in_array($opt_value, $disable)) { $opt_disable = ' disabled="disabled"'; } $list[] = $this->_build($option, $disabled); } // add the options to the xhtml and close the select $xhtml .= implode("\n ", $list) . "\n</select>"; return $xhtml; } protected function _build($option, $disabled) { $html = '<option'; foreach ($option as $attrib => $value) { $html .= " $attrib=\"$value\""; } return $html.$disabled.">".$option['label']."</option>"; } }
С этим вы должны быть готовы:
$elt = new Zend_Form_Element_SelectAttribs('whatever'); $elt->addOption($value,$label,array('attribname' => 'attribvalue'));
Используя addMultiOption ($ value, $ label), я просто установил параметр значения примерно так:
$value = $id . '" ref="' . $ref;
и когда он делает, вы получаете:
<option value="<idValue>" ref="<refValue"><labelValue></option>
Надеюсь это поможет….
Хорошо, значение получает экранированное, но optionsClasses не так внутри цикла, что добавляет addMultiOptions (val, lable). Я делаю что-то вроде этого:
$optionClasses[<val>] = 'ref_' . <val> . '" ref="' . <ref>;
а затем после цикла просто выполните setAttrib ('optionClasses', $ optionsClasses)
И это на самом деле работает …
Я ответил на это по другому вопросу, но не смог найти способ добавить комментарий здесь для ссылки на него; Это была Zend Framework addMultiOption, добавляющая настраиваемые параметры, такие как «rel» для параметров
Я не нашел ответа @ mingos и имел некоторые проблемы с реализацией установки значения. Его ответ многое помог с тем, что нужно было расширить и изменить, однако. Как только я начал это, все остальное было довольно легко. Я просто расширил ZF1 Select и overrode там, где мне было нужно:
/** * Select, now with abbility to specify attributes on <Option>, addMultiOption has new syntax * @author Seth Miller */ class MyNamespace_Form_Element_SelectAttribs extends Zend_Form_Element_Select { public $options = array(); public $helper = 'selectAttribs'; /** * Add an option * * @param string $option * @param string $value * @return Zend_Form_Element_Multi */ public function addMultiOption($value, $label = '', $attribs = array()) { $value = (string) $value; if (!empty($label)) { $label = (string) $label; } else { $label = $value; } $this->_getMultiOptions(); if (!$this->_translateOption($value, $label)) { $this->options[$value] = array( 'value' => $value, 'label' => $label ) + $attribs; } return $this; } /** * Add many options at once * * @param array $options * @return Zend_Form_Element_Multi */ public function addMultiOptions(array $options) { foreach ($options as $optionKey => $optionProperties) { if (is_array($optionProperties) && array_key_exists('key', $optionProperties) && array_key_exists('value', $optionProperties) ) { if(array_key_exists('key', $optionProperties)) $optionKey = $optionProperties['key']; $this->addMultiOption($optionKey, $optionProperties['value'], $optionProperties['attribs']); } else { $this->addMultiOption($optionKey, $optionProperties); } } return $this; } public function isValid($value, $context = null) { if ($this->registerInArrayValidator()) { if (!$this->getValidator('InArray')) { $multiOptions = $this->getMultiOptions(); $options = array(); foreach ($multiOptions as $optionKey => $optionData) { // optgroup instead of option label if (is_array($optionData['options'])) { $options = array_merge($options, array_keys($optionData['options'])); } else { $options[] = $optionKey; } } $this->addValidator( 'InArray', true, array($options) ); } } return parent::isValid($value, $context); } }
И помощник вида:
класс MyNamespace_View_Helper_SelectAttribs расширяет Zend_View_Helper_FormElement {
public function selectAttribs($name, $value = null, $attribs = null, $options = null, $listsep = "<br />\n") { $info = $this->_getInfo($name, $value, $attribs, $options, $listsep); extract($info); // name, id, value, attribs, options, listsep, disable // force $value to array so we can compare multiple values to multiple // options; also ensure it's a string for comparison purposes. $value = array_map('strval', (array) $value); // check if element may have multiple values $multiple = ''; if (substr($name, -2) == '[]') { // multiple implied by the name $multiple = ' multiple="multiple"'; } if (isset($attribs['multiple'])) { // Attribute set if ($attribs['multiple']) { // True attribute; set multiple attribute $multiple = ' multiple="multiple"'; // Make sure name indicates multiple values are allowed if (!empty($multiple) && (substr($name, -2) != '[]')) { $name .= '[]'; } } else { // False attribute; ensure attribute not set $multiple = ''; } unset($attribs['multiple']); } // now start building the XHTML. $disabled = ''; if (true === $disable) { $disabled = ' disabled="disabled"'; } // Build the surrounding select element first. $xhtml = '<select' .' name="'.$this->view->escape($name).'"' .' id="'.$this->view->escape($id).'"' .$multiple .$disabled .$this->_htmlAttribs($attribs) .">\n "; // build the list of options $list = array(); $translator = $this->getTranslator(); foreach ((array) $options as $optionKey => $optionData) { if (isset($optionData['options'])) { $optDisable = ''; if (is_array($disable) && in_array($optionData['value'], $disable)) { $optDisable = ' disabled="disabled"'; } if (null !== $translator) { $optValue = $translator->translate($optionData['value']); } $optId = ' id="'.$this->view->escape($id).'-optgroup-' .$this->view->escape($optionData['value']).'"'; $list[] = '<optgroup' .$optDisable .$optId .' label="'.$this->view->escape($optionData['value']).'">'; foreach ($optionData['options'] as $optionKey2 => $optionData2) { $list[] = $this->_build($optionKey2, $optionData2, $value, $disable); } $list[] = '</optgroup>'; } else { $list[] = $this->_build($optionKey, $optionData, $value, $disable); } } // add the options to the xhtml and close the select $xhtml .= implode("\n ", $list)."\n</select>"; return $xhtml; } /** * Builds the actual <option> tag * * @param string $value Options Value * @param string $label Options Label * @param array $selected The option value(s) to mark as 'selected' * @param array|bool $disable Whether the select is disabled, or individual options are * @return string Option Tag XHTML */ protected function _build($optionKey, $optionData, $selected, $disable) { if (is_bool($disable)) { $disable = array(); } $opt = '<option'; foreach ($optionData as $attrib => $attribValue) { $opt .= ' '.$this->view->escape($attrib).'="'.$this->view->escape($attribValue).'"'; } // selected? if (in_array((string) $optionData['value'], $selected)) { $opt .= ' selected="selected"'; } // disabled? if (in_array($optionData['value'], $disable)) { $opt .= ' disabled="disabled"'; } $opt .= '>' . $this->view->escape($optionData['label']) . "</option>"; return $opt; }
неpublic function selectAttribs($name, $value = null, $attribs = null, $options = null, $listsep = "<br />\n") { $info = $this->_getInfo($name, $value, $attribs, $options, $listsep); extract($info); // name, id, value, attribs, options, listsep, disable // force $value to array so we can compare multiple values to multiple // options; also ensure it's a string for comparison purposes. $value = array_map('strval', (array) $value); // check if element may have multiple values $multiple = ''; if (substr($name, -2) == '[]') { // multiple implied by the name $multiple = ' multiple="multiple"'; } if (isset($attribs['multiple'])) { // Attribute set if ($attribs['multiple']) { // True attribute; set multiple attribute $multiple = ' multiple="multiple"'; // Make sure name indicates multiple values are allowed if (!empty($multiple) && (substr($name, -2) != '[]')) { $name .= '[]'; } } else { // False attribute; ensure attribute not set $multiple = ''; } unset($attribs['multiple']); } // now start building the XHTML. $disabled = ''; if (true === $disable) { $disabled = ' disabled="disabled"'; } // Build the surrounding select element first. $xhtml = '<select' .' name="'.$this->view->escape($name).'"' .' id="'.$this->view->escape($id).'"' .$multiple .$disabled .$this->_htmlAttribs($attribs) .">\n "; // build the list of options $list = array(); $translator = $this->getTranslator(); foreach ((array) $options as $optionKey => $optionData) { if (isset($optionData['options'])) { $optDisable = ''; if (is_array($disable) && in_array($optionData['value'], $disable)) { $optDisable = ' disabled="disabled"'; } if (null !== $translator) { $optValue = $translator->translate($optionData['value']); } $optId = ' id="'.$this->view->escape($id).'-optgroup-' .$this->view->escape($optionData['value']).'"'; $list[] = '<optgroup' .$optDisable .$optId .' label="'.$this->view->escape($optionData['value']).'">'; foreach ($optionData['options'] as $optionKey2 => $optionData2) { $list[] = $this->_build($optionKey2, $optionData2, $value, $disable); } $list[] = '</optgroup>'; } else { $list[] = $this->_build($optionKey, $optionData, $value, $disable); } } // add the options to the xhtml and close the select $xhtml .= implode("\n ", $list)."\n</select>"; return $xhtml; } /** * Builds the actual <option> tag * * @param string $value Options Value * @param string $label Options Label * @param array $selected The option value(s) to mark as 'selected' * @param array|bool $disable Whether the select is disabled, or individual options are * @return string Option Tag XHTML */ protected function _build($optionKey, $optionData, $selected, $disable) { if (is_bool($disable)) { $disable = array(); } $opt = '<option'; foreach ($optionData as $attrib => $attribValue) { $opt .= ' '.$this->view->escape($attrib).'="'.$this->view->escape($attribValue).'"'; } // selected? if (in_array((string) $optionData['value'], $selected)) { $opt .= ' selected="selected"'; } // disabled? if (in_array($optionData['value'], $disable)) { $opt .= ' disabled="disabled"'; } $opt .= '>' . $this->view->escape($optionData['label']) . "</option>"; return $opt; }
}
И реализация в форме будет примерно такой:
$selectElement = new MyNamespace_Form_Element_SelectAttribs('selectElementName'); $selectElement->addMultiOption($value, $label, array('data-custom' => 'custom data embedded in option tag.');
Надеюсь, это поможет кому-то. Благодарю.
mingos, вы забыли о методе setvalue для мультиселектора.
вы добавите что-то вроде:
... foreach ($options as $opt_value => $option) { $opt_disable = ''; $opt_selected = ''; if (is_array($disable) && in_array($opt_value, $disable)) { $opt_disable = ' disabled="disabled"'; } if (in_array($opt_value,$value)) { $opt_selected = ' selected="selected"'; } $list[] = $this->_build($option, $disabled, $opt_selected); } ... and protected function _build($option, $disabled, $opt_selected) { $html = '<option'; foreach ($option as $attrib => $value) { $html .= " $attrib=\"$value\""; } return $html . $disabled . $opt_selected . " foo>" . $option['label'] . "</option>"; }
Вы можете продлить / перезаписать помощник Zend_View_Helper_FormSelect
но реальная проблема будет заключаться в получении дополнительных данных для каждой опции.
По умолчанию Zend_Form_Element_Select
(через Zend_Form_Element_Multi
) ожидает две строки для каждой опции: одну для атрибута value
и необязательную для текстового содержимого. Возможно, вам понадобится создать свой собственный элемент для обработки дополнительных данных.
Нет необходимости в пользовательском элементе формы вообще, что вы можете сделать: $ element-> setAttrib ('disable', array (1, 2, 5));
Как объяснено в http://pietervogelaar.nl/set-attribute-on-select-option-with-zend_form/