We have moved our forum to GitHub Discussions. For questions about Phalcon v3/v4/v5 you can visit here and for Phalcon v6 here.

addOption method of forms-element-select object does not seem to work with array as argument

Hi,

I want to add options to my form's select field using addOption() method. Docs state that it takes an array as an argument, well in my case it does not. I'm using Phalcon 1.2.3 and I'm sure I'm doing something wrong, but I don't really know what. What I want to achieve is pass an id and a value, which consists of a given text (in my case "(role_type) role_name", however the only thing I get in the view is the string 'Array'. addOption() method works fine with a string. In my form class I set the select field as follows:

$user_role_params = array(
    'useEmpty'  => true,
    'emptyText' => 'Please Select...',
    'using'     => array('id', 'name')
);
$acl_roles = Role::find();
$user_role = new Select('role_id');

$user_role->setAttributes($user_role_params);

foreach ($acl_roles as $acl_role) {
    $user_role->addOption(array(
        'id'   => $acl_role->getId(),
        'name' => '('.$acl_role->getType().')'.$acl_role->getName()));
}

$user_role->setLabel('User Role: ');
$this->add($user_role);

And my view is a simple volt template with the following content:

<form method="post">
        {% for field in form %}
            <p>
            {% set label = field.getLabel() %}
            {% if label !== '' %}
                <label for="{{ field.getName() }}">{{ label }}</label>
            {% endif %}

                {{ field }}
            </p>
        {% endfor %}
        {{ submit_button("Add User") }}
    </form>

Thanks.



98.9k

addOption appends an option if the current options are an array of options, combining a database resultset with an array is not supported. You can convert the resultset to an array first before passing it to Select.

edited Oct '14

Hi Phalcon,

Could you please elaborate on where I try to combine a resultset with an array? Your anwer made me try various other things I have not tried before and none of them seem to work, appending an array with addOption results in a string 'Array', even if I create a select with

$user_role = new Select('role_id', array(1 => 'one'));

I did, however manage to get what I wanted, but not in a way I wanted / I was expecting. Here is how:

// set params var
        $user_role_params = array(
            'useEmpty'   => true,
            'emptyValue' => 0,
            'emptyText'  => 'Please Select...'
        );
// get all roles
        $acl_roles = Role::find();
// loop through to get the required format       
        foreach ($acl_roles as $acl_role) {
           $arr[$acl_role->getId()] = '('.$acl_role->getType().')'.$acl_role->getName();
        }
// create select object using array and parms var
        $user_role = new Select('role_id', $arr, $user_role_params);
        $user_role->setLabel('User Role: ');
        $this->add($user_role);

And for those who might want to add more options elswhere in their code I came up with a workaround (first get existing options, append additional options to that array and replace the existing ones with setOptions method):

        $ar = $user_role->getOptions() + array(4 => 'more');
        $user_role->setOptions($ar);

Overall, either I don't understand something (most likely) or there is a bug in a way the addOption() method works (less likely, but possible) which leads to only one conclusion: I must start learning C :) Take care.

Found something that would keep you from doing a loop:

$results = Role::find(
            array(
                'columns' => 'id, ' . new RawValue('CONCAT ("(", type, ") ", name) as typeName')
            )
        );

$user_role_params = array(
    'useEmpty'  => true,
    'emptyText' => 'Please Select...',
    'using'     => array('id', 'typeName')
);

$user_role = new Select('role_id', $results, $user_role_params);

The key is to return the concatenated columns from the database directly and use that virtual column name in the Select() function. Might be too late for your, but will hopefully help others searching for something like this.



7.9k
edited Mar '14

based on Mark Garret's solution, the below snippet worked fine and produced a select with entries like :

EDP Manager
EDP Senior
TAX Manager
TAX Senior

where uppercase come from "cls" filed and Camelcase come from "name" field

code within a Form class


        $rank_id = new Select
        (
            'rank_id', 
            Ranks::find
            (
                array
                (
                    'conditions' => 'ISNULL(deleted_at)', 
                    'columns' => 'id,'.new Phalcon\Db\RawValue('CONCAT (cls, " ", name) AS clsName'),
                    'order' => ' sort_order ASC, cls ASC, name ASC'
                )
            ), 
            array
            (
                'using' => array
                (
                    'id', 
                    'clsName'
                ), 
                'useEmpty' => TRUE, 
                'class' => 'form-control'
            )
        );
        $rank_id->setLabel('Rank');
        $this->add($rank_id);