I want know how to add custom attribute for option in a select field of Zend form.
我想知道如何在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>
How to add this type attribute in the option?
如何在选项中添加此类型属性?
6 个解决方案
#1
9
It is not possible using ZF's implementation of Zend_Form_Element_Select
. You need to create your own element. I have done something similar, here's the relevant code:
使用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;
}
}
Put this into /library/Zend/Form/Element/SelectAttribs.php. You also need a helper to render the element. Put it into your view helpers directory, name it SelectAttribs.php as well. Here's the contents of my file:
把它放到/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>";
}
}
With this, you should be ready to go:
有了这个,你应该准备好了:
$elt = new Zend_Form_Element_SelectAttribs('whatever');
$elt->addOption($value,$label,array('attribname' => 'attribvalue'));
#2
3
Using addMultiOption($value,$label) I just set the value parameter to something like:
使用addMultiOption($ value,$ label)我只需将value参数设置为:
$value = $id . '" ref="' . $ref;
and when it renders you get:
当它呈现时,你得到:
<option value="<idValue>" ref="<refValue"><labelValue></option>
Hope this helps....
希望这可以帮助....
Okay, value gets escaped but optionClasses does not so inside the loop that adds the addMultiOptions(val,lable) I do something like this:
好的,值被转义,但是optionClasses不会在添加addMultiOptions(val,lable)的循环中这样做我做这样的事情:
$optionClasses[<val>] = 'ref_' . <val> . '" ref="' . <ref>;
and then after the loop just do a setAttrib('optionClasses',$optionClasses)
然后在循环之后只做一个setAttrib('optionClasses',$ optionClasses)
And that actually works...
这实际上有效......
I answered this for another question but could not find a way to add a comment here to reference it; It was Zend Framework addMultiOption adding custom parameters like "rel" for options
我为另一个问题回答了这个问题,但是找不到在这里添加评论的方法来引用它;这是Zend Framework addMultiOption为选项添加“rel”等自定义参数
#3
2
I didn't find @mingos's answer complete and had some issues with implementing setting the value. His answer helped a lot with what needed to be extended and changed however. Once I had that start the rest was pretty easy. I just extended ZF1's Select and overrode where I needed:
我没有找到@ mingos的答案完成,并且在实现设置值方面存在一些问题。他的答案对需要扩展和改变的内容有很大帮助。一旦我有了这个开始,其余的很容易。我只是扩展了ZF1的选择和覆盖我需要的地方:
/**
* 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);
}
}
And the view helper:
和视图助手:
class MyNamespace_View_Helper_SelectAttribs extends Zend_View_Helper_FormElement {
class 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;
}
}
And implementation in a form would be something like:
表单中的实现类似于:
$selectElement = new MyNamespace_Form_Element_SelectAttribs('selectElementName');
$selectElement->addMultiOption($value, $label, array('data-custom' => 'custom data embedded in option tag.');
I hope that helps someone. Thanks.
我希望能有所帮助。谢谢。
#4
1
mingos, you forgot about setvalue method of multiselect.
mingos,你忘记了多重选择的setvalue方法。
you shoul add something like:
你应该添加类似的东西:
...
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>";
}
#5
0
You could extend / overwrite the Zend_View_Helper_FormSelect
helper but the real problem is going to be getting the extra data into each option.
您可以扩展/覆盖Zend_View_Helper_FormSelect助手,但真正的问题是将额外的数据放入每个选项中。
By default, Zend_Form_Element_Select
(via Zend_Form_Element_Multi
) expects two strings for each option, one for the value
attribute and an optional one for the text content. You may need to create your own element to handle the extra data.
默认情况下,Zend_Form_Element_Select(通过Zend_Form_Element_Multi)期望每个选项有两个字符串,一个用于value属性,另一个用于文本内容。您可能需要创建自己的元素来处理额外的数据。
#6
0
No need for custom form element at all, what u can do is: $element->setAttrib('disable', array(1, 2, 5));
根本不需要自定义表单元素,你可以做的是:$ element-> setAttrib('disable',array(1,2,5));
As explained at http://pietervogelaar.nl/set-attribute-on-select-option-with-zend_form/
如http://pietervogelaar.nl/set-attribute-on-select-option-with-zend_form/所述
#1
9
It is not possible using ZF's implementation of Zend_Form_Element_Select
. You need to create your own element. I have done something similar, here's the relevant code:
使用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;
}
}
Put this into /library/Zend/Form/Element/SelectAttribs.php. You also need a helper to render the element. Put it into your view helpers directory, name it SelectAttribs.php as well. Here's the contents of my file:
把它放到/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>";
}
}
With this, you should be ready to go:
有了这个,你应该准备好了:
$elt = new Zend_Form_Element_SelectAttribs('whatever');
$elt->addOption($value,$label,array('attribname' => 'attribvalue'));
#2
3
Using addMultiOption($value,$label) I just set the value parameter to something like:
使用addMultiOption($ value,$ label)我只需将value参数设置为:
$value = $id . '" ref="' . $ref;
and when it renders you get:
当它呈现时,你得到:
<option value="<idValue>" ref="<refValue"><labelValue></option>
Hope this helps....
希望这可以帮助....
Okay, value gets escaped but optionClasses does not so inside the loop that adds the addMultiOptions(val,lable) I do something like this:
好的,值被转义,但是optionClasses不会在添加addMultiOptions(val,lable)的循环中这样做我做这样的事情:
$optionClasses[<val>] = 'ref_' . <val> . '" ref="' . <ref>;
and then after the loop just do a setAttrib('optionClasses',$optionClasses)
然后在循环之后只做一个setAttrib('optionClasses',$ optionClasses)
And that actually works...
这实际上有效......
I answered this for another question but could not find a way to add a comment here to reference it; It was Zend Framework addMultiOption adding custom parameters like "rel" for options
我为另一个问题回答了这个问题,但是找不到在这里添加评论的方法来引用它;这是Zend Framework addMultiOption为选项添加“rel”等自定义参数
#3
2
I didn't find @mingos's answer complete and had some issues with implementing setting the value. His answer helped a lot with what needed to be extended and changed however. Once I had that start the rest was pretty easy. I just extended ZF1's Select and overrode where I needed:
我没有找到@ mingos的答案完成,并且在实现设置值方面存在一些问题。他的答案对需要扩展和改变的内容有很大帮助。一旦我有了这个开始,其余的很容易。我只是扩展了ZF1的选择和覆盖我需要的地方:
/**
* 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);
}
}
And the view helper:
和视图助手:
class MyNamespace_View_Helper_SelectAttribs extends Zend_View_Helper_FormElement {
class 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;
}
}
And implementation in a form would be something like:
表单中的实现类似于:
$selectElement = new MyNamespace_Form_Element_SelectAttribs('selectElementName');
$selectElement->addMultiOption($value, $label, array('data-custom' => 'custom data embedded in option tag.');
I hope that helps someone. Thanks.
我希望能有所帮助。谢谢。
#4
1
mingos, you forgot about setvalue method of multiselect.
mingos,你忘记了多重选择的setvalue方法。
you shoul add something like:
你应该添加类似的东西:
...
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>";
}
#5
0
You could extend / overwrite the Zend_View_Helper_FormSelect
helper but the real problem is going to be getting the extra data into each option.
您可以扩展/覆盖Zend_View_Helper_FormSelect助手,但真正的问题是将额外的数据放入每个选项中。
By default, Zend_Form_Element_Select
(via Zend_Form_Element_Multi
) expects two strings for each option, one for the value
attribute and an optional one for the text content. You may need to create your own element to handle the extra data.
默认情况下,Zend_Form_Element_Select(通过Zend_Form_Element_Multi)期望每个选项有两个字符串,一个用于value属性,另一个用于文本内容。您可能需要创建自己的元素来处理额外的数据。
#6
0
No need for custom form element at all, what u can do is: $element->setAttrib('disable', array(1, 2, 5));
根本不需要自定义表单元素,你可以做的是:$ element-> setAttrib('disable',array(1,2,5));
As explained at http://pietervogelaar.nl/set-attribute-on-select-option-with-zend_form/
如http://pietervogelaar.nl/set-attribute-on-select-option-with-zend_form/所述