0

I have a view displaying company details, and I added a list of orders made by this company (separate model and controller). Everything works, however the CGridView that is used to display the list of orders is rendered (renderPartial()) from the company's controller, and because of that, the default controller of the CGridView is company instead of order, that causes all the automatically generated URLs like for the update/delete buttons to be invalid, because they are being generated as /company/delete?id= and they should refer to the order controller. I went around this by manually creating the URLs for the action buttons like that:

$columns[] = array(
        'class' => 'CButtonColumn',
        'buttons' => array(
            'delete' => array(
                'label' => 'Download',
                'url' => 'CController::createUrl("/order/delete", array("id"=>$data->id))',
                'options' => array('class' => 'download'),
            ),
        ),  
        'template' => '{delete}',
);

But I don't like this approach, as this requires manual creation of every URL. I tried setting the controller field of the CGridView, but it's read-only. How can I modify the default controller/model that CGridView is working on?

I also see that CGridView generates a hidden 'keys' div with IDs of elements, and these keys have update URLs with incorrect controller name, so I really need to somehow change the controller CGridView is working on, as I don't want to risk it updating entries in wrong controllers.

Edit I tried creating an instance of the controller and use that instance to create the widget:

$ctrl = Yii::app()->createController('order')[0];
$ctrl->widget('zii.widgets.grid.CGridView', $grid);

But even though the owner property (read only) of the created widget is good (OrderController), the action URLs are still being generated with the actual path (/company/) instead of /order/.

rob006
  • 21,383
  • 5
  • 53
  • 74
AJ Cole
  • 169
  • 2
  • 13

1 Answers1

0

When you're using relative routes (like delete), Yii will use current request context to resolve route. So it does not matter which controller is used to render widget, route of Yii::app()->controller will be used as a base for relative routes.

There is not much what you can do in this case - if your widget should not depend on context, you should use absolute routes for URLs:

[
    'class' => 'CButtonColumn',
    'deleteButtonUrl' => 'Yii::app()->controller->createUrl("/order/delete",array("id"=>$data->primaryKey))',
    // ...
],

If you don't want to repeat this in multiple places, you may create widget or helper, which will prepare CGridView settings.

rob006
  • 21,383
  • 5
  • 53
  • 74