转载

yii下多条件多表组合查询以及自写ajax分页

多条件组合查询主要用到yii的CDbCriteria,这个类很多oem框架都有,非常好用。

前台查询表单效果是这样的,多个条件组,每个组里放多个input,name为数组。当任何一个复选框被勾选上,发起ajax请求,当然,最顶层的复选框勾上时判断是否有子项,有的话把所有的子项勾选上。

yii下多条件多表组合查询以及自写ajax分页

yii下多条件多表组合查询以及自写ajax分页

但提交一次请求会向服务端post这样一个表单

yii下多条件多表组合查询以及自写ajax分页

其中currentPage是隐藏字段,当分页按钮被点击是这个字段的值会发生变化,并且发起查询请求。

这个表单会提交到如下的action中进行处理

 1 <?php  2   3 class XXXController extends Controller  4 {  5     //...  6      public function actionAjaxSearch(){  7         //print_r($_POST);  8         $result = array(  9             'examItems'=>array(), 10         ); 11         $c = new CDbCriteria; 12         $c->with = array('paper','course'); // 连接表 13  14         // 全局设置 15         $c->addCondition("course.type='program'"); 16         $c->order = 't.create_time desc'; 17         $keywords = FALSE; 18         if (isset($_POST['keywords']) AND ! empty($_POST['keywords'])) 19         { 20             $keywords = preg_replace('//s+/', '%', $_POST['keywords']); 21             $keywords = '%'.$keywords.'%'; 22             $c->addSearchCondition('t.title', $keywords, FALSE); 23         } 24  25         $keyRegions = array(); 26         if(isset($_POST['region'])){ 27             $keyRegions = $_POST['region']; 28         } 29         if(!empty($keyRegions)){ 30             //$regions = implode(',',$keyRegions); 31             $regions = ""; 32             foreach($keyRegions as $r){ 33                 $regions .= "'".$r."',"; 34             } 35             $regions = rtrim($regions,','); 36  37             $c->addCondition("paper.event_id in (select id from exam_events where type in (".$regions."))"); 38         } 39  40         if (isset($_POST['course'])) 41         { 42             $c->addInCondition('t.course_id', $_POST['course']); 43         } 44  45         // 判断类型条件 46         $keyTypes = array(); 47         if(isset($_POST['type'])){ 48             $tps = $_POST['type']; 49             foreach ($tps as $t) 50             { 51                 $keyTypes[] = $t; 52             } 53         } 54         if(!empty($keyTypes)){ 55             $c->addInCondition('t.type',$keyTypes); 56         } 57          58         $currentPage = isset($_GET['currentPage']) ? $_GET['currentPage'] : 1 ; 59         $eleItemCount = = ExamItems::model()->count($c); 60         $pages = PagingTools::getPages($eleItemCount,$currentPage,10,4); 61  62         $c->limit = $pages['limit']; 63         $c->offset = $pages['offset']; 64  65         $result['examItems'] = ExamItems::model()->findAll($c); 66         $this->renderPartial('result', array('result'=>$result,'pages'=>$pages,'keywords'=>$_POST['keywords'])); 67  68     } 69     //... 70 }

这里利用CDbCriteria对多条件进行组合,并在最后确定分页结果,传递到视图。

这里因为是ajax分页,当时我把yii的分页找了个遍发现都没有符合心意的分页工具。于是打算自己来写这个分页。

  1 <?php   2 /**   3  * Created by PhpStorm.   4  * User: Administrator   5  * Date: 15-5-3   6  * Time: 上午9:24   7  */   8    9 class PagingTools{  10 //    /**  11 //     * @var int 每个页面容纳项目数  12 //     */  13 //    public $pageEleItemCount;  14 //    /**  15 //     * @var int 最多显示多少页面按钮  16 //     */  17 //    public $pageMaxCount;  18 //    /**  19 //     * @var int 总的元素个数  20 //     */  21 //    public $eleItemCount;  22 //    /**  23 //     * @var int 当前页  24 //     */  25 //    public $currentPage = 1;  26   27 //    public function getPages(){  28 //  29 //        $pages = array(  30 //            /* 所求页面总数 */  31 //            'count'=>1,  32 //            /* 起始页面 */  33 //            'start'=>1,  34 //            /* 结束页面 */  35 //            'end'=>1,  36 //        );  37 //  38 //        if($this->eleItemCount > $this->pageEleItemCount){  39 //            //需要分页  40 //            $pages['count'] = intval($this->eleItemCount / $this->pageEleItemCount);  41 //            if($this->eleItemCount != $pages['count']*$this->pageEleItemCount) $pages['count']+=1;  42 //            if($pages['count'] > $this->pageMaxCount){//多于10页  43 //                $this->pageMaxCount -= 1;//数学问题3 到 6 的距离等于 6 - 3 + 1  44 //                //从中取10页,包含当前页  45 //                if($this->currentPage <= intval($this->pageMaxCount/2)){//很靠近首页  46 //                    $pages['start'] = 1;  47 //                }  48 //                else if($pages['count']-$this->currentPage < $this->pageMaxCount/2){//很靠近尾页  49 //                    $pages['start'] = $pages['count'] -  $this->pageMaxCount ;  50 //                }else{  51 //                    $pages['start'] = $this->currentPage - intval($this->pageMaxCount/2);  52 //                }  53 //                $pages['end'] = $this->pageMaxCount+$pages['start'] > $pages['count'] ? $pages['count'] : $this->pageMaxCount+$pages['start'];  54 //            }else{  55 //                $pages['start'] = 1;$pages['end'] = $pages['count'];  56 //            }  57 //        }  58 //  59 //        return $pages;  60     /**  61      * 获取分页参数  62      *  63      * @param int $eleItemCount 总的项目个数  64      * @param int $currentPage 当前页  65      * @param int $limit 每个页面容纳项目数  66      * @param int $pageMaxCount 最多显示多少页面按钮  67      * @return array  68      */  69     public static function getPages($eleItemCount,$currentPage = 1,$limit = 10,$pageMaxCount = 7){  70         $pages = array(  71             /* 所求页面总数 */  72             'count' => 1,  73             /* 起始页面 */  74             'start' => 1,  75             /* 结束页面 */  76             'end' => 1 ,  77             /* 查询偏移 */  78             'offset' => 0 ,  79             /* 默认参数直接返回 */  80             'currentPage' => $currentPage,  81             'limit' =>  $limit,  82             'pageMaxCount' => $pageMaxCount,  83         );  84   85         if($eleItemCount > $limit){  86             //需要分页  87             $pages['count'] = intval($eleItemCount / $limit);  88             if($eleItemCount != $pages['count']*$limit) $pages['count']+=1;  89             if($pages['count'] > $pageMaxCount){//多于10页  90                 $pageMaxCount -= 1;//数学问题3 到 6 的距离等于 6 - 3 + 1  91                 //从中取10页,包含当前页  92                 if($currentPage <= intval($pageMaxCount/2)){//很靠近首页  93                     $pages['start'] = 1;  94                 }  95                 else if($pages['count']-$currentPage < $pageMaxCount/2){//很靠近尾页  96                     $pages['start'] = $pages['count'] -  $pageMaxCount ;  97                 }else{  98                     $pages['start'] = $currentPage - intval($pageMaxCount/2);  99                 } 100                 $pages['end'] = $pageMaxCount+$pages['start'] > $pages['count'] ? $pages['count'] : $pageMaxCount+$pages['start']; 101             }else{ 102                 $pages['start'] = 1;$pages['end'] = $pages['count']; 103             } 104             $pages['offset'] = ($currentPage - 1 ) * $limit; 105         } 106         return $pages; 107     } 108  109 }

这里的视图放在与PageingTool相同目录的views目录下,

 1 <?php  2 $isMobile = isset($isMobile) ? intval($isMobile) : 0;  3 $pagelinks = array(  4     'start'=>array('首页','<<'),  5     'prev'=>array('上一页','<'),  6     'next'=>array('下一页','>'),  7     'end'=>array('末页','>>'),  8 );  9 ?> 10 <?php if($pages['count'] > 1):?> 11     <div class="paging-container"> 12         <ul class="pagination"> 13             <li class="page first <?=$pages['currentPage']==1 ? 'disabled' :''?>"><a href="javascript:void(0)"  data-page="1"><?=$pagelinks['start'][$isMobile]?></a></li> 14             <li class="page pprev <?=$pages['currentPage']==1 ? 'disabled' :''?>"><a href="javascript:void(0)" aria-label="Previous" data-page="<?=$pages['currentPage']-1?>"><?=$pagelinks['prev'][$isMobile]?></a></li> 15             <?php for($i=$pages['start'];$i<=$pages['end'] ;$i++):?> 16             <li class="page <?=$pages['currentPage'] == $i ? 'active' : ''?>"><a href="javascript:void(0)" data-page="<?=$i?>"><?=$i?></a></li> 17             <?php endfor;?> 18             <li class="page pnext <?=$pages['currentPage']==$pages['count'] ? 'disabled' :''?>"><a href="javascript:void(0)" aria-label="Next" data-page="<?=$pages['currentPage']+1?>"><?=$pagelinks['next'][$isMobile]?></a></li> 19             <li class="page last <?=$pages['currentPage']==$pages['count'] ? 'disabled' :''?>"><a href="javascript:void(0)" data-page="<?=$pages['count']?>"><?=$pagelinks['end'][$isMobile]?></a></li> 20         </ul> 21     </div> 22 <?php endif;?>

最后为分页按钮增加事件

 1 $(document).ready(function(){  2     $('.list-area').ajaxSuccess(function(){  3         var _this = $(this);  4         function toPage(v){  5             // 修改隐藏的input[name=currentPage]  6             // 异步提交表单  7         }  8         $('.paging-container .page a').click(function(){  9             var _this = $(this); 10             if(!(_this.parent('li').hasClass('disabled'))) { 11                 toPage(_this.attr('data-page')); 12             } 13         }); 14     }); 15 });

这个分页希望实现如下的效果,按钮数量有个上限,并尽量保证活动的按钮最好居中。效果如下。

yii下多条件多表组合查询以及自写ajax分页

yii下多条件多表组合查询以及自写ajax分页

yii下多条件多表组合查询以及自写ajax分页

yii下多条件多表组合查询以及自写ajax分页

在视图当中,有了result和pages之后,就可以迭代出结果和分页

 1 <?php foreach ($result['examItems'] as $item) : ?>  2     <div class="row pt15 pb15 bb1-gray">  3         <div class="col-md-12 search-table" see-url="<?=$this->createUrl('examItems/ajaxViewItem')?>">  4             <div class="row">  5                 <a href="javascript:void(0)" class="item-title" style="font-size: 15px;color: #6c6c6c">  6                     <?=Tools::getShortTitle($item->title,80,true,$keywords,'code');?>  7                 </a>  8                 <div class="pull-right">  9                     <a href="javascript:void(0)" class="see" data-id="<?=$item->id?>"><i class="fa fa-eye"></i><span>查看</span></a> 10                 </div> 11             </div> 12             <div class="row itemCt" style="display: none;padding:8px"></div> 13             <div class="row"> 14                 <div class="col-md-12"> 15                     <div class="col-md-5 pull-left pt10"> 16                         <span class="col-md-3  mr10  badge badge-default"><?=$tps[$item->type]?></span> 17                         <span class="col-md-3 badge badge-default"><?=isset($item->paper) ? isset($item->paper->event) ? $cgs[$item->paper->event->type] : '' : '' ;?></span> 18                     </div> 19                     <div class="pull-right mt5"> 20                         <?php if(isset($item->paper)):?> 21                             <a data-auth href="<?=$this->createUrl('course/exam/'.$item->paper->id)?>" target="_blank" class="icon icon-clock text-blue ml15 text-gray"> 22                                 <span><?=$item->paper->title?></span> 23                             </a> 24                         <?php endif;?> 25                     </div> 26                 </div> 27             </div> 28         </div> 29     </div> 30 <?php endforeach; ?> 31 <div class="list-paging text-center pb10"> 32     <?php 33         $this->renderPartial('application.components.views.paging',array('pages'=>$pages,'isMobile'=>false)); 34     ?> 35 </div>
正文到此结束
Loading...