Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Select is always multiple #424

Open
tomasr1981 opened this issue Jun 11, 2024 · 2 comments
Open

Select is always multiple #424

tomasr1981 opened this issue Jun 11, 2024 · 2 comments

Comments

@tomasr1981
Copy link

Hi,
I extended Zend_Select:

<?php
require_once 'Zend/Form/Element/Select.php';

class My_Form_Element_SelectAttribs extends Zend_Form_Element_Select {

    public $options = array();
    public $helper = 'selectAttribs';
    
    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;
    }
}

This is using in form:

$select = new My_Form_Element_SelectAttribs('id');
$select->setLabel('Select')
             ->setValue(isset($_POST['id']) ? $_POST['id'] : null)
             ->setAttribs(array(
                    'size' => 1
             ));
$select->addOption(false, '==Select==');
foreach ($itemsForSelect as $item) {
    $select->addOption($item->country_id, $select->title, array('data-something' => $select->something));
}
$this->addElement($select);

Select has multiple attrib. How can I remove it? Param size does not work. In last oficial version of ZF1 ii worked.

Snímek obrazovky pořízený 2024-06-11 08-37-02

@rruchte
Copy link

rruchte commented Jun 11, 2024

Can you provide a concise runnable example? There is something important happening in your selectAttribs helper plugin that may be causing your problem.

When I run your code (after commenting out selectAttribs and editing the call to addOption), I do not get a multi-select, but the result is clearly not what you are looking for either. Seems like your problem is in your code.

<?php
class My_Form_Element_SelectAttribs extends Zend_Form_Element_Select {
	
	public $options = array();
	// What is this?
	//public $helper = 'selectAttribs';
	
	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;
	}
}

$select = new My_Form_Element_SelectAttribs('id');
$select->setLabel('Select')
	   ->setValue(isset($_POST['id']) ? $_POST['id'] : null)
	   ->setAttribs(array(
						'size' => 1
					));
$select->addOption(false, '==Select==');

$itemsForSelect = [
	(object)['country_id' => 1, 'title' => 'Austria', 'something' => 'foo'],
	(object)['country_id' => 2, 'title' => 'Belgium', 'something' => 'bar'],
	(object)['country_id' => 3, 'title' => 'Croatia', 'something' => 'baz']
];

foreach ($itemsForSelect as $item)
{
	/*
	 Are $select->title and $select->something correct? Should probably be looking for elements of $item, right?
	 $select->addOption($item->country_id, $select->title, array('data-something' => $select->something));
	 */
	$select->addOption($item->country_id, $item->title, array('data-something' => $item->something));
}

$form = new Zend_Form('foo');
$form->addElement($select);


echo $form->render();
echo PHP_EOL;

Result:

<form enctype="application/x-www-form-urlencoded" action="" method="post">
    <dl class="zend_form">
        <dt id="id-label"><label for="id" class="optional">Select</label></dt>
        <dd id="id-element">
            <select name="id" id="id" size="1">
                <optgroup id="id-optgroup-" label="">
                    <option value="value"></option>
                    <option value="label">==Select==</option>
                </optgroup>
                <optgroup id="id-optgroup-1" label="1">
                    <option value="value">1</option>
                    <option value="label">Austria</option>
                    <option value="data-something">foo</option>
                </optgroup>
                <optgroup id="id-optgroup-2" label="2">
                    <option value="value">2</option>
                    <option value="label">Belgium</option>
                    <option value="data-something">bar</option>
                </optgroup>
                <optgroup id="id-optgroup-3" label="3">
                    <option value="value">3</option>
                    <option value="label">Croatia</option>
                    <option value="data-something">baz</option>
                </optgroup>
            </select></dd>
    </dl>
</form>

@tomasr1981
Copy link
Author

Your are right. Helper looked like:

<?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();
        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, $value, $disabled);
        }

        // add the options to the xhtml and close the select
        $xhtml .= implode("\n   ", $list) . "\n</select>";

        return $xhtml;
    }

    protected function _build($option, $selected, $disabled) {
        // selected
        $opt_selected = '';
        if (in_array((string) $option['value'], $selected)) {
            $opt_selected .= ' selected="selected"';
        }

        $html = '<option';
        foreach ($option as $attrib => $value) {
            $html .= $option['label'] !== $value ? " $attrib=\"$value\"" : null;
        }
        return $html . $opt_selected . $disabled . ">" . $option['label'] . "</option>";
    }
}

I had to add remove multiple attr when it was set as false:

if (isset($attribs['multiple']) && $attribs['multiple'] === false) {
        unset($attribs['multiple']);
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants