Yii Framework Forum: CGridView sorting with CArrayDataProvider - Yii Framework Forum

Jump to content

Page 1 of 1
  • You cannot start a new topic
  • You cannot reply to this topic

CGridView sorting with CArrayDataProvider Rate Topic: -----

#1 User is offline   tomsea 

  • Junior Member
  • Pip
  • Yii
  • Group: Members
  • Posts: 66
  • Joined: 25-November 11

Posted 29 December 2011 - 10:53 PM

Hello, I am using CArrayDataProvider as the data provider for a CGridView, and everything works fine, except the sorting.

The "sorting links" are already in the column headers, but when I click any of them, the table gets empty.

Basically, this is what I'm doing:

In the model:
$command = Yii::app()->db->createCommand();
$command->select('*');
$command->from('example');
$rawData = $command->queryAll();
$dataProvider=new CArrayDataProvider($rawData, array(
    'sort'=>array(
	'attributes'=>array(
	     'field1', 'field2'
	),
    ),
    'pagination'=>array(
	'pageSize'=>20,
    ),
));


In the view:
$this->widget('zii.widgets.grid.CGridView', array(
    'dataProvider'=>$dataProvider,
        'columns'=>array(
                array(
                        'name'=>'field1',
                        'header'=>' My Field 1',
                ),
                array(
                        'name'=>'field2',
                        'header'=>' My Field 2',
                ),
        ),
));


Am I missing something? I will appreciate any ideas to make the sorting work.

Thanks in advance!
0

#2 User is offline   codesutra 

  • Advanced Member
  • PipPipPip
  • Yii
  • Group: Members
  • Posts: 596
  • Joined: 15-March 11
  • Location:India

Posted 30 December 2011 - 01:45 AM

View Posttomsea, on 29 December 2011 - 10:53 PM, said:

Hello, I am using CArrayDataProvider as the data provider for a CGridView, and everything works fine, except the sorting.

The "sorting links" are already in the column headers, but when I click any of them, the table gets empty.

Basically, this is what I'm doing:

In the model:
$command = Yii::app()->db->createCommand();
$command->select('*');
$command->from('example');
$rawData = $command->queryAll();
$dataProvider=new CArrayDataProvider($rawData, array(
    'sort'=>array(
	'attributes'=>array(
	     'field1', 'field2'
	),
    ),
    'pagination'=>array(
	'pageSize'=>20,
    ),
));


In the view:
$this->widget('zii.widgets.grid.CGridView', array(
    'dataProvider'=>$dataProvider,
        'columns'=>array(
                array(
                        'name'=>'field1',
                        'header'=>' My Field 1',
                ),
                array(
                        'name'=>'field2',
                        'header'=>' My Field 2',
                ),
        ),
));


Am I missing something? I will appreciate any ideas to make the sorting work.

Thanks in advance!



Try with
'enableSorting'=>true,

in a GridView.Might be this is missing thing.
CodeSutra
0

#3 User is offline   tomsea 

  • Junior Member
  • Pip
  • Yii
  • Group: Members
  • Posts: 66
  • Joined: 25-November 11

Posted 30 December 2011 - 12:23 PM

Thank you jayant, but it is not having any effect.

I will appreciate further ideas. Thank you.

Edit:

Ok I think I know where the problem is.

For this view I'm receiving a couple of parameters using "POST" method, so those parameters are lost when I click on the "sort link" in any column header, even though the sorting seems to use AJAX (the page is not fully reloaded and the 'spin' animation is shown for a moment). Without those parameters, the grid doesn't show anything because they are required to find the data to be displayed. I know this is the problem because I set those parameters to be constant in the controller, and now the grid is sorting just fine.

Is there any way to preserve the parameters? Be it passing the parameters again when sorting, or somehow preserve them when sorting through AJAX. I am a newbie in AJAX, so I thought that since the page is not fully reloaded, the parameters were to stay there, but it seems that's not true.

Thanks in advance!
0

#4 User is offline   codesutra 

  • Advanced Member
  • PipPipPip
  • Yii
  • Group: Members
  • Posts: 596
  • Joined: 15-March 11
  • Location:India

Posted 30 December 2011 - 11:00 PM

View Posttomsea, on 30 December 2011 - 12:23 PM, said:

Thank you jayant, but it is not having any effect.

I will appreciate further ideas. Thank you.

Edit:

Ok I think I know where the problem is.

For this view I'm receiving a couple of parameters using "POST" method, so those parameters are lost when I click on the "sort link" in any column header, even though the sorting seems to use AJAX (the page is not fully reloaded and the 'spin' animation is shown for a moment). Without those parameters, the grid doesn't show anything because they are required to find the data to be displayed. I know this is the problem because I set those parameters to be constant in the controller, and now the grid is sorting just fine.

Is there any way to preserve the parameters? Be it passing the parameters again when sorting, or somehow preserve them when sorting through AJAX. I am a newbie in AJAX, so I thought that since the page is not fully reloaded, the parameters were to stay there, but it seems that's not true.

Thanks in advance!


try likethis in controller file
    $criteria->params=array(':status'=>'Publish',':cityId'=>$cityId,':sdate'=>$sdate);


and let me know if it works..
CodeSutra
0

#5 User is offline   codesutra 

  • Advanced Member
  • PipPipPip
  • Yii
  • Group: Members
  • Posts: 596
  • Joined: 15-March 11
  • Location:India

Posted 30 December 2011 - 11:03 PM

Here i am putting my a bit complex search filter code from controller file. i hope this will help you a lot.Since its work like a charm for me..


	public function actionUpcoming()
	{

		$this->layout = "inner";
		$model = new Event();

		$cityList = CHtml::listData(City::model()->findAll(array('order'=>'cityname ASC')), 'id', 'cityname');

		$criteria 			 =	new CDbCriteria();
		$criteria->condition = 'status=:status AND city_id =:cityId AND start_date >= :sdate';

		if(isset($_GET['keyword']) && $_GET['keyword']!='Search Event'){
			$keyword = $_GET['keyword'];
			$criteria->addCondition('event_name LIKE "%'.$keyword.'%"');
		}

		if(isset($_GET['city'])){
			$cityId = $_GET['city'];
			$sdate = date('Y-m-d');
			if(isset($_GET['music_genre']) && $_GET['music_genre'] !='' && isset($_GET['date']) && $_GET['date'] !='Calender'){
				$sdate = $_GET['date'];
				$music_genre = $_GET['music_genre'];
				$criteria->addCondition('music_genre ="'.$music_genre.'"');
				$criteria->addCondition('start_date ="'.$sdate.'"');
			}elseif(isset($_GET['music_genre']) && $_GET['music_genre'] !=''){
				$music_genre = $_GET['music_genre'];
				$criteria->addCondition('music_genre ="'.$music_genre.'"');
			}elseif(isset($_GET['date']) && $_GET['date'] !='Calender'){
				$sdate = $_GET['date'];
				$criteria->addCondition('start_date ="'.$sdate.'"');
			}else{
				$sdate = date('Y-m-d');
			}
		}else{
			$cityId=Yii::app()->session->get('currentcity');
			if(isset($cityId) && !empty($cityId) ){
		    	$cityId = $cityId;
		    }else{
		    	$cityId = 1;
		    }
		    $sdate = date('Y-m-d');
		}

		$cityName = City::model()->cityName($cityId);

		$criteria->params=array(':status'=>'Publish',':cityId'=>$cityId,':sdate'=>$sdate);
		$dataProvider = new CActiveDataProvider('Event', array(
                                'pagination'=>array(
                                'pageSize'=>15,
                                //'params' => array('city' => $cityId,'sortby'=>$sortBy),
                                ),
                                'criteria'=>$criteria,

		));

		$this->render('upcoming',array('dataProvider'=>$dataProvider,'cityList'=>$cityList,'cityId'=>$cityId,'cityName'=>$cityName));
	}


CodeSutra
0

#6 User is offline   MrLe 

  • Newbie
  • Yii
  • Group: Members
  • Posts: 4
  • Joined: 22-February 12

Posted 19 March 2012 - 09:25 PM

Just wanted to share my solution sorting a column value involving relations. Trick is to make the grid column header a link so that it will sort via query. Am welcoming improvements/suggestions.

Model:
public $sort_user_profile_url="";
public $default_order=array();


Controller:
$criteria = new CDbCriteria;

$model->sort_user_profile_url = Yii::app()->baseUrl."/controller_name/action_name/sort/userProfile/asc";

        if( isset($_REQUEST["sort"]) )
        {
            if( $_REQUEST["sort"] == "userProfile" && (boolean)array_key_exists("asc", $_REQUEST) )
            {
                $model->sort_user_profile_url = Yii::app()->baseUrl."/controller_name/action_name/sort/userProfile/desc";
                $criteria->order='profile.firstname ASC';
            }
            elseif( $_REQUEST["sort"] == "userProfile" && (boolean)array_key_exists("desc", $_REQUEST) )
            {
                $criteria->order='profile.firstname DESC';
            }
        }
        else
        {
            $model->default_order=array('id' => true);      // reset default order by id
        }

$data=controller_name::model()->resetScope()->with( array( 'profile'=>array('together'=>true, 'joinType'=>'INNER JOIN') ) )->findAll($criteria);


View:
$dataProvider = new CArrayDataProvider($data, array(
        'sort'=>array(
            'attributes'=>array('id'),
            'defaultOrder'=>$model->default_order,
        ),
        'pagination'=>array(
            'pageSize'=>20,
        ),
    ));

$widget_grid=$this->widget('zii.widgets.grid.CGridView', array(
        'id'=>'grid-id',
        'dataProvider'=>$dataProvider,
        'columns'=>array(
            array('name'=>'id', 'header'=>Yii::t('app', $model->getAttributeLabel('id'))),
            array('name'=>'profile.name', 'header'=>CHtml::link( Yii::t('app', $model->getAttributeLabel('profile.name')), '#', array('onclick'=>'js:window.location="'.$model->sort_user_profile_url.'";')),    
                'value'=>'$data->profile->firstname." ".$data->profile->lastname'),
            
        ),
    ));

0

#7 User is offline   kenburcham 

  • Newbie
  • Yii
  • Group: Members
  • Posts: 1
  • Joined: 09-November 11

Posted 22 March 2012 - 07:02 PM

I ended up doing something pretty similar, but just used the Yii automagic incoming variable setting:

in my controller:
 public function actionReports($sort = 'title') // later my &sort=title link param will end up with $sort=title
 {
            //populate up an array i want to display
            $rd = new ArrayReportDocumentor();
            $reports = $rd->processAllReports();
            
            $dataProvider=new CArrayDataProvider($reports, array(
                'id'=>'id',
                'sort'=>array(
                    'defaultOrder'=> $sort.' ASC',
                    'attributes'=>array(
                        'title', 'report_type', 'filename'
                    ),
                ),
                'pagination'=> false, //array(
                    //'pageSize'=>15,
                //),
            ));
            
            $sort_url = $this->createAbsoluteUrl($this->action->id);
            
            $this->render('list_reports', array('reportsProvider' => $dataProvider, 'sort_url' => $sort_url));
        }


in my view:


$this->widget('zii.widgets.grid.CGridView', array(
	'dataProvider' => $reportsProvider,
	'columns' => array(

		array(
			'name' => 'Title',
			'type' => 'raw',
                        'header' => CHtml::link('Title','#',array('onclick'=>'js:window.location="'.$sort_url.'&sort=title";')),
			'value' => 'CHtml::encode($data["title"])'
		),
                array(
			'name' => 'Description',
			'type' => 'raw',
			'value' => 'CHtml::encode($data["description"])'
		),
		array(
			'name' => 'Type',
			'type' => 'raw',
                        'header' => CHtml::link('Type','#',array('onclick'=>'js:window.location="'.$sort_url.'&sort=report_type";')),
			'value' => 'CHtml::encode($data["report_type"])'
		),
		array(
			'name' => 'Actual File',
			'type' => 'raw',
                        'header' => CHtml::link('Filename','#',array('onclick'=>'js:window.location="'.$sort_url.'&sort=filename";')),                    
			'value' => 'CHtml::encode($data["filename"])'
		),
                array(
			'name' => 'Params',
			'type' => 'raw',
			'value' => 'implode("<br/>",$data["params"])'
		),
                

	),
));


Not sure if this is the best way, really, but it works!
0

#8 User is offline   MrLe 

  • Newbie
  • Yii
  • Group: Members
  • Posts: 4
  • Joined: 22-February 12

Posted 25 March 2012 - 09:09 PM

I think it's more flexible/powerful if we do it via Yii's inbuilt search() that way we could use a dropdownlist to filter results and sort at the same time. That is, we are not using CArrayDataProvider, but CActiveProvider. Note: I had a problem with the ajax search function when I included <form enctype="multipart/form-data">.

For example,

Model:
public $titles_name="";

return array(
			array('titles_name', 'safe', 'on'=>'search'),
		);

public function relations()
	{
		return array(
            'titles'=>array(self::BELONGS_TO, 'Titles', 'title_id' ),
		);
	}


public function search()
	{
		$criteria=new CDbCriteria;
		
	    $criteria->with = array(
	        'titles' => array(
	            'condition' => 'titles.item_type = :item_type',
	            'params' => array(':item_type' => 1),
	        ),
	    );
	    $criteria->together = true;

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

		return new CActiveDataProvider($this, array(
			'criteria'=>$criteria,
			'sort'=>array(
			    'attributes'=>array(
			        'titles_name'=>array(
			            'asc'=>'titles.name',
			            'desc'=>'titles.name DESC',
			        ),
			    ),
			),
		));
	}

Controller:
$model=new ControllerName('search');

        $model = new ItemPurchases('search');
	    $model->unsetAttributes();  // clear any default values
		if(isset($_GET['ControllerName']))
			$model->attributes=$_GET['ControllerName'];


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

View:
<div class="search-form" style="display:none"></div>

$widget_grid=$this->widget('zii.widgets.grid.CGridView', array(
	'id'=>'grid-id',
	'dataProvider'=>$model->search(),
	'filter'=>$model,
        'columns'=>array(
		array('name'=>'titles_name', 'header'=>Yii::t('app', $model->getAttributeLabel('title_id')), 'value'=>'$data->titles->name', 'filter' => CHtml::listData(ControllerName2::model()->resetScope()->with( array('titles'=>array('joinType'=>'INNER JOIN')) )->findAll(), 'titles.name', 'titles.name'), 'type'=>'raw'),
		array('name'=>'id', 'header'=>Yii::t('app', $model->getAttributeLabel('id'))),

	),
));

0

Share this topic:


Page 1 of 1
  • You cannot start a new topic
  • You cannot reply to this topic

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