CGridView problem with dropdownlist

Hi, I have problem about pagination from CGridView by selecting from dropdownlist. Because it no keep state after I select option from dropdown. I show image below. How can i solve this problem. Thank for your advice.

Step 1.

2679

19-3-2555 11-47-22.jpg

Step 2.

2680

19-3-2555 11-49-58.jpg

Step 3.

2681

19-3-2555 11-52-02.jpg

Step 4.

2682

19-3-2555 11-53-53.jpg

Without more informations, I would say that your response should return the value of the first option so that you can use it as a parameter while changing the page.

can u show example for me please? Thank you.

Right now, I can’t help you further, because of lack of time. But if you post here your view, and your contoller actions called by the form, I will have a look at it later this evening.

Did you solve your problem ?

If not, more informations about your application logic is needed:

  • the view

  • controller action

  • model search function

  • parameters sent while changing option with the dropdown

Ok thank you for your help.

This is view




<?php

$this->breadcrumbs=array(

	'Coin',

);?>


<?php 

echo CHtml::beginForm('','post',array('id'=>'order-form'));

?>

Status: <?php echo CHtml::dropDownList('ddlStatus', $_POST['ddlStatus'] == '' ? 'AP': $_POST['ddlStatus'], Coin::model()->getStatus())?>&nbsp;

Bill Type: <?php echo CHtml::dropDownList('ddlBillType', $_POST['ddlBillType'] == '' ? 'CR' : $_POST['ddlBillType'], Coin::model()->getBillType())?>&nbsp;

Zone: <?php echo CHtml::dropDownList('ddlZone', $_POST['ddlZone'] == '' ? '01' : $_POST['ddlZone'], Coin::model()->getZone())?>&nbsp;

Pay Type: <?php echo CHtml::dropDownList('ddlPayType', $_POST['ddlPayType'] == '' ? '01' : $_POST['ddlPayType'], Coin::model()->getPayType())?>&nbsp;

วันที่: 

<?php

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

    'name'=>'date',

	'value'=>$_POST['date'],

    'language'=>Yii::app()->language=='et' ? 'et' : null,

    'options'=>array(

        'showAnim'=>'fold', // 'show' (the default), 'slideDown', 'fadeIn', 'fold'

        'showOn'=>'button', // 'focus', 'button', 'both'

        'buttonText'=>Yii::t('ui','Select form calendar'), 

        'buttonImage'=>Yii::app()->request->baseUrl.'/images/calendar.png', 

        'buttonImageOnly'=>true,

		'dateFormat'=>'dd-mm-yy',

    ),

    'htmlOptions'=>array(

        'style'=>'width:80px;vertical-align:top'

    ),  

));

?>&nbsp;

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

    'buttonType'=>'submit',

    'name'=>'btnSubmit',

    'value'=>'1',

    'caption'=>'แสดงรายการ',

));?>

<p></p>

<hr>

<p></p>

<?php 

// ลิงค์สำหรับเลือกด้านบน

$this->widget('ext.widgets.bmenu.XBatchMenu', array(

    'formId'=>'order-form',

    'checkBoxId'=>'order-id',

    'ajaxUpdate'=>'order-grid', // if you want to update grid by ajax

    'emptyText'=>Yii::t('ui','กรุณาเลือกรายการก่อนครับ!'),

    'confirm'=>Yii::t('ui','คุณต้องการเลือกรายการดังกล่าวใช่หรือไม่?'),

    'items'=>array(

        array('label'=>Yii::t('ui','ยืนยันรายการที่เลือก'), 'url'=>array('updateItems', 'op'=>'selected')),

    ),

    'htmlOptions'=>array('class'=>'actionBar'),

));

?>

<?php $pageSize=Yii::app()->user->getState('pageSize', Yii::app()->params['defaultPageSize']);?>

<?php

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

    'id'=>'order-grid',

    'dataProvider'=>$dataProvider,

	'enableSorting'=>false,

	//'ajaxUpdate'=>false,

    'selectableRows'=>2, // multiple rows can be selected

    'columns'=>array(

        array(

            'class'=>'CCheckBoxColumn',

            'id'=>'order-id',

        ),

        array(

				'name' => 'ginv_no',

				'htmlOptions' => array('width'=>'150px'),

			),

		array(

				'name' => 'Inv_Date',

				'value' => 'date_format(date_create($data->Inv_Date), "d-M-Y")',

			),

		array(

				'name' => 'Send_Date',

				'value' => 'date_format(date_create($data->Send_Date), "d-M-Y")',

			),

		array(

				'name' => 'CU_NAME',

				'htmlOptions' => array('style'=>'text-align:left'),

			),

		array(

				'name' => 'wh_name',

				'htmlOptions' => array('style'=>'text-align:center'),

			),

		array(

				'name' => 'AR_AMT',

				'htmlOptions' => array('style'=>'text-align:right'),

			),

    ),

));


Yii::app()->clientScript->registerScript('initPageSize', <<<EOD

	$('.change-pagesize').live('change', function(){

		$.fn.yiiGridView.update('order-grid', {data:{pagesSize: $(this).val()}})

	});

EOD

,CClientScript::POS_READY);


echo CHtml::endForm();


// ลิงค์สำหรับเลือกด้านล่าง

$this->widget('ext.widgets.bmenu.XBatchMenu', array(

    'formId'=>'order-form',

    'checkBoxId'=>'order-id',

    'ajaxUpdate'=>'order-grid', // if you want to update grid by ajax

    'emptyText'=>Yii::t('ui','กรุณาเลือกรายการก่อนครับ!'),

    'confirm'=>Yii::t('ui','คุณต้องการเลือกรายการดังกล่าวใช่หรือไม่?'),

    'items'=>array(

        array('label'=>Yii::t('ui','ยืนยันรายการที่เลือก'), 'url'=>array('updateItems', 'op'=>'selected')),

    ),

    'htmlOptions'=>array('class'=>'actionBar'),

));

?>



Controller




<?php


class CoinController extends Controller

{

	public function actionIndex()

	{

		if(!isset($_POST['btnSubmit']))

		{

			$dataProvider = Coin::model()->getData('AP', 'CR', '01', '01', $date);

			$this->render('index', array('dataProvider'=>$dataProvider));		

		}

		else

		{

			if(isset($_GET['pageSize']))

			{

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

				unset($_GET['pageSize']);

			}

			$status = $_POST['ddlStatus'];

			$bill_type = $_POST['ddlBillType'];

			$zone_code = $_POST['ddlZone'];

			$pay_type = $_POST['ddlPayType'];

			$date = $_POST['date'];

			

			$dataProvider = Coin::model()->getData($status, $bill_type, $zone_code, $pay_type, $date);

			$this->render('index', array('dataProvider'=>$dataProvider));

		}	

	}

	

	public function actionUpdateItems()

	{

		if(isset($_GET['pageSize']))

		{

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

				unset($_GET['pageSize']);

		}

		// allow POST request only

		if(Yii::app()->request->isPostRequest)

		{

			$status = $_POST['ddlStatus'];

			$chkPack = $_POST['chkPack'];

			$currentday = date("Y-m-d"); //2012-02-08

			$currenttime = date("H:i:s");

			$orderid = $_POST['order-id'];

			$select=!empty($_GET['op']) && $_GET['op']=='selected' ? 1 : 0;

			

			if($status==='AP')

			{

				if($_POST['chkPack'])

				{

					Coin::model()->updateByPk($_POST['order-id'], array('PackD'=>$currentday, 'PackT'=>$currenttime,'SendD'=>$currentday, 'SendT'=>$currenttime, 'Doc_Flow'=>'S'));

				}

				else

				{

					Coin::model()->updateByPk($_POST['order-id'], array('PackD'=>$currentday, 'PackT'=>$currenttime, 'Doc_Flow'=>'P'));

				}

			}

			elseif ($status==='P')

			{

				Coin::model()->updateByPk($_POST['order-id'], array('SendD'=>$currentday, 'SendT'=>$currenttime, 'Doc_Flow'=>'S'));

			}

			elseif ($status==='S')

			{

				Coin::model()->updateByPk($_POST['order-id'], array('Doc_Flow'=>'T'));

			}

			

			//Coin::model()->updateByPk($orderid, array('PackD'=>$currentday, 'PackT'=>$currenttime,'SendD'=>$currentday, 'SendT'=>$currenttime, 'Doc_Flow'=>'S'));

			

			// if AJAX request, we should not redirect the browser

			if(!isset($_GET['ajax']))

			{

				if(!$this->goBack())

					$this->redirect(array('index'));

				else

					$this->goBack();

			}

		}

		else

		{

			throw new CHttpException(400, 'Invalid request. Please do not repeat this request again.');

		}

	}


	// Uncomment the following methods and override them if needed

	

	public function filters()

	{

		// return the filter configuration for this controller, e.g.:

		return array(

			'accessControl', // perform access control

		);

	}

	

	public function accessRules()

	{

		return array(

			/*array('allow', // allow all users to perform 'index' and 'view' actions

				'actions'=>array('index'),

				'users'=>array('*'),

			),*/

			array('allow', // allow authenticated user to perform 'create' and 'update' actions

				'actions'=>array('index'),

				'users'=>array('@'),

			),

			array('allow', // allow admin user to perform 'admin' and 'delete' actions

				'actions'=>array('updateitems'),

				'users'=>array('lakhana   '),

			),

			array('deny', // deny all users

				'users'=>array('*'),

			),

		);

	}

	

	/*

	public function actions()

	{

		// return external action classes, e.g.:

		return array(

			'action1'=>'path.to.ActionClass',

			'action2'=>array(

				'class'=>'path.to.AnotherActionClass',

				'propertyName'=>'propertyValue',

			),

		);

	}

	*/

}



Model




class Coin extends CActiveRecord

{

   public function getStatus()

	{

		return array(

			'AP' => 'พิมพ์แล้ว',

			'P' => 'จัดส่งสินค้า',

			'S' => 'ส่งสินค้า',

			'T' => 'โอนบิล',

			'B' => 'Balance',

			'C' => 'Cancel'

		);	

	}

	

	public function getBillType()

	{

		$sql = "SELECT ref_code, ref_desc FROM ref_data WHERE ref_type = '05' ORDER BY ref_code";

		$rows = Yii::app()->db->createCommand($sql)->queryAll();

		

		foreach ($rows as $row)

		{

			$list[$row['ref_code']] = $row['ref_desc'];

		}

		

		return $list; 

	}

	

	public function getZone()

	{

		$sql = "SELECT ref_code, ref_desc FROM ref_data WHERE ref_type = '06' ORDER BY ref_code";

		$rows = Yii::app()->db->createCommand($sql)->queryAll();

		

		foreach ($rows as $row)

		{

			$list[$row['ref_code']] = $row['ref_desc'];

		}

		

		return $list;

	}

	

	public function getPayType()

	{

		$sql = "SELECT ref_code, ref_desc FROM ref_data WHERE ref_type = 'PT' ORDER BY ref_code";

		$rows = Yii::app()->db->createCommand($sql)->queryAll();

		

		foreach ($rows as $row)

		{

			$list[$row['ref_code']] = $row['ref_desc'];

		}

		

		return $list;

	}

	

	public function getData($status, $bill_type, $zone_code, $pay_type, $date)

	{

		$criteria = new CDbCriteria;

		

		if($status != 'S')

		{

			$s1 = ' warehouse.wh_name, Rec_Stat';

			$s2 = ' LEFT JOIN warehouse ON t.wh_code = warehouse.wh_code';

			$s3 = ', send_date DESC';

		}

		else

		{

			$s1 = ' saleman.sl_name AS sl_name';

			$s2 = ' LEFT JOIN saleman ON t.Sl_Code = saleman.Sl_Code';

			$s3 = '';

		}

		

		$criteria->select = "Doc_No, (Bill_Type + '-' + t.ZO_Code + '-' + PT_Code + '-' + Inv_No ) AS ginv_no, Inv_Date, Send_Date, customer.CU_NAME, $s1, AR_AMT";

		$criteria->join = "LEFT JOIN Customer ON Customer.Cu_Code = t.Cu_Code" . $s2;

		$criteria->compare('Bill_Type', $bill_type);

		if(!empty($date))

		{

			$criteria->compare('Inv_Date', $date);

		}

		$criteria->compare('t.ZO_Code', $zone_code);

		

		if($status === 'AP')

		{

			$criteria->addCondition('Bill_FD IS NOT NULL');

		}


		$criteria->compare('Doc_Flow', substr($status, 0, 1));

		$criteria->addNotInCondition('Rec_Stat', array(C, X), 'AND');

		$criteria->order = 'ginv_no, Doc_No, Send_Date ASC';

		

		

		return new CActiveDataProvider($this, array(

			'criteria' => $criteria,

			'pagination' => array(

				'pageSize'=>Yii::app()->user->getState('pageSize', Yii::app()->params['defaultPageSize'])

			),

		));

	}



Ok, I understand. First I was thinking that your dropdowns wher some CGridView filters, but they are in fact in a submit form. So, when using the pager your parameters from this submit form are lost.

I see two different ways for solving that problem:

  • in CGridView, you can define a ‘pager’ property: Defaults to array(‘class’=>‘CLinkPager’) that you can override with your own class. CreatePageButton calls CPagination createPageUrl. You may overide this to pass all your params that are sets in the submit form.

  • use the principle of the "custom search" generated by gii crud utility to filter your datas with your dropdowns and refresh the grid via ajax

Hi luc. Can you show sample code for me? I try to your recommended already. It’s not work. But I am not sure that the correct solution.

Hi Jack. If you can solve this please tell me. Thank you.

Who can help me? ;)

Below a working example of solution 2:

I use ‘Sakila’ database data sample and most of the code genereted by gii.

Model ‘Customer’:




	// 'district' is defined in the related model 'address'

	public $district;


	public function rules()

	{

		// NOTE: I've added 'city' and 'district' 

		return array(

			array('customer_id, store_id, first_name, last_name, email, address_id, active, create_date, last_update, city, district', 'safe', 'on'=>'search'),

		);

	}


	public function relations()

	{

		return array(


			'address' => array(self::BELONGS_TO, 'Address', 'address_id'),

		);

	}


	public function attributeLabels()

	{

		return array(

			//added here for the form and yhe gridview

			'district' => 'district',

			'city'=>'city',

		);

	}


	public function search()

	{

		// Warning: Please modify the following code to remove attributes that

		// should not be searched.


		$criteria=new CDbCriteria;


		$criteria->with=array('address','address.city');

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

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


		return new CActiveDataProvider($this, array(

			'criteria'=>$criteria,

		));

	}



Controller :




	public function actionAdmin()

	{

		$model=new Customer('search');

		$model->unsetAttributes();  // clear any default values

		if(isset($_GET['Customer']))

			$model->attributes=$_GET['Customer'];


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

			'model'=>$model,

		));

	}



View:




Yii::app()->clientScript->registerScript('search', "

$('.search-button').click(function(){

	$('.search-form').toggle();

	return false;

});

$('.search-form form').submit(function(){

	$.fn.yiiGridView.update('customer-grid', {

		data: $(this).serialize()

	});

	return false;

});

");

?>




<div class="search-form" 	>

<?php $this->renderPartial('_search',array(

	'model'=>$model,

)); ?>

</div><!-- search-form -->


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

	'id'=>'customer-grid',

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

	'filter'=>$model,

	'columns'=>array(

		//'customer_id',

		//'store_id',

		'first_name',

		'last_name',

		'email',

		'address.address',

		'address.city.city',

		'address.district',

		'active',

		/*'create_date',

		'last_update',

		*/

		array(

			'class'=>'CButtonColumn',

		),

	),

));



_search partial :




<?php $form=$this->beginWidget('CActiveForm', array(

	'action'=>Yii::app()->createUrl($this->route),

	'method'=>'get',

)); ?>


	<div class="row">

		<?php echo $form->label($model,'city'); ?>

		<?php echo $form->textField($model,'city'); ?>

	</div>


	<div class="row">

		<?php echo $form->label($model,'district'); ?>

		<?php echo $form->dropDownList($model,'district',CHtml::listData(Address::model()->findAll(),'district','district'),array('prompt'=>'')); ?>

	</div>


	<div class="row">

		<?php echo $form->label($model,'active'); ?>

		<?php echo $form->dropDownList($model,'active',array('1'=>'yes','0'=>'no'),array('prompt'=>'')); ?>

	</div>




	<div class="row buttons">

		<?php echo CHtml::submitButton('Search'); ?>

	</div>


<?php $this->endWidget(); ?>



PS: I do not really understand whath these statements are for:




Status: <?php echo CHtml::dropDownList('ddlStatus', $_POST['ddlStatus'] == '' ? 'AP': $_POST['ddlStatus'], Coin::model()->getStatus())?>&nbsp



hmmmm, after having posting that, I had a look at your code and I realize that you will have to introduce some custom search method, but I do not really know how to do that …

Thank you for your advise luc. :rolleyes:

Try to add this code at the bottom of your view page before the closing body tag:




<script type="text/javascript">

    $('#order-form').submit(function(){

        $.fn.yiiGridView.update('order-grid', {

            data: $(this).serialize()

        });

        return false;

    });

</script>



I think it’ll update the query parameters to be sent to the server by the gridview.

ok fricky_world. I will try later. Thanks :)

Hi fricky_world. I’m tried but it’s not work. After click submit it not work. How else? :(

I think it’s because the value from the submit button is never sent.

How about changing this line (in your controller):

if(!isset($_POST[‘btnSubmit’]))

into this:

if(!isset($_POST[‘ddlStatus’]))

Same problem. :(

How about using $_GET:

if(!isset($_GET[‘ddlStatus’]))

I think the javascript "$.fn.yiiGridView.update" send the value using $_GET parameter.

That also means that you need to change all the $_POST into $_GET

$status = $_GET[‘ddlStatus’];

$bill_type = $_GET[‘ddlBillType’];

$zone_code = $_GET[‘ddlZone’];

$pay_type = $_GET[‘ddlPayType’];

$date = $_GET[‘date’]

Thank you very much fricky_world. It’s work. :)