您的位置:首页 > 编程语言 > PHP开发

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

2015-07-05 17:47 681 查看
多条件组合查询主要用到yii的CDbCriteria,这个类很多oem框架都有,非常好用。

前台表单

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





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



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

Action代码

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

<?php

class XXXController extends Controller
{
//...
public function actionAjaxSearch(){
//print_r($_POST);
$result = array(
'examItems'=>array(),
);
$c = new CDbCriteria;
$c->with = array('paper','course'); // 连接表

// 全局设置
$c->addCondition("course.type='program'");
$c->order = 't.create_time desc';
$keywords = FALSE;
if (isset($_POST['keywords']) AND ! empty($_POST['keywords']))
{
$keywords = preg_replace('/\s+/', '%', $_POST['keywords']);
$keywords = '%'.$keywords.'%';
$c->addSearchCondition('t.title', $keywords, FALSE);
}

$keyRegions = array();
if(isset($_POST['region'])){
$keyRegions = $_POST['region'];
}
if(!empty($keyRegions)){
//$regions = implode(',',$keyRegions);
$regions = "";
foreach($keyRegions as $r){
$regions .= "'".$r."',";
}
$regions = rtrim($regions,',');

$c->addCondition("paper.event_id in (select id from exam_events where type in (".$regions."))");
}

if (isset($_POST['course']))
{
$c->addInCondition('t.course_id', $_POST['course']);
}

// 判断类型条件
$keyTypes = array();
if(isset($_POST['type'])){
$tps = $_POST['type'];
foreach ($tps as $t)
{
$keyTypes[] = $t;
}
}
if(!empty($keyTypes)){
$c->addInCondition('t.type',$keyTypes);
}

$currentPage = isset($_GET['currentPage']) ? $_GET['currentPage'] : 1 ;
$eleItemCount = = ExamItems::model()->count($c);
$pages = PagingTools::getPages($eleItemCount,$currentPage,10,4);

$c->limit = $pages['limit'];
$c->offset = $pages['offset'];

$result['examItems'] = ExamItems::model()->findAll($c);
$this->renderPartial('result', array('result'=>$result,'pages'=>$pages,'keywords'=>$_POST['keywords']));

}
//...
}


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

分页工具

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

<?php
/**
* Created by PhpStorm.
* User: Administrator
* Date: 15-5-3
* Time: 上午9:24
*/

class PagingTools{
//    /**
//     * @var int 每个页面容纳项目数
//     */
//    public $pageEleItemCount;
//    /**
//     * @var int 最多显示多少页面按钮
//     */
//    public $pageMaxCount;
//    /**
//     * @var int 总的元素个数
//     */
//    public $eleItemCount;
//    /**
//     * @var int 当前页
//     */
//    public $currentPage = 1;

//    public function getPages(){
//
//        $pages = array(
//            /* 所求页面总数 */
//            'count'=>1,
//            /* 起始页面 */
//            'start'=>1,
//            /* 结束页面 */
//            'end'=>1,
//        );
//
//        if($this->eleItemCount > $this->pageEleItemCount){
//            //需要分页
//            $pages['count'] = intval($this->eleItemCount / $this->pageEleItemCount);
//            if($this->eleItemCount != $pages['count']*$this->pageEleItemCount) $pages['count']+=1;
//            if($pages['count'] > $this->pageMaxCount){//多于10页
//                $this->pageMaxCount -= 1;//数学问题3 到 6 的距离等于 6 - 3 + 1
//                //从中取10页,包含当前页
//                if($this->currentPage <= intval($this->pageMaxCount/2)){//很靠近首页
//                    $pages['start'] = 1;
//                }
//                else if($pages['count']-$this->currentPage < $this->pageMaxCount/2){//很靠近尾页
//                    $pages['start'] = $pages['count'] -  $this->pageMaxCount ;
//                }else{
//                    $pages['start'] = $this->currentPage - intval($this->pageMaxCount/2);
//                }
//                $pages['end'] = $this->pageMaxCount+$pages['start'] > $pages['count'] ? $pages['count'] : $this->pageMaxCount+$pages['start'];
//            }else{
//                $pages['start'] = 1;$pages['end'] = $pages['count'];
//            }
//        }
//
//        return $pages;
/**
* 获取分页参数
*
* @param int $eleItemCount 总的项目个数
* @param int $currentPage 当前页
* @param int $limit 每个页面容纳项目数
* @param int $pageMaxCount 最多显示多少页面按钮
* @return array
*/
public static function getPages($eleItemCount,$currentPage = 1,$limit = 10,$pageMaxCount = 7){
$pages = array(
/* 所求页面总数 */
'count' => 1,
/* 起始页面 */
'start' => 1,
/* 结束页面 */
'end' => 1 ,
/* 查询偏移 */
'offset' => 0 ,
/* 默认参数直接返回 */
'currentPage' => $currentPage,
'limit' =>  $limit,
'pageMaxCount' => $pageMaxCount,
);

if($eleItemCount > $limit){
//需要分页
$pages['count'] = intval($eleItemCount / $limit);
if($eleItemCount != $pages['count']*$limit) $pages['count']+=1;
if($pages['count'] > $pageMaxCount){//多于10页
$pageMaxCount -= 1;//数学问题3 到 6 的距离等于 6 - 3 + 1
//从中取10页,包含当前页
if($currentPage <= intval($pageMaxCount/2)){//很靠近首页
$pages['start'] = 1;
}
else if($pages['count']-$currentPage < $pageMaxCount/2){//很靠近尾页
$pages['start'] = $pages['count'] -  $pageMaxCount ;
}else{
$pages['start'] = $currentPage - intval($pageMaxCount/2);
}
$pages['end'] = $pageMaxCount+$pages['start'] > $pages['count'] ? $pages['count'] : $pageMaxCount+$pages['start'];
}else{
$pages['start'] = 1;$pages['end'] = $pages['count'];
}
$pages['offset'] = ($currentPage - 1 ) * $limit;
}
return $pages;
}

}


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

<?php
$isMobile = isset($isMobile) ? intval($isMobile) : 0;
$pagelinks = array(
'start'=>array('首页','<<'),
'prev'=>array('上一页','<'),
'next'=>array('下一页','>'),
'end'=>array('末页','>>'),
);
?>
<?php if($pages['count'] > 1):?>
<div class="paging-container">
<ul class="pagination">
<li class="page first <?=$pages['currentPage']==1 ? 'disabled' :''?>"><a href="javascript:void(0)"  data-page="1"><?=$pagelinks['start'][$isMobile]?></a></li>
<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>
<?php for($i=$pages['start'];$i<=$pages['end'] ;$i++):?>
<li class="page <?=$pages['currentPage'] == $i ? 'active' : ''?>"><a href="javascript:void(0)" data-page="<?=$i?>"><?=$i?></a></li>
<?php endfor;?>
<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>
<li class="page last <?=$pages['currentPage']==$pages['count'] ? 'disabled' :''?>"><a href="javascript:void(0)" data-page="<?=$pages['count']?>"><?=$pagelinks['end'][$isMobile]?></a></li>
</ul>
</div>
<?php endif;?>


最后为分页按钮增加事件

$(document).ready(function(){
$('.list-area').ajaxSuccess(function(){
var _this = $(this);
function toPage(v){
// 修改隐藏的input[name=currentPage]
// 异步提交表单
}
$('.paging-container .page a').click(function(){
var _this = $(this);
if(!(_this.parent('li').hasClass('disabled'))) {
toPage(_this.attr('data-page'));
}
});
});
});


效果

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









视图代码

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

<?php foreach ($result['examItems'] as $item) : ?>
<div class="row pt15 pb15 bb1-gray">
<div class="col-md-12 search-table" see-url="<?=$this->createUrl('examItems/ajaxViewItem')?>">
<div class="row">
<a href="javascript:void(0)" class="item-title" style="font-size: 15px;color: #6c6c6c">
<?=Tools::getShortTitle($item->title,80,true,$keywords,'code');?>
</a>
<div class="pull-right">
<a href="javascript:void(0)" class="see" data-id="<?=$item->id?>"><i class="fa fa-eye"></i><span>查看</span></a>
</div>
</div>
<div class="row itemCt" style="display: none;padding:8px"></div>
<div class="row">
<div class="col-md-12">
<div class="col-md-5 pull-left pt10">
<span class="col-md-3  mr10  badge badge-default"><?=$tps[$item->type]?></span>
<span class="col-md-3 badge badge-default"><?=isset($item->paper) ? isset($item->paper->event) ? $cgs[$item->paper->event->type] : '' : '' ;?></span>
</div>
<div class="pull-right mt5">
<?php if(isset($item->paper)):?>
<a data-auth href="<?=$this->createUrl('course/exam/'.$item->paper->id)?>" target="_blank" class="icon icon-clock text-blue ml15 text-gray">
<span><?=$item->paper->title?></span>
</a>
<?php endif;?>
</div>
</div>
</div>
</div>
</div>
<?php endforeach; ?>
<div class="list-paging text-center pb10">
<?php
$this->renderPartial('application.components.views.paging',array('pages'=>$pages,'isMobile'=>false));
?>
</div>
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: