Problems With Dataprovider In Renderpartial Views

Hi all,

I am currently stuck on an issue that I am hoping someone can help me out with.

I have two sections, lets call them section A and section B and I have created them both as modules. Both sections display an index page showing data using the CGridView widget and the data is being pulled in from separate models. When I access the index view of each model the data tables are displaying correctly.

For example -

index.php?r=firstsection/view/index

index.php?r=secondsection/view/index

What I am trying to do though is pull in content from section B into section A using renderPartial. The problem I am having is that an error is being displayed that there is an ‘Undefined variable: dataProvider’ in the index view of section B.

Is this because there is a dataProvider variable already defined for section A or is there another way I need to do this?

I have searched for a solution to this issue but there doesn’t seem to be any mention of dataProviders in renderPartial files.

Would anyone be kind enough to help me out with this?

Many thanks in advance

Hi auren,

It sounds like just a syntax problem in using renderPartial.

How do you call renderPartial to render the section B in the section A?

Hi softark.

Thanks for replying.

I call the view from section B in section A in the following way -




<?php echo $this->renderPartial('application.modules.sectionb.views.users.index',array('model'=>new Users)); ?>

Many thanks.

I see.

So you are not passing the dataProvider to the view.

  1. How do you make ready $dataProvider in your index view of the section B?

  2. How do you call ‘render’ in your actionIndex of the section B?

For the index view of section B I am just using CGridView as follows -


<?php $this->widget('zii.widgets.grid.CGridView', array(

	'id'=>'users-grid',

	'dataProvider'=>$dataProvider,

    	'columns'=>array(

        	'user_id',

		'user_screen_name',

		'user_authentication_type',

		'user_account_status',

		'user_email_address',

		'user_is_surveyor',

		'user_is_administrator',

		'user_has_enquiries',

		    array(

                'class' => 'CButtonColumn',

                'buttons'=>array(

                        'update' => array(

                                'label'=>'<i class="icon-user"></i> <span>View User</span>',

                                'options' => array('class'=>'btn btn-small'),

                        ),

                ),

        ),

	),

)); ?>

…and in my actionIndex for section B I have -


	public function actionIndex()

	{

		$dataProvider=new CActiveDataProvider('Users');

                

                

		$this->render('index',array(

			'dataProvider'=>$dataProvider,

		));

	}

Many thanks

So you have to pass the dataProvider.




<?php

echo $this->renderPartial('application.modules.sectionb.views.users.index',

    array('dataProvider'=>new CActiveDataProvider('Users'))); 

?>



Note that the 2nd parameter of renderPartial and render is an array of data which will be extracted into PHP variables in the view script. We use this parameter to pass various variables from the controller to the view.

For example, if you pass




array('foo' => new ModelA, 'bar' => new ModelB)



then you get a variable named $foo which is a ModelA object and a variable named $bar which is a ModelB object in the view script.

[EDIT]

??

Echoing too much?




<?php

$this->renderPartial('application.modules.sectionb.views.users.index',

    array('dataProvider'=>new CActiveDataProvider('Users'))); 

?>



I see.

So the CGridView widgets of both sections have their own $dataProvider variable but when you call section B in section A you pass it in the renderPartial?

A couple of things I have noticed are -

  1. When accessing the index view of section B directly (by the URL) the CGridView is displayed without any layout or theme? EDIT - I had made a mistake in the controller and fixed it.

  2. Even though I can now see both CGridView widgets [from section A and section B] in section A when I click to edit any item from section B it displays the update view of data from section A.

I hope this makes sense? I really appreciate your help on this.

Well, not only with renderPartial but also with render, we have to pass the variables in the 2nd parameter. The variables in a view script have to be supplied using it, except for $this which refers to the current controller instance. The 2 view scripts may have a variable with the same name, but they may or may not be the same thing. It’s all up to you. In this particular instance, the 2 data providers have to be the different things, of course.

"render" will render the view with the layout around it, and "renderPartial" will render it without the layout.

Ah, yes. You are right. It’s because the CGridView’s buttons will create the links to the current controller by default. You have to set ‘viewButtonUrl’, ‘updateButtonUrl’ and ‘deleteButtonUrl’ of the CButtonColumn of the section B explicitly so that the links will point to the controller/actions of module B.

http://www.yiiframework.com/doc/api/1.1/CButtonColumn

After all, you may want to throw away the idea of reusing the view of section B … and I think it’s reasonable. :D

IMO, the models should be reused intensively, but the views are not.

Thanks softark!

The CGridView buttons are now working thanks to your heads-up about customising the CButtonColumn.

I would be interested to hear your thoughts about how you would (with your experience) go about this yourself?

Basically, I have various models, controllers and views for things such as Users, Properties, Auctions, Enquiries and they are interchangable. This means that from with Properties you will need to get data from the Users model to assign to Properties, from with Auctions you will need to be able to get Property data and from Enquiries you will need some data from Properties and Users. Obviously, I have all of the related tables in my models.

I have started to build these as separate modules but I was stuck on getting partial bits of data from one view into another view. Hopefully armed with this new knowledge I can move forward.

Many thanks

That’s exactly where we have to squeeze our poor brains. I also don’t have the right answer.

I have to confess that the DRY concept has been very difficult for me when I’m working with views. Now I tend to use copy and paste (and modify) for views in order to spare my thinking. I really don’t know it’s the right decision or not. :(

I know what you mean. As this is my first Yii and even first MVC project I am trying to follow the best practices as much as possible but I am perhaps trying to take it too far.

Many thanks for your help today.