CForm sub-form rendering

I have specified a form using form builder. It includes a sub-form to make a dropdown list from a related model.

Here is the controller action:


    $form = new CForm('application.views.foo._form', $model = new Foo);

    $form['bar']->model = $barModel = new Bar;

    $form['bar']['name']->items = CHtml::listData($barModel->findAll(), 'id', 'name');

    if ( $form->submitted('add') && $form->validate() && $model->save() )

        $this->redirect(array('view','id'=>$model->id));

    $this->render('add', array('form' => $form,));



And here is the form specification (omitting the buttons):


return array(

    'title' => 'Add Foo',

    'elements' => array(

        'name' => array('type' => 'text',),

        'bar' => array(

            'type' => 'form',

            'elements' => array('name' => array('type' => 'dropdownlist')),

        ),

    ),

);

As written this works fine. But if I want to use ‘id’ instead of ‘name’ as the sub-form element, the dropdown doesn’t render. I’m not getting an error, and the rest of the form is there, just not the dropdown.

Is this a bug? Is ‘id’ a reserved word in this context? Is there another way I should be doing this?

Edit: Yii 1.1.0, PHP 5.3.0, Apache 2 on Mac OS X.6

Edit: OK, not a bug. See post #10 below. Sorry for the false alarm.

Have you var_dump’ed to ensure the array is as you expect it to be?




var_dump($form['bar']['name']->items);

exit;



Yeah, the items are there in either case. They just aren’t rendered when the element is named ‘id’.

Now I’m wondering if this is a PHP bug. Having traced through the ->render() process, a simple echo $form; in the controller action behaves exactly the same (no surprise as echo is exactly what render() ends up doing). bugs.php.net is down at the moment so it’s hard to search. I suspect __toString().

OK, scratch that. Now I suspect CForm::renderElement().

For some reason the CForm object containing the dropdown list gets a visible property of false when the dropdown list is named ‘id’, but true otherwise.

Might want to report this as an issue in the Yii bugtracker, see if Qiang is able to replicate as an error.

Will do once I’ve narrowed it down a bit more.

Worked around by explicitly declaring the ‘visible’ property for that element:


return array(

    'title' => 'Add Foo',

    'elements' => array(

        'name' => array('type' => 'text',),

        'bar' => array(

            'type' => 'form',

            'elements' => array(

                'id' => array(

                    'type' => 'dropdownlist',

                    'visible' => true,

                )

            ),

        ),

    ),

);

Will report.

Bug report stands, but after all that I’ve figured out I didn’t actually want to use a sub-form in this case :blink:

And I can reproduce the bug without a subform, just a top-level element that is a dropdownlist named ‘id’.

Doesn’t have to be a dropdownlist, either. Same behavior with any element with a key of ‘id’.

I guess this is expected behavior. Issue was that ‘id’ was not a required attribute for this model. Hence massive assignment prohibited by CFormInputElement::evaluateVisible(). :rolleyes: