zoukankan      html  css  js  c++  java
  • yii下多条件多表组合查询以及自写ajax分页

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

    前台表单

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

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

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

    Action代码

    这个表单会提交到如下的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('首页','&lt;&lt;'),
     5     'prev'=>array('上一页','&lt'),
     6     'next'=>array('下一页','&gt'),
     7     'end'=>array('末页','&gt;&gt;'),
     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 });

    效果

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

    视图代码

    在视图当中,有了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>
  • 相关阅读:
    【Azure】创建4层SLB运行网站
    【Azure】高可用方案
    【Azure】 微软云资源管理模式(Azure Resource Manager)
    JavaScript BOM
    JavaScript数组的属性和方法
    JavaScript parseFloat() 函数和parseInt()函数
    Javascript实现checkbox的全选
    设计一个含有一个表单的页面,并且在表单上放入一个文本框。编写程序,当鼠标在页面上移动时,鼠标的坐标将显示在这个文本框中。
    如何在页面完全加载后执行JS
    如何让脚本的执行顺序按照你设定的顺序执行
  • 原文地址:https://www.cnblogs.com/lvyahui/p/4622714.html
Copyright © 2011-2022 走看看