Yii Framework Forum: DropDown for pageSize in CGridView - Yii Framework Forum

Jump to content

  • (2 Pages)
  • +
  • 1
  • 2
  • You cannot start a new topic
  • You cannot reply to this topic

DropDown for pageSize in CGridView A convenient drop down to select page size and save in User state. Rate Topic: ***** 13 Votes

#1 User is offline   Mike 

  • Elite Member
  • PipPipPipPipPip
  • Yii
  • Group: Members
  • Posts: 3,013
  • Joined: 06-October 08
  • Location:Upper Palatinate

Posted 29 April 2010 - 05:52 PM

*
POPULAR

I found myself in the need for a dropDownList to select the page size on a CGridView. I was amazed that only a few lines of code where required. So i thought i'd share.

On top of my controller action for the gridview (if you used CRUD, this is actionAdmin() ) i added:

// page size drop down changed
if (isset($_GET['pageSize'])) {
    Yii::app()->user->setState('pageSize',(int)$_GET['pageSize']);
    unset($_GET['pageSize']);  // would interfere with pager and repetitive page size change
}


In the model (e.g. model/User.php) the data provider in search() is configured like:

return new CActiveDataProvider(get_class($this),array(
    'pagination'=>array(
        'pageSize'=> Yii::app()->user->getState('pageSize',Yii::app()->params['defaultPageSize']),
    ),
    'criteria'=>$criteria,
));


And finally the view (e.g. views/user/admin.php) :


<?php 
// put this somewhere on top
$pageSize=Yii::app()->user->getState('pageSize',Yii::app()->params['defaultPageSize']); ?>

<?php
// we use header of button column for the drop down
// so change the CButtonColumn in columns array like this:
...
array(
    'class'=>'CButtonColumn',
    'header'=>CHtml::dropDownList('pageSize',$pageSize,array(20=>20,50=>50,100=>100),array(
        // change 'user-grid' to the actual id of your grid!!
        'onchange'=>"$.fn.yiiGridView.update('user-grid',{ data:{pageSize: $(this).val() }})",
    )),
),


Et voilà, we have a page size selector that keeps it's value in user state.


EDIT:
Forgot to mention the configuration in the application parameters:
// Accessable with Yii::app()->params['paramName']
'params'=>array (

    'defaultPageSize'=>20,


EDIT2:
Changed to match the CRUD generated code.

This post has been edited by Mike: 03 June 2010 - 03:55 AM

13

#2 User is offline   Filist 

  • Newbie
  • Yii
  • Group: Members
  • Posts: 6
  • Joined: 03-May 10

Posted 03 May 2010 - 07:06 AM

Hello Mike,

I have been trying to implement this code for 4 hours now...
Never used Yii before, trying it out for 3 days now.

So the problems that I am facing: I can't figure out where to insert this part:
// page size drop down changed
if (isset($_GET['pageSize'])) {
    user()->setState('pageSize',(int)$_GET['pageSize']);
    unset($_GET['pageSize']);  // would interfere with pager and repetitive page size change
}

I think it should come into the controllers file of the model I am working on, am I correct? Into the:
	public function actionUpdate()
	{
		$model=$this->loadModel();

Once I insert all the code that you have provided, the page does not load properly. I figured out that if I replace user()->getState('pageSize') with a static number, the page loads fine. I thought I forgot to add the default page size to the main configuration file, but this is not the case.

But even with the static number in pageSize the drop down list is not functional. I change the value to 50 or 100, but nothing happens.
I went to the page source and figured out that this:
'onchange'=>"$.fn.yiiGridView.update('tracker-grid',{ data:{pageSize: $(this).val() }})",

was replaced by this:
'onchange="$.fn.yiiGridView.update(& #039;tracker-grid&# 039;,{ data:{pageSize: $(this).val() }})",


Can you please help me deal with this?
0

#3 User is offline   Mike 

  • Elite Member
  • PipPipPipPipPip
  • Yii
  • Group: Members
  • Posts: 3,013
  • Joined: 06-October 08
  • Location:Upper Palatinate

Posted 03 May 2010 - 09:15 AM

You use the code generated through CRUD? I admit that my example was more general and thus maybe adressed to the advanced user. Nevertheless i tried with some fresh generated CRUD code now and adjusted the code accordingly.

Maybe you can give it another try and let me know if it still doesn't work for you.
0

#4 User is offline   Filist 

  • Newbie
  • Yii
  • Group: Members
  • Posts: 6
  • Joined: 03-May 10

Posted 04 May 2010 - 01:33 AM

Thank you so much, Mike.

Yes, I used CRUD generated code.
I have implemented the modification you posted, now everything loads fine, just one problem remains.
The grid name inside of onchange() function is getting it's single quotes replaced bu the HTML special characters.

So this:
'onchange'=>"$.fn.yiiGridView.update('mdl--std--student-details-grid',{ data:{pageSize: $(this).val() }})",

turns into this:
onchange="$.fn.yiiGridView.update(&#O39;mdl--std--student-details-grid&#O39;,{ data:{pageSize: $(this).val() }})" name="pageSize" id="pageSize"


Should I change it somewhere in php.ini?
0

#5 User is offline   Mike 

  • Elite Member
  • PipPipPipPipPip
  • Yii
  • Group: Members
  • Posts: 3,013
  • Joined: 06-October 08
  • Location:Upper Palatinate

Posted 04 May 2010 - 03:21 AM

Yeah, that's happening for me, too. But did you try it? It works, the browser seems to interpret that string correctly. If you're really concerned, you could connect the event handler with jQuery. Something i usually prefer anyway:

<?php
array(
    'class'=>'CButtonColumn',
    'header'=>CHtml::dropDownList('pageSize',$pageSize,array(20=>20,50=>50,100=>100),array(
        'id''=>'user-grid-pageSize'
    )),
),

// somewhere below:
Yii::app()->clientScript->registerScript('initPageSize','$("#user-grid-pageSize").change(function(){
    $.fn.yiiGridView.update('user-grid',{ data:{pageSize: $(this).val() }});
});',CClientScript::POS_READY);

0

#6 User is offline   Filist 

  • Newbie
  • Yii
  • Group: Members
  • Posts: 6
  • Joined: 03-May 10

Posted 04 May 2010 - 03:55 AM

Still no go...

The thing is, when I select something from the drop down list, a js error pops up. Just an empty alert with OK button.
I thought the problem is caused by single cote being replaced by &#O39;, but looks like I am wrong.

So whenever something is selected from the drop down list, i just receive a js alert.

By the way, the ajax function that we registered
Yii::app()->clientScript->registerScript('initPageSize'..................
should appear in the html source? Because it doesn't for me.
0

#7 User is offline   Mike 

  • Elite Member
  • PipPipPipPipPip
  • Yii
  • Group: Members
  • Posts: 3,013
  • Joined: 06-October 08
  • Location:Upper Palatinate

Posted 04 May 2010 - 04:04 AM

Ok, here's my tested view code for the grid. Please try again:

<?php $pageSize=Yii::app()->user->getState('pageSize',Yii::app()->params['defaultPageSize']); ?>
<?php $this->widget('zii.widgets.grid.CGridView', array(
    'id'=>'user-grid',
    'dataProvider'=>$model->search(),
    'filter'=>$model,
    'columns'=>array(
        'id',
        'username',
        'password',
        'email',
        array(
            'class'=>'CButtonColumn',
            'header'=>CHtml::dropDownList(
                'pageSize',
                $pageSize,
                array(5=>5,20=>20,50=>50,100=>100),
                array('class'=>'change-pagesize')
            ),
        ),
    ),
)); ?>
<?php Yii::app()->clientScript->registerScript('initPageSize',<<<EOD
    $('.change-pagesize').live('change', function() {
        $.fn.yiiGridView.update('user-grid',{ data:{ pageSize: $(this).val() }})
    });
EOD
,CClientScript::POS_READY); ?>

0

#8 User is offline   Filist 

  • Newbie
  • Yii
  • Group: Members
  • Posts: 6
  • Joined: 03-May 10

Posted 04 May 2010 - 04:30 AM

Ok! Great!

The problem was not with the view, the problem was with controller.

I made a misstake by putting this:
if (isset($_GET['pageSize'])) {
    user()->setState('pageSize',(int)$_GET['pageSize']);
    unset($_GET['pageSize']);  // would interfere with pager and repetitive page size change
}
before the model is generated, not at the end of the function.

Now it shows no errors, BUT... :)

When I change the drop down list to any value, the processing image appears for a second, disappears and I am still having my default number of rows. It does not update the grid. Just like if I have chosen the default number.

And the drop down list changes value back to the default number.

This post has been edited by Filist: 04 May 2010 - 05:36 AM

0

#9 User is offline   Mike 

  • Elite Member
  • PipPipPipPipPip
  • Yii
  • Group: Members
  • Posts: 3,013
  • Joined: 06-October 08
  • Location:Upper Palatinate

Posted 04 May 2010 - 07:16 AM

So try do do some debugging. setState() should save the state persistently. Check if that works by e.g. putting

print user()->getState('pageSize'); 


on different places. Also check if the if($_GET[...]) condition is ever true...
0

#10 User is offline   jward 

  • Newbie
  • Yii
  • Group: Members
  • Posts: 12
  • Joined: 26-May 10
  • Location:U.S.

Posted 26 May 2010 - 05:39 PM

I have the same problem as Filist with pageSize not persisted.
Has a solution been found yet?
0

#11 User is offline   Mike 

  • Elite Member
  • PipPipPipPipPip
  • Yii
  • Group: Members
  • Posts: 3,013
  • Joined: 06-October 08
  • Location:Upper Palatinate

Posted 27 May 2010 - 01:36 AM

@jward:
Same here: Try to debug what's wrong. Try to find out where 'pageSize' is deleted from user state (by echoing it's value on different places). Or use any other mechanism to store that value persistently.
0

#12 User is offline   jward 

  • Newbie
  • Yii
  • Group: Members
  • Posts: 12
  • Joined: 26-May 10
  • Location:U.S.

Posted 27 May 2010 - 03:31 PM

It works for me after I changed
          user()->setState('pageSize',(int)$_GET['pageSize']);
to
Yii::app()->user->setState('pageSize',(int)$_GET['pageSize']);

Can anyone guess why it wouldn't work originally?

Here's a broader view of the change:
	public function actionAdmin() 	{
 		$model=new User('search');
 		if(isset($_GET['User']))
 			$model->attributes=$_GET['User'];

                  // page size drop down changed
                 if (isset($_GET['pageSize'])) {
                      //user()->setState('pageSize',(int)$_GET['pageSize']);  //this doesn't work for me
                     Yii::app()->user->setState('pageSize',(int)$_GET['pageSize']);   //use Yii::app()->user
                     unset($_GET['pageSize']);  // would interfere with pager and repetitive page size change
                 }

                  $this->render('admin',array(
 			'model'=>$model,
 		)); 


SEE MY UPDATE ON 2-Jun-2010

This post has been edited by jward: 02 June 2010 - 03:25 PM

0

#13 User is offline   Mike 

  • Elite Member
  • PipPipPipPipPip
  • Yii
  • Group: Members
  • Posts: 3,013
  • Joined: 06-October 08
  • Location:Upper Palatinate

Posted 28 May 2010 - 02:05 AM

Hmm. That doesn't make sense to me. Do you use another user() function? It should look like:

/**
 * This is the shortcut to Yii::app()->user.
 */
function user()
{
    return Yii::app()->user;
}

0

#14 User is offline   jward 

  • Newbie
  • Yii
  • Group: Members
  • Posts: 12
  • Joined: 26-May 10
  • Location:U.S.

Posted 28 May 2010 - 09:54 AM

I'm trying the Yii blog tutorial which has a User class modeled from tbl_user. Might this be the cause of the problem?
0

#15 User is offline   Mike 

  • Elite Member
  • PipPipPipPipPip
  • Yii
  • Group: Members
  • Posts: 3,013
  • Joined: 06-October 08
  • Location:Upper Palatinate

Posted 29 May 2010 - 04:34 AM

It shouldn't. In one of my projects i also have a class User and a shortcut function user(), which works fine. Did you try with another function name?
0

#16 User is offline   smoothcoder 

  • Junior Member
  • Pip
  • Yii
  • Group: Members
  • Posts: 29
  • Joined: 03-December 09
  • Location:Thailand

Posted 29 May 2010 - 08:47 AM

Hi Mike,Filist and Jward. I've been very interested by this add-on as I might have to use it. So I Gii'ed and made the test too. After minor problems it all works.
You can see it in the "farm dropdown_pagesize".

Quote

By the way, the ajax function that we registered
Yii::app()->clientScript->registerScript('initPageSize'..................
should appear in the html source? Because it doesn't for me.

I had that problem too. So I checked in the source code and I saw the JQuery code was perfectly present.And at that moment I saw my :blink: BBIIGG mistake in registerScript:
I had Id with value "user-grid" whereas you should change it accordingly, so in my case 'tbl-user-grid"

8) I hope it is of any use ...
0

#17 User is offline   Mike 

  • Elite Member
  • PipPipPipPipPip
  • Yii
  • Group: Members
  • Posts: 3,013
  • Joined: 06-October 08
  • Location:Upper Palatinate

Posted 29 May 2010 - 09:00 AM

View Postsmoothcoder, on 29 May 2010 - 08:47 AM, said:

I had Id with value "user-grid" whereas you should change it accordingly, so in my case 'tbl-user-grid"

8) I hope it is of any use ...


Oh, forgot to mention that. Thanks for pointing that out. Will change the top post.
0

#18 User is offline   jward 

  • Newbie
  • Yii
  • Group: Members
  • Posts: 12
  • Joined: 26-May 10
  • Location:U.S.

Posted 02 June 2010 - 03:22 PM

View PostMike, on 28 May 2010 - 02:05 AM, said:

Hmm. That doesn't make sense to me. Do you use another user() function? It should look like:

/**
 * This is the shortcut to Yii::app()->user.
 */
function user()
{
    return Yii::app()->user;
}


I just realized what was meant by this. I thought this code was already generated with the rest of the blog tutorial scaffolding but it wasn't and I didn't look for it. I stumbled upon Home » Documentation » The Yii Cookbook » Use shortcut functions to reduce typing and realized it was related to this issue.

I added this code to the project and can now use the user() shortcut without needing to use Yii::app()->user.
0

#19 User is offline   Mike 

  • Elite Member
  • PipPipPipPipPip
  • Yii
  • Group: Members
  • Posts: 3,013
  • Joined: 06-October 08
  • Location:Upper Palatinate

Posted 03 June 2010 - 03:56 AM

Oh, sorry for that. I've got so used to these shortcuts. The example is now using Yii::app()->user again everywhere to not confuse anyone reading it.
0

#20 User is offline   Antonio Ramirez 

  • Elite Member
  • Yii
  • Group: Yii Dev Team
  • Posts: 1,448
  • Joined: 04-October 10

Posted 09 November 2010 - 06:35 PM

View PostMike, on 04 May 2010 - 04:04 AM, said:

Ok, here's my tested view code for the grid. Please try again:

<?php $pageSize=Yii::app()->user->getState('pageSize',Yii::app()->params['defaultPageSize']); ?>
<?php $this->widget('zii.widgets.grid.CGridView', array(
    'id'=>'user-grid',
    'dataProvider'=>$model->search(),
    'filter'=>$model,
    'columns'=>array(
        'id',
        'username',
        'password',
        'email',
        array(
            'class'=>'CButtonColumn',
            'header'=>CHtml::dropDownList(
                'pageSize',
                $pageSize,
                array(5=>5,20=>20,50=>50,100=>100),
                array('class'=>'change-pagesize')
            ),
        ),
    ),
)); ?>
<?php Yii::app()->clientScript->registerScript('initPageSize',<<<EOD
    $('.change-pagesize').live('change', function() {
        $.fn.yiiGridView.update('user-grid',{ data:{ pageSize: $(this).val() }})
    });
EOD
,CClientScript::POS_READY); ?>



This is a really great post. There should be a place in the wiki where, separated by objects -or within the class reference information, related wiki articles should appear for the people to learn. This is a great tip Mike, and I will surely use it in my new project. This is actually a great tip for those who wish to create more complex filters to the data displayed.

If you don't mind, I will like to post an article in my blog with this know-how.

Thanks!
¿How long would it take for you to understand that you own nothing in this world?

www.ramirezcobos.com
www.2amigos.us
www.github.com/tonydspaniard
www.github.com/2amigos


Posted Image
1

Share this topic:


  • (2 Pages)
  • +
  • 1
  • 2
  • You cannot start a new topic
  • You cannot reply to this topic

2 User(s) are reading this topic
0 members, 2 guests, 0 anonymous users