多条件组合查询主要用到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('首页','&lt;&lt;'),
'prev'=>array('上一页','&lt'),
'next'=>array('下一页','&gt'),
'end'=>array('末页','&gt;&gt;'),
);
?>
<?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>

yii下多条件多表组合查询以及自写ajax分页的更多相关文章

  1. mysql按月分表, 组合查询

    每个月月底最后一天建好下个月的空表 或每年底建1到12月的空表 , table_201901,table_201902,table_201903 增加记录不需要修改,insert到当月对应表就好了. ...

  2. Python操作Mysql数据库——多表组合查询

    前面我们介绍了单张表的查询,包括模糊查询.分组.排序.各种筛选条件等等操作,在实际应用中,查询的数据往往不止局限在一张表里,通常需要多张表在一起进行组合查询,今天我们将会对Mysql当中的多张有关联的 ...

  3. 多条件动态LINQ 组合查询

    本文章转载:http://www.cnblogs.com/wangiqngpei557/archive/2013/02/05/2893096.html 参考:http://dotnet.9sssd.c ...

  4. MySQL必知必会:组合查询(Union)

        MySQL必知必会:组合查询(Union) php mysqlsql  阅读约 8 分钟 本篇文章主要介绍使用Union操作符将多个SELECT查询组合成一个结果集.本文参考<Mysql ...

  5. Webform(分页、组合查询)

    一.分页 1.写查询方法: public List<Student> Select(int PageCount, int PageNumber) {//PageCount为每页显示条数,P ...

  6. JPA的多表复杂查询

    转 JPA的多表复杂查询:详细篇 原文链接: https://mp.weixin.qq.com/s/7J6ANppuiZJccIVN-h0T3Q 2017-11-10 从小爱喝AD钙  最近工作中由于 ...

  7. VB.NET版机房收费系统---组合查询

    查询的意思就是查找,寻找,指在某一个或几个地方找出自己所要的信息,假如我想搜索一下我自己写的博客,名字叫做初雪之恋,我在百度的搜索框中输入丁国华三个字,会有怎样的惊喜等着我? 啊哦,这个信息并不是我想 ...

  8. 【TP3.2】TP3.2下实现ajax分页(原创+亲测可用)

    一,写在最开始:ajax分页的原理,是利用了js的ajax执行请求,获取分页list和分页page [代码块],去替换页面显示数据的[代码块] 技术:js的ajax + TP3.2的fetch(&qu ...

  9. sql这两个表和查询的组合yii通过使用数据库查询

    sql两个表的组合查询  使用 join on 比如:两个表查询: select u.username, t.title from user u join task t on u.id = t.id; ...

随机推荐

  1. MySQL数据库设计复习笔记及项目实战

    最近手头上有3个项目开动,其他2个都是从底层开始的,一个已经开始了一段时间的了,在小城市小团队开发的条件下,都没有专门的DBA来做数据库的设计和维护,往往都是开发人员顶上,可是看了很多的数据库的设计, ...

  2. How do I use a host name to look up an IP address?

    The InetAddress class can be used to perform Domain Name Server (DNS) lookups. For example, you can ...

  3. Java多线程小结

    简述 Java是支持多线程编程的语言,线程相比于进程更加轻量级,线程共享相同的内存空间,但是拥有独立的栈.减少了进程建立.销毁的资源消耗.jdk1.5后对java的多线程编程提供了更完善的支持,使得j ...

  4. WPF DataGrid 合并单元格

    在网上搜索wpf合并单元格,一直没搜索到,没办法,只能自己想办法搞定了.其实就是DataGrid套DataGrid,为了方便支持Column拖动,在合并的DataGridColumn那一列的Heade ...

  5. MFC 一个类訪问还有一个类成员对象的成员变量值

    作者:卿笃军 原文地址:http://blog.csdn.net/qingdujun/article/details/35263857 MFC中一个类要訪问另外一个类的的对象的成员变量值,这就须要获得 ...

  6. (转载)SVN 提交操作缩写(A D M R) .

    前言: 今天使用SVN提交代码,发现提交后的代码找不到之前的版本. 操作的字母缩写为R.一般我们常见的操作为 A D M R   A:add,新增 C:conflict,冲突 D:delete,删除 ...

  7. 手动创建Servlet--J2EE学习笔记

    Java Servlet 是运行在 Web 服务器或应用服务器上的程序,它是作为来自 Web 浏览器或其他 HTTP 客户端的请求和 HTTP 服务器上的数据库或应用程序之间的中间层. 使用 Serv ...

  8. Java基础知识强化之集合框架笔记48:产生10个1~20之间的随机数(要求:随机数不能重复) 简洁版

    1. 编写一个程序,获取10个1至20的随机数,要求随机数不能重复. 分析:  A: 创建随机数对象  B: 创建一个HashSet集合  C: 判断集合的长度是不是小于10    是:就创建一个随机 ...

  9. Android(java)学习笔记179:BroadcastReceiver之 有序广播和无序广播(BroadcastReceiver优先级)

    之前我们在Android(java)学习笔记178中自定义的广播是无序广播,下面我们要了解一下有序广播:   1.   我们首先了解一下有序广播和无序广播区别和联系? (1) 有序广播> 接受者 ...

  10. PHP5常量

    用函数 define()设置常量 define函数有3个参数 1.必选,常量的名称,标识符 2.必选,常量的值 3.可选,默认不设置,常量名称大小写敏感.如果设置true,常量名称不区分大小写! 下面 ...