DropDown for pageSize in CGridView

I agree! :)

If you want more filtering, consider checking out the datafilter extension:

http://www.yiiframew…sion/datafilter

Thanks. :)

The basic idea was to show, how easy you can enhance Yii’s components if you’re not afraid of javascript. So sure, feel free to share wherever you like.

Pretty good man, not bad at all… and also the link of jacmoe…

Thank you both

I follow your example and set Agent and Brokerage. I add 1/2/3 items per page for testing purposes. Only Agent view is working. Brokerage view always resets the item-per-view back to 1 in the dropdownlist even though the number of items are displayed correctly, and i have no clue why dropdownlist resets to 1 every time I select a new pagesize.

Javascript issue maybe ?

p/s: after looking closely, the setup allows different view share the same pagesize.

p/s: the dropdownlist in the non-working-view does not have [selected="selected"], why is that ?

Thanks

Without showing the relevant code parts we can’t tell much. You probably don’t provide the current $pageSize to the dropdownlist in your view file. So maybe check the code for typos.

Just a trivial addition to the great article. :D

The pageSize dropDownList can also be implemented as a part of the summary text, not as the button column header.




<?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,

    'summaryText'=>'Displaying {start}-{end} of {count} result(s). ' .

        CHtml::dropDownList(

            'pageSize',

            $pageSize,

            array(5=>5,20=>20,50=>50,100=>100),

            array('class'=>'change-pageSize')) .

        ' rows per page',

    'columns'=>array(

        'id',

        'username',

        'password',

        'email',

        array(

            'class'=>'CButtonColumn',

        ),

    ),

)); ?>

<?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); ?>



good idea , i like your thought ; cheers

Thanks for the code guys. I have it working on one grid just fine but when I add it to a different grid the functionality does not work on that second grid. Is that to be expected or can one use this as many times at wanted in a given app?

It should work for any grid and you can use it for all the grids in the app…

I came across this recently, my solutions was to extend the CGridView class such:




<?php

/*

 * Project : 

 * Date    : Jul 1, 2011 10:20:59 AM

 * Author  : matt.cheale

 * File    : MGridView.php

 */


Yii::import( 'zii.widgets.grid.CGridView' );


/**

 * Extends CGridView making pagers at the top and bottom default and adding in a pageSize

 * form element.

 *

 * @author matt.cheale

 * @since Jul 1, 2011

 */

class MGridView extends CGridView

{

	/**

	 * @var string overides the parent default.

	 */

	public $template = "{limit}\n{pager}\n{items}\n{pager}\n{limit}";

	

	/**

	 * @var array the option values for use in the drop down

	 */

	public $pageSizeOptions = array( '5' => '5', '10' => '10', '20' => '20', '50' => '50' );

	

	/**

	 * @var CModel the model that is used to power the search.

	 */

	public $model;

	

	/**

	 * Renders the Show X amount of items drop down.

	 */

	public function renderLimit()

	{

		if ( ! $this->model instanceof CModel )

		{

			return;

		}

		

		$refl = new ReflectionClass( $this->model );

		if ( ! $refl->hasProperty( 'pageSize' ) )

		{

			return;

		}

		

		echo CHtml::openTag( 'div', array( 'class' => 'grid-limit' ) );

		echo CHtml::label( 'Show:', null );

		echo CHtml::activeDropDownList( $this->model, 'pageSize',

			array( '5' => '5', '10' => '10', '20' => '20', '50' => '50' ), array( 'class' => 'grid-limit-field' ) );

		echo CHtml::closeTag( 'div' );

	}

	

	/**

	 * Overides parent to add in jQuery for the changing of the drop down lists.

	 */

	public function registerClientScript()

	{

		parent::registerClientScript();

		

		$id = $this->getId();

		Yii::app()->getClientScript()->registerScript( __CLASS__ . '#' . $id . '#limit-field', <<<___JS___

$('#{$this->getId()} .grid-limit-field').live( 'change', function() { $.fn.yiiGridView.update('{$id}', { data: $(this).serialize() }); return false; } );

___JS___

			, CClientScript::POS_READY );

	}

}



I’m sure it could be made more generic further though. Just thought I’d share ;)

After seeing your answer I revisited it today and got them working. Thanks

Since this is tied to the user state, how can a default be set for a guest user? Right now looks like the default is 10 if you are not logged in and I need that increased.

In the $model->search() you are reading the pageSize, right?

So there you can check if it’s not set and if the user isGuest… and set the value you need…

Ok I just ended up taking care of it in my config file like Mike suggested.

Hi,

I have tried this, but I am getting the following JS Error …

TypeError: settings is undefined

[Break On This Error]

$grid.addClass(settings.loadingClass);

Any ideas, its for something to do with the Yii GridView JQuery update I think.

James.

Great tip Mike ! Thank you!

I had a project requirement to offer this feature in many views and the client wanted the user model to have a default that they could maintain and each view would start with the user default as the set of data.

I had to tweak things a bit to get the user default set as they entered the view and then allow the view to control the pagesize

as the user changes it.

This was a huge help !

Thanks again!

i use extention it’s work.

http://www.yiiframework.com/extension/pagesize/

Hey Mike and others. Have anyone had problems with losing filters by #search-form.serialize after change pager size?

Dear Friends

That was really great.

I have something to share.

Here I have not used session.

I have a model:[b]Edible/b.

I have created a virtual property pageSize in the model and made it safe on search.




class Edible extends CActiveRecord

{   

	public $pageSize=10;

	

	public function rules()

	{

	

		return array(

			array('name', 'required'),

			array('name', 'length', 'max'=>64),

			array('id, name,pageSize', 'safe', 'on'=>'search'),

		);

	}


	

	public function search()

	{

		$criteria=new CDbCriteria;


		$criteria->compare('id',$this->id);

		$criteria->compare('name',$this->name,true);


		return new CActiveDataProvider($this, array(

			'criteria'=>$criteria,

			'pagination'=>array("pageSize"=>$this->pageSize),//Declaring page size.

		));

	}

}







<?php echo CHtml::activeDropDownList($model,'pageSize',array(5=>5,10=>10,20=>20,50=>50,100=>100));?>

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

	'id'=>'edible-grid',

	'dataProvider'=>$model->search(),

	'filter'=>$model,

//calling beforeAjaxUpdate method.

	'beforeAjaxUpdate'=>'js:function(id,options)  

         {		

		var url=options.url;

		url=url+"&Edible[pageSize]="+$("#Edible_pageSize").val();

		options.url=url;		

		return true;

	 }',

	'columns'=>array(

		'id',

		'name',

		array(

			'class'=>'CButtonColumn',

		),

	),

)); ?>

<?php


Yii::app()->clientScript->registerScript('test','


$("#Edible_pageSize").on("change",function(){

	$("#edible-grid").yiiGridView("update",{data:{"Edible[pageSize]":$(this).val()}});

	});

');




I am making a dropDownList at the top of the grid.

name attribute of that input="Edible[pageSize]".

id attribute of that input="Edible_pageSize.

Both are by default made by YII.

In beforeAjaxUpdate method I am appending the value of the pageSize.So it is always available when going across pages and during filtering.

I am also registering script for ajax update of GRID when user changes the value of dropDownList.

Regards.

// Accessable with Yii::app()->params[‘paramName’]

‘params’=>array (

'defaultPageSize'=&gt;20,

hello sir,where can i change the params value in yii?? i mean in which page i have to change??

thank you

subbu vemuri

Hello, friends :)

I read all your posts and found no suitable solution but many interesting ideas and hints how I can do it.

My requirements are as follows:

  • Drop down menu allows the user to select the page size (how many rows per page to be showed in the grid)

  • User’s choice is stored in user’s state variable

  • The grid should works with any model, without need of model’s class modification

  • The page size menu should be optional (configurable) throug the template property.

So… I extended the CGridView and wrote this:


<?php


Yii::import('zii.widgets.grid.CGridView');


/**

 * Extends CGridView, adding drop down menu that controls the page size (number of items showed per page)

 */

class ExtendedGridView extends CGridView {


	/**

	 * @var string overides the parent default.

	 */

	public $template = "{items}\n{limit}\n{pager}";


	/**

	 * @var array the option values for use in the drop down

	 */

	public $pageSizeOptions = array('5' => '5', '10' => '10', '20' => '20', '50' => '50');


	/**

	 * @var integer the default page size (items per page shown)

	 */

	protected $defaultPageSize;


	public function init() {

		//Yii::log(CVarDumper::dumpAsString($this->customHtml), 'debug');

		if(isset($_GET['pageSize']) && is_numeric($_GET['pageSize'])) {

			Yii::app()->user->setState('pageSize', intval($_GET['pageSize']));

		}

		

		$pageSize = Yii::app()->user->getState('pageSize');

		$this->defaultPageSize = is_numeric($pageSize) ? $pageSize : $this->dataProvider->pagination->pageSize;

	

		$this->dataProvider->setPagination(array(

			'pageSize' => intval($this->defaultPageSize)

		));

		

		parent::init();

	}


	/**

	 * Renders the Show X amount of items drop down.

	 */

	public function renderLimit() {		

		echo CHtml::openTag('div', array('class' => 'grid-limit'));

		echo CHtml::label(t('extendedgridview.form.label.perpage_dropdown').':', null);

		echo CHtml::dropDownList('pageSize', $this->defaultPageSize, $this->pageSizeOptions, array(

			'class'=>'grid-limit-field',

			'id'=>__CLASS__.$this->getId()

		));

		echo CHtml::closeTag('div');

	}


	/**

	 * Overides parent to add in jQuery for the changing of the drop down lists.

	 */

	public function registerClientScript() {

		parent::registerClientScript();


		$id = $this->getId();

		Yii::app()->getClientScript()->registerScript(__CLASS__ . '#' . $id . '#limit-field', <<<___JS___

		$('#{$this->getId()} .grid-limit-field').live( 'change', function() { 

			$.fn.yiiGridView.update('{$id}', { data: $(this).serialize() }); 

			return false; 

		});

___JS___

		, CClientScript::POS_READY);

	}


}

I hope that somebody will benefit of my code.

Best regards,

Vladimir