CStarRating and CListView problem

Hello all,

My goal is to display a profile page which includes paginated comments, so

I’m rendering a view (viewprofile) from my controller which renders partial another view (listcomments).

In the listcomments view I include the widget CListView which renders the _listcomments view via the itemView option. The _listcomments uses the CStarRating widget.

Everything is ok in the first load of the page and the _listcmoments is rendered with the stars of the CStarRating widget, but when i click on the next page the results (the values are correct) display the radio buttons instead of CStarRating’s stars.

I’ve seen in other answers in the forum that i should renderpartial the listcomments view with the processOutput=false, which i did but I still have the same problem.

any ideas anyone ?

thanks!

Try $this->renderPartial(’_listcomments’, array(‘model’ => $model), true, true));

The 3rd param (true) should return the results instead of displaying them and the 4th param (true) should register the scripts necessary for the CStarRating widget. Let me know if this works.

Cheers,

Matt

I don’t know how to renderPartial the _listcomments view since I’m rendering it from the itemView argument

of the CListView

in the listcomments view (which is renderPartial from the viewprofile view) i have


<?php

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

                'dataProvider' => $dataProvider_Comments,

                'itemView' => '_listcomments',

            ));

        ?>

which renders the _listcomments… how should i renderPartial the _listcomments view ?

i’ve added a


$dummyVar = $this->renderPartial('_listcomments', array('data'=>$data'), true, true);

inside the listcomments view right before the CListView widget call… From what you said

i expected to register the scripts with the renderPartial and then display them with the

CListView widget… but that didn’t work either… i still get the radio buttons instead of

the stars

Ok, I see. It appears the JS is being lost during pagination. This, unfortunately, is a common side-effect of renderPartial().

Yes, try to render partial, with the params that I mentioned before, in the _listComments file. This should call the associated partial view.

The one downside I can see, is that it will try to include the JS for each record. Let me know if that works.

Matt

well the first try didn’t go so well


Fatal error: Allowed memory size of 134217728 bytes exhausted (tried to allocate 40961 bytes) in C:\var\yii-framework\yii-1.1.6.r2877\framework\web\CBaseController.php on line 117

That happens when i try to renderPartial the _listcomments inside the _listcomments view…

I’ll play a bit with the above and i’ll let you know the results…

thanks

I meant to create a 2nd partial view, called _comments, with a simple call to renderPartial(’_listComments’, array(data…), true, true).




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

                'dataProvider' => $dataProvider_Comments,

                'itemView' => '_comments',

            ));



On 2nd thought, the 3rd param should be false. It SHOULD display the result. The 4th param should still be true.

Matt

Still no luck… i’m currently trying this:

  1. in viewprofile view i have:

renderPartial('listcomments',..)

  1. in listcomments i call the:

CListView(...,'itemView'=>'_comments')

  1. inside _comments i only :

 renderPartial('_listcomments', array('data'=>$data), false, true);

it still shows radio buttons after i click on next page. Is the above the solution you mentioned

or did i misunderstand something ?

thanks,

papasj

Ok, tomorrow when I get some time I will create a few dummy pages to see if I can come up with a solution.

Cheers,

Matt

I’ve created a new webapp to test this scenario and used a table (comments) with fields id and rating.

Generated the model and CRUD through the gii module so now in our sandbox app we’ve got

  1. A CommentsController which in the actionIndex it creates an CActiveDataProvider with our Comments class

    and then renders index.php view

  2. index.php view calls the CListView widget as follows:




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

	'dataProvider'=>$dataProvider,

	'itemView'=>'_view',

)); ?>



  1. The _view.php view calls the CStarRating widget as follows:



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

	<?php $this->widget('CStarRating', array(

                        'value' => $data->rating,

                        'id' => $data->id,

                        'readOnly' => true,

                        'name' => 'reviewRating-' . $data->id,

                        'id' => 'reviewRating-' . $data->id,

                    ));?>



When we browse to our Comments controller we see the first 10 results and

the stars replaced the radio buttons.

Now if i click in the next page the rest of the results come up but the

radio buttons are not replaced by the stars.

I’ll try different scenarios based on what you said and i’ll post the results.

thanks,

papasj

I haven’t succeed anything by trying to renderPartial() a 2nd view…

I did found though, the afterAjaxUpdate option of the CListView widget and I thought i could re-run

the jquery.rating.rating() and I ended up with this link which is in russian but the idea is pretty much the same.

So, i added the following in the CListView widget




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

	'dataProvider'=>$dataProvider,

	'itemView'=>'_view',

        'afterAjaxUpdate'=>'function(id,data) {             

            $("span[id^=\'reviewRating-\'] > input").rating();

        }',

));



and now after each ajax loaded page we "update" the radio buttons…

If you have some time give a try in the 2nd renderPartial() method… i wonder what I’m doing

wrong.

cheers!

Ok, I think I got it. Revert your changes and simply add an ‘id’ property, must start with a hash (#), to the CListView widget.




<?php

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

    'dataProvider' => $dataProvider,

    'itemView' => '_listcomments',

    'id' => '#qwerty',

)); ?>



I believe Yii is setting both widget (CListView and CStarRating) containers to the same Id. I have tested it on my machine and I can page while keeping the CStarRating widget intact. See screenshot. Sorry for the previous, long workarounds.

1561

Portfolio.png

Cheers,

Matt

and yes Matt, you got it right!! It works fine by just adding a separate id to the CListView widget :) No need for the previous workarounds…

cheers for your time mate!

papasj

Perfect!

But i found an error when you have two or more zii.widgets.CListView in the same view.

My actual problem is that when I add “‘id’ => ‘#foo_’.$id,” to the CListView, the paginator start work in a dependantly way.

When i hit page 2, all the paginator from all the ClistView work toghether.

I realize that, with this change, the pager is’n ajax anymore…

Any hint?

Sorry for my enlgish.

Thanks in advance.

Yes, thats an issue with passing id, ajax pagination doesn’t work…i am facing same issue!

Hello,

This is my solution. This is a solution that I use for CListViews because I don’t like to turn on scripts for Ajaxrequests as this seems to cause unexpected behavior (such as the problems mentioned here.)

I call actions based on the mouse entering the div container of the list view.

For example,

$(’.list-view’).live(‘mouseenter’,function() { //list-view is the id of the div containing my list view

//code here

}

Inside this, I place scripts or actions that I want to have executed after pagination. It is not perfect, as it will run only when the user mouseovers the container. But I’m not sure how else to do this.

Anyway, for Cstarrating, I have placed this code inside.

jQuery(’.starRating > input’).rating(

{‘starWidth’:22,‘callback’:fookie} //these are the widget parameters

);

Make sure to add a class name (here, ‘starRating’) to your star widget

$this->widget(‘CStarRating’,

    array(

‘htmlOptions’=>array(

'class'=&gt;'starRating'

),

This should work without messing anything else up ~…

Joshua

joshua@venturekorea.net

Your solution works but now it refreshes the page on paginate and that’s why it work. There’s no more ajax pagination. And also the url gets uglier with some params.

Thank you so much waterloomatt, this worked perfectly for me.

Any updates?

I have tested both solutions:

as commented, changing the id makes the page loaded after pagination, not ajax pagination

using afterAjaxUpdate and calling rating the starRating is rendered but seems its done with the item default values, if you’ve choosen allowEmpty false the forbidden symbol is showing, if you had readOnly is always read/write. What is working is the ‘value’ property