Applying Clistview On The View Page Of Widget

AllAdvertisements.php there is on the /protected/components :


<?php

/**

 * AllAdvertisements is a Yii widget used to display a list of All Advertisements

 */

class AllAdvertisements extends CWidget

{

    private $_Advertisements;

    public $userId = null;


    public function init()

    {

        $this->_Advertisements = Advertisement::model()->findAllAdvertisements($this->userId);

    }


    public function getAllAdvertisements()

    {

        return $this->_Advertisements;

    }


    public function run()

    {

        // this method is called by CController::endWidget()

        $this->render('AllAdvertisementsview');

    }

}

And, AllAdvertisementsview.php on the /protected/components/views :


<?php

    $dataProvider = $this->getAllAdvertisements();

    $this->widget('zii.widgets.CListView', array(

        'dataProvider'=>$dataProvider,

        'itemView'=>'//views/advertisement/_view',

    ));

?>

And on the /protected/views/site/index.php recall the widget as follow:


$this->widget('application.components.AllAdvertisements');

But, get this error:


Fatal error: Call to a member function getData() on a non-object in C:\Apache2\htdocs\yii\framework\zii\widgets\CBaseListView.php on line 108

What’s the problem?

Dear Friend

Consider the following.




public function init()

    {

        $this->_Advertisements = Advertisement::model()->findAllAdvertisements($this->userId);

    }




findAllAdvertisements is not a method in AR.

Replace it by [b]findAll/b.

After that declare the dataProvider in the following way.




$dataProvider=new CArrayDataProvider($this->getAllAdvertisements());

);



Kindly check after making above changes.

Regards.

That method (findAllAdvertisements) is defined in the Advertisement model.

Declared it at the "/protected/components.AllAdvertisements.php" ?

Dear Friend

Sorry I was not aware of that.

AllAdvertisementsview.php on the /protected/components/views .




<?php

    $dataProvider =new CArrayDataProvider($this->getAllAdvertisements());

    $this->widget('zii.widgets.CListView', array(

        'dataProvider'=>$dataProvider,

        'itemView'=>'//views/advertisement/_view',

    ));

?>



Thanks but,

Encountered with this error:


require() [<a href='function.require'>function.require</a>]: Filename cannot be empty 

AllAdvertisementsview.php


$dataProvider =new CArrayDataProvider($this->getAllAdvertisements());

$this->widget('zii.widgets.CListView', array(

    'dataProvider'=>$dataProvider,

    'itemView'=>'/protected/views/advertisement/_view',

));

/protected/views/advertisement/_view.php(generated with Gii)


<?php

/* @var $this AdvertisementController */

/* @var $data Advertisement */

?>


<div class="view">


	<b><?php echo CHtml::encode($data->getAttributeLabel('id')); ?>:</b>

	<?php echo CHtml::link(CHtml::encode($data->id), array('view', 'id'=>$data->id)); ?>

	<br />


	<b><?php echo CHtml::encode($data->getAttributeLabel('name')); ?>:</b>

	<?php echo CHtml::encode($data->name); ?>

	<br />


	<b><?php echo CHtml::encode($data->getAttributeLabel('description')); ?>:</b>

	<?php echo CHtml::encode($data->description); ?>

	<br />


	<b><?php echo CHtml::encode($data->getAttributeLabel('user_id')); ?>:</b>

	<?php echo CHtml::encode($data->user_id); ?>

	<br />


</div>

On what exact line this happens -


require() [<a href='function.require'>function.require</a>]: Filename cannot be empty 

?

Seems to me, provided code is ok and should work.

P.S. By the way, I recomment not to use such a paths in ‘itemView’=>’/protected/views/advertisement/_view’ because if application would be placed in some other folder, path would be wrong. Use something like ‘//advertisment/_view’ instead.

Dear Friend

As LastDay suggested, we can do the the following.




'itemView'=>'//advertisement/_view',



or




'itemView'=>'application.views.advertisement._view',



Regards.

The attachment file say.

Dear Friend

PHP warning indictes the difficulty in getting the _view file.

We are erring somewhere…

Let us try the following.

Copy that _view file and bring it to /protected/components/views/

Now make the following change.




'itemView'=>'_view',



Let us see what happens.

Through this way works, very well.

CWidget::render() method by default tries to find file within views/ folder on teh same level where derived widget class located.

http://www.yiiframework.com/doc/api/1.1/CWidget#getViewPath-detail

How can override it?

Add you Widget class to components/ folder for example. This new Widget class should extend base CWidget class - and in your realisation of Widget class you could override getViewPath, And all your widget should derive from thsi new Widget class.

I foolishly tried to overrides getViewPath() this way:




    public function getViewPath()

    {

        return '//protected/views/advertisement';

    }



Obviously that is this problem:


Declaration of AllAdvertisements::getViewPath() should be compatible with that of CWidget::getViewPath() 

Can help me override this method for this path: //protected/views/advertisement

Thanks

Dear Friends

Lastday is absolutely correct in that CWidget::render() method by default tries to find file within views/ folder on the same level where derived widget class located.

In our scenario,we can solve it by calling the owner controller.




$dataProvider =new CArrayDataProvider($this->getAllAdvertisements());

$this->owner->widget('zii.widgets.CListView', array(     //I have added owner.

    'dataProvider'=>$dataProvider,

    'itemView'=>'//advertisement/_view',

));



Its pointed correctly.

In CWidget.php declarion of method is following - public function getViewPath($checkTheme=false). So add parameter $checkTheme=false to your method in children class.