Zalon
Zalon

Reputation: 85

yii sorting CListView with dropdown

So I have a CListView, that I can sort using the attributes I've set in sortableAttributes, this is fine when it's just ASC and DESC sorting. But I also want to sort the CListView by a category. In my model I have a category, ranging from 0-8. I've made a dropdown select that shows the categories.

What I would like to do is update my CListView when an option in the dropdown is selected, I could write my own jQuery code for this, but I'm guessing there is some smart yii way of doing this.

Thanks

<?php $this->widget('zii.widgets.CListView', array(
    'dataProvider'=>$model->search(),
    'sortableAttributes'=>array('views','create_time','release_time'),
    'id'=>'#videos',
    'itemView'=>$view,
    'pager'=>array('cssFile'=>'/css/pager.css'),
)); ?>

Upvotes: 3

Views: 4799

Answers (2)

Zalon
Zalon

Reputation: 85

For future reference, this is how I ended up doing it.

Yii::app()->clientScript->registerScript('category', "
$('#category').change(function(){
    $.fn.yiiListView.update('videos', {
        data: $(this).serialize()
    });
    return false;
});
");

The important part is the id in the htmlOptions of the dropDownList, as you cannot use "Video[category]" as the id for the $.fn.yiiListView.update function. But it is needed as the name of the select, to be able to use the already existing search ability.

<?php echo CHtml::dropDownList(
    'Video[category]',
    0,
    Lookup::items('VideoCategory'),
    array('id' => 'category')
); ?>

Upvotes: 2

bool.dev
bool.dev

Reputation: 17478

After much toiling:

There are two things you have to do. First, we need the modified data from the server, for that you could modify your model's search function, because that is the one providing the dataprovider for the CListView.

So in the search() function of your model you could add an if condition to modify the $criteria of the dataprovider, for example something like this:

public function search() {

     // Warning: Please modify the following code to remove attributes that
     // should not be searched.

     $criteria=new CDbCriteria;

     // added the following if condition to modify the criteria to include only videos of a certain category
     if (isset($_GET['category']))
           $criteria->compare('category',$_GET['category'],true);// my category is string, hence the third attribute
     else
           $criteria->compare('category',$this->category,true);// we need the else part, coz the search function is used for actual searching also, for instance in gridview filters/search

     $criteria->compare('id',$this->id);
     // your other attributes follow    

     return new CActiveDataProvider($this, array(
            'criteria'=>$criteria,
     ));
}

Note: I'm not sure if it is absolutely necessary to sanitize $_GET['category'] before comparing.

Second we need to update the CListView for which we can use its function $.fn.yiiListView.update. So for example:

<div id="categoryupdating">
<?php 
    echo CHtml::dropDownList('dropit', '', 
     array('1'=>'Cateogry1','2'=>'Category2','3'=>'Category3','4'=>'Category4'),
     array('onchange'=>"$.fn.yiiListView.update('videos', {url: '".Yii::app()->createUrl('controller/action')."?category='+$('#dropit option:selected').val()})"));
?>
</div>

Here ofcourse you should be populating the data for the dropdown dynamically using probably such functions as CHtml::listData , and the controller/action should be the controller/action of the CListView.

Check out the jquery.yiilistview.js file to know more about yii's listview widget's javascript functions.

Note: $.fn.yiiListView.update takes the id of the listview and the url to call for update, as parameters.

Edit: added else condition also, since the search function is used for actual searching in gridview, and elsewhere.

Upvotes: 2

Related Questions