多条件组合查询主要用到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. IOS开发之内存管理--dealloc该写些什么

    在非ARC开发环境中,dealloc是类释放前,清理内存的最后机会.到底那些变量和属性该释放呢,一些特殊的类(nstimer,observer)该怎么释放.需要注意的是不释放会引起内存泄露,过度释放也 ...

  2. AX2012服务器配置--Windows Server 2012 如何实现多个用户远程桌面登陆?

    Windows Server 2012 如何实现多个用户远程桌面登陆?说明:Windows Server 2012默认情况下,只运行2个用户远程桌面登陆,这里我们可以通过安装远程桌面会话主机配置来实现 ...

  3. GC overhead limit exceeded解决

    java.lang.OutOfMemoryError: GC overhead limit exceeded解决   一.异常如下:Exception in thread "main&quo ...

  4. [TypeScript] Using Lodash in TypeScript with Typings and SystemJS

    One of the most confusing parts of getting started with TypeScript is figuring out how to use all th ...

  5. mysql中enum的用法

    字段 类型 长度/值*1 整理 属性 Null 默认2 额外 注释 enum         说明:enum类型的字段,若长度值写长度1/2,报错 (1)  数据长度为1,则为0,1,2… (2)   ...

  6. SOA体系结构之基础培训教程-大纲篇

    引言: 最近受邀做了一个企业的SOA体系结构的内训,本文是内训课程的培训大纲,分享一下吧,希望大家能够喜欢.同时也想针对大纲中列出的内容对SOA架构体系做一次回顾,如果时间允许把完整的课件也想放上来共 ...

  7. 用NodeJs实现延迟调用,规避定时任务的闭包问题

    很多人在用NodeJs的setTimeout(callback, delay[, arg][, ...])编写定时任务时,习惯上直接操作callback外部的对象object(闭包的特点).这样做有一 ...

  8. python学习笔记--Django入门二 Django 的模板系统

    为了使网站更干净简洁更容易维护,页面的设计和Python的代码必须分离开.我们可以使用Django的 模板系统 (Template System)来实现这种模式. 几个简单的模板标签(tag):   ...

  9. Android 开发之动画详解

    一.动画类型 Android的animation由四种类型组成:alpha.scale.translate.rotate XML配置文件中 alpha 渐变透明度动画效果 scale 渐变尺寸伸缩动画 ...

  10. ZeroClipboard.swf

    ZeroClipboard.config({             moviePath: "source/ZeroClipboard.swf",             hove ...