Yii框架下CDataColumn中filter,pager样式定义应用实例

jerry Yii 2015年08月18日 收藏

filter首先要有自己的数据源,这个可以是当前表格使用的model,也可以是其他一些array,这个实例中我使用了当前model,CGridView的filter字段如果不设置,表格中不会出现filter一栏.在这个controll中,我使用model的中一个search改写的方法searchgrid来生成model实例,editkey方法是用来接收jeditable传值,对key字段尽心修改的方法,因为返回很简单,所以只使用了0和1返回修改后状态即可

  1.  public function actionIndex() {
  2.          if (Yii::app()->user->isGuest) {
  3.              $this->redirect(array('index/login'));
  4.              exit;
  5.          }
  6.          $this->select['key'] = "current";
  7.  
  8.          $model = new CyaskQuestion('searchgrid');
  9.          $this->render("index", array('model' => $model));
  10.  
  11.  }
  1.  /**
  2.  *接受ajax传值,修改关键字
  3.  *@param int qid
  4.  */
  5.   public function actionEditKey() {
  6.          $qid = Yii::app()->request->getParam('qid') != '' ? Yii::app()->request->getParam('qid') : 0;
  7.          $key = Yii::app()->request->getParam('key') != '' ? Yii::app()->request->getParam('key') : '';
  8.          if ($qid > 0 && $key != '') {
  9.              $model           = CyaskQuestion::model()->find('qid=:qid', array(':qid' => $qid));
  10.              $model->keywords = $key;
  11.              if ($model->validate() && $model->save()) {
  12.                 exit("1");
  13.             } else {
  14.                 exit("0");
  15.             }
  16.         }
  17.     }

在model中需要建立一个修改后的search方法,当然如果你直接修改search方法也可以,在很多网上的文章中讲解CGridView时候,dataProvider中总是使用$model->search()来提供数据,就是这个意思,我这里另建立了一个方法来提供数据,当你点击选择filter数据的时候,被选择的filter数据会发送给controll,controll建立model的过程中model就会得到这个filter值,所以,如果没有filter就取出全部数据,有filter值就根据值来取数据.

  1. /**
  2.  * 根据传上来的分类值来提取question列表
  3.  *@param int sort分类
  4.  */
  5.  public function searchGrid() {
  6.         $sort           = Yii::app()->request->getParam('sort');        
  7.         $criteria       = new CDbCriteria;        
  8.         $criteria->with = 'so';        
  9.         
  10.         if ($sort > 0) {            
  11.              $criteria->addCondition('t.sid1=:sid');            
  12.              $criteria->params[':sid'] = $sort;        
  13.          }        
  14.          return new CActiveDataProvider($this, array(            
  15.                  'criteria'   => $criteria,            
  16.                  'pagination' => array(                
  17.                          'pageSize' => 20,                
  18.                          'pageVar'  => 'page',            
  19.                          ),        
  20.          ));    
  21.    }

下来是view页面,在CGridView中,首先要设置CGridVIew的filter属性,这样表格才会出现filter一栏,然后在每个列定义时候要定义filter的具体数据,如果此列不需要filter功能,可以将此列的filter关闭,如果在CGridView的column定义中没有定义class,默认都是CDataColumn,所以filter是CDataColumn的属性之一,这点大家要清楚,我在sort列增加了filter,其他列关闭了filter.filter是一个下拉选框,所以使用了CHtml::droDownList来显示数据.另外,由于使用了jeditable插件,所以其中的key数据列中使用了value属性,属性值是一段js代码,这段代码Yii会自动返回成js来执行,其目的是为了给jeditable执行点击编辑效果增加一个类指示标识,以方便起找到这个html元素.

  1. <?php
  2.        $this->widget('zii.widgets.grid.CGridView', array(
  3.            'id'            => 'key_grid',
  4.            //这个是表格的数据提供源定义
  5.            'dataProvider'  => $model->searchgrid(),
  6.            //这里如果不设置,表格就不会出现filter一栏
  7.            'filter'        => $model,
  8.            //这个是表格样式定义,可以自己改一下看看
  9.            'itemsCssClass' => 'items',
  10.            //因为表格行样式和其他地方有冲突,所以在这里定义了表格行的样式
  11.            'rowCssClass'   => array('odd alt-row', 'even'),
  12.            //CGridView的页脚样式定义,很多人问怎么定义页脚样式,所以这里也贴了出来
  13.            'pager'         => array(
  14.                'header'            => '',
  15.                'maxButtonCount'    => 7,
  16.                'firstPageCssClass' => 'previous',
  17.                'lastPageCssClass'  => 'next',
  18.                'firstPageLabel'    => '<<',
  19.                'lastPageLabel'     => '>>',
  20.                'prevPageLabel'     => '<',
  21.                'nextPageLabel'     => '>',
  22.            ),
  23.            'columns'       => array(
  24.                //没有定义class属性的,都默认是CDataColumn类,'filter' => false,就是关闭了本列的filter功能
  25.                array('name' => 'qid', 'header' => 'ID', 'filter' => false, 'htmlOptions' => array('style' => 'text-align:center')),
  26.                array('name' => 'asktime', 'header' => '发表时间', 'value' => 'date("Y-m-d",$data->asktime)', 'filter' => false, 'htmlOptions' => array('style' => 'text-align:center')),
  27.                array('name'        => 'so.sort1', 'header'      => '分类',
  28.                    //sort栏的filter没有关闭,使用的是CyaskSort分类表里的sort数据,其实这个完全可以在CyaskSort的model里写个方法,直接返回listData的数据,也简洁明白.为了大家看明白,专门贴出数据来源方式
  29.                    'filter'      => CHtml::dropDownList('sort', '', CHtml::listData(CyaskSort::model()->findAll("sid1=0"), 'sid', 'sort1')), 'htmlOptions' => array('style' => 'text-align:center'),
  30.                ),
  31.                array('name' => 'title', 'header' => '标题', 'filter' => false, 'htmlOptions' => array('style' => 'text-align:center;width:600px')),
  32.                //这一列应用了jeditable,在value中的定义目的是为了返回一个class等于editable的div,title属性是为了如果修改不成功,就提取出来这个属性,将该栏还原为原来的数据,type这一属性很重要,raw是指这一栏的value属性不会用html的encode进行URL 编码,否则,你将看到<div></div>显示在数据栏里.
  33.                array('name'        => 'keywords',
  34.                    'header'      => '关键字',
  35.                    'filter'      => false,
  36.                    'htmlOptions' => array('style' => 'text-align:center;width:400px;height:25px'),
  37.                    'value'       => function($data) {
  38.                    return '<div class="edittable" id=' . $data->qid . ' title="' . $data->keywords . '">' . $data->keywords . '</div>';
  39.                },
  40.                    'type' => 'raw'
  41.                ),
  42.            ),
  43.            //afterAJaxUpdate属性是可以在filter动作获得数据后,再进行一些js的动作,本例中不需要,但是这个属性对扩展一些功能很重要,所以贴出来,大家可以根据自己需求改写.
  44.            'afterAjaxUpdate' => 'function(){}',
  45.        ))
  46.        ?>
  47.        <!--引入表格编辑插件-->
  48.        <?php Yii::app()->clientScript->registerScriptFile(Yii::app()->request->baseUrl . '/js/jquery.jeditable.js'); ?>
  49.        <script type="text/javascript">
  50.            $("div[class^='edittable']").editable(function(value, settings) {
  51.                //要修改的是那一行,就依靠这个id来辨别,这个是<div class="editable">元素中提供的
  52.                id = $(this).attr("id");
  53.                //这个就是原有值,本方法中的value是修改后的值
  54.                orikey = $(this).attr('title');
  55.                $.ajax({
  56.                    type: "post",
  57.                    //如果在Yii中开启了Token验证,这里就必须把csrfToken一起传上去,否则,不会接受你发送的数据的
  58.                    data: "key=" + value + "&qid=" + id + "<?php echo '&' . Yii::app()->request->csrfTokenName . "=" . Yii::app()->request->getCsrfToken() ?>",
  59.                    url: "<?php echo $this->createUrl("key/editkey") ?>",
  60.                    async: false,
  61.                    success: function(data) {
  62.                        if (data != '1') {
  63.                            alert('修改失败');
  64.                            //修改失败就用原值来返回,否则返回的是修改后的值
  65.                            value = orikey;
  66.                        }
  67.                    }
  68.                })
  69.                return value;
  70.            }, {
  71.                //这个是edittable的编辑栏样式定义,还有很多参数,有兴趣大家可以自己找些资料看
  72.                submit: "OK",
  73.                width: 200,
  74.            });
  75.        </script>

另外,CGridView使用了Jquery的类库,如果你在页面其他地方手动调用jquery可能会出现冲突错误,如

  1. $.param.querystring is not a function

这个错误会导致你无论怎么选择filter,都不会发送请求道cintroll去取数据,解决办法就是,无论在什么地方调用jquery,最好使用Yii的registe来注册,而不要使用<script>来引入.