改变
原来的后台只支持一个字段进行搜索,搜索名为keyword。
然后在ListBuilder类查询数据时
$map['a|b'] = [
$condition1,
$condition2,
];
这样去搜索多字段。
但是很多项目搜索条件很复杂。有的时候还会关联下拉选择。比如用户列表搜索某个等级的下拉。
为了方便大家在后台快速的添加搜索表单项。我扩展了它原来的模板,和ListBuilder类。
实现
首先 ListBuilder的显示是通过一个Common/Builder/Layout/Admin/list.html 来引入遍历模板和js的。
原内容:
<extend name="$_admin_public_layout"/>
<block name="style">
<link rel="stylesheet" type="text/css" href="__CUI__/css/cui.extend.min.css">
<include file="./Application/Common/Builder/style.html" />
</block>
<block name="main">
<include file="./Application/Common/Builder/listbuilder.html">
</block>
<block name="script">
<script type="text/javascript" src="__CUI__/js/cui.extend.min.js"></script>
<include file="./Application/Common/Builder/javascript.html" />
</block>
为了方便以后升级,我们保留原有的listbuilder.html。
我新增了一个listbuilderadv.html。
新内容:
<extend name="$_admin_public_layout"/>
<block name="style">
<link rel="stylesheet" type="text/css" href="__CUI__/css/cui.extend.min.css">
<include file="./Application/Common/Builder/style.html" />
</block>
<block name="main">
<include file="./Application/Common/Builder/listbuilderadv.html">
</block>
<block name="script">
<script type="text/javascript" src="__CUI__/js/cui.extend.min.js"></script>
<include file="./Application/Common/Builder/javascript.html" />
</block>
看一下listbuilderadv.html:
<div class="builder listbuilder-box panel-body">
<!-- Tab导航 -->
<notempty name="tab_nav">
<div class="builder-tabs">
<div class="row">
<div class="col-xs-12">
<ul class="nav nav-tabs">
<volist name="tab_nav.tab_list" id="tab">
<li class="<php>if($tab_nav['current_tab'] == $key) echo 'active';</php>"><a href="{$tab.href}">{$tab.title}</a></li>
</volist>
</ul>
</div>
</div>
</div>
<div class="form-group"></div>
</notempty>
<!-- 顶部工具栏按钮 -->
<if condition="($top_button_list || $search || $search_form_items)">
<div class="builder-toolbar">
<div class="row">
<!-- 工具栏按钮 -->
<empty name="top_button_list">
<div class="col-xs-12 col-sm-12 clearfix">
<include file="./Application/Common/Builder/search.html" />
</div>
<else />
<div class="col-xs-12 col-sm-3 button-list clearfix">
<div class="form-group">
<volist name="top_button_list" id="button">
<a {$button.attribute}>{$button.title}</a>
</volist>
</div>
</div>
<!-- 搜索框 -->
<if condition="($search || $search_form_items )">
<div class="col-xs-12 col-sm-9 clearfix">
<include file="./Application/Common/Builder/search.html" />
</div>
</if>
</empty>
</div>
</div>
</if>
<!-- 数据列表 -->
<div class="builder-container">
<div class="row">
<div class="col-xs-12">
<div class="builder-table">
<div class="panel panel-default table-responsive">
<table class="table table-bordered table-striped table-hover">
<thead>
<tr>
<th><input class="check-all" type="checkbox"></th>
<volist name="table_column_list" id="column">
<th>{$column.title|htmlspecialchars}</th>
</volist>
</tr>
</thead>
<tbody>
<empty name="table_data_list">
<tr class="builder-data-empty">
<php>$tdcolspan = count($table_column_list)+1</php>
<td class="text-center empty-info" colspan="{$tdcolspan}">
<i class="fa fa-database"></i> 暂时没有数据<br>
<span class="small">本系统由 <a href="{:C('WEBSITE_DOMAIN')}" class="text-muted" target="_blank">{:C('PRODUCT_NAME')}</a> v{:C('CURRENT_VERSION')} 强力驱动</span>
</td>
</tr>
<else />
<volist name="table_data_list" id="data">
<tr>
<td><input class="ids" type="checkbox" value="{$data[$table_data_list_key]}" name="ids[]"></td>
<volist name="table_column_list" id="column">
<td>{$data[$column['name']]}</td>
</volist>
</tr>
</volist>
</empty>
</tbody>
</table>
</div>
<notempty name="table_data_page">
<ul class="pagination">{$table_data_page}</ul>
</notempty>
</div>
</div>
</div>
</div>
<!-- 额外功能代码 -->
{$extra_html}
</div>
原来的listbuilder 有bug。必须有topButton 才能显示搜索。
<if condition="($top_button_list || $search || $search_form_items)">
我改成了 或。
然后为了能支持多个搜索表单项,我在ListBuilder中加了和FormBuilder类似的$_search_form_items 数组属性,
然后为了兼容旧的样式,将搜索表单区分为有顶部菜单的搜索和有顶部搜索的表单。
然后把搜索表单公共为一Common/Builder/search.html的文件。
在上面区分包含。
我们看一下search.html:
<form class="form form-inline" method="get" action="{$search_url}" name="seach" >
<empty name="search">
<style>
.form-inline .form-group{
margin-right: 12px;
margin-bottom: 15px;
}
.form-inline .btn{
margin-bottom: 15px;
}
</style>
<volist name="search_form_items" id="form" key="k">
<switch name="form.type">
<include file='Application/Common/Builder/FormType/hidden.html' type='' />
{// 不可修改文本 }
{// 字符串 }
<include file='Application/Common/Builder/SearchFormType/text.html' type='' />
{// 复选框 }
<include file='Application/Common/Builder/SearchFormType/checkbox.html' type='' />
{// 下拉框 }
<include file='Application/Common/Builder/SearchFormType/select.html' type='' />
{// 日期 }
<include file='Application/Common/Builder/SearchFormType/date.html' type='' />
{// 日期时间 }
<include file='Application/Common/Builder/SearchFormType/datetime.html' type='' />
{// 日期范围 }
<include file='Application/Common/Builder/SearchFormType/dateranger.html' type='' />
// 扩展类型
<default />
{:hook('FormBuilderExtend', array('form' => $form))}
</switch>
</volist>
<button type="submit" class="btn btn-default search-btn">搜索</button>
<else />
<div class="form-group">
<div class="input-group search-form">
<input type="text" name="keyword" class="search-input form-control" value="{$_GET.keyword}" placeholder="{$search.title}">
<span class="input-group-btn"><a class="btn btn-default search-btn"><i class="fa fa-search"></i></a></span>
</div>
</div>
</empty>
</form>
<script>
$(function(){
$(".search-btn").on('click',function(){
})
})
</script>
这里面其实就是参考了FormBuilder的遍历,然后只保留了大部分常用的搜索表单项:hidden、text、checkbox、select、date、datetime、dateranger(时间段范围选择器)。并为了和原有的FormType里文件区分作用保持同名,新增了一个SearchFormType目录存放相关文件。
然后主要是将bootstrap美化的表单改为行内表单,就是多个表单项在一行,不是一个表单项占一行。
加了form-inline类,并将一些表单的 <div class="right">包裹的div去除,不然仍有换行块。
最后是处理搜索按钮,必须加上search-btn类,去触发后台admin.js中的搜索事件。
不加的话,发现不论get 提交的form表单 action怎么写 都是提交到admin.php里。
这样搜索表单的显示就基本完成了。模板里会自动将get上的参数绑定表单项显示。如地址上?a=a, 那么搜索表单项name名为a的表单当搜索过时显示上次搜索的条件。
基本搜索表单的扩展已经实现了。
就是扩展ListBuilder显示相关模板。
使用
老项目参考xilutp项目的搜索相关提交:
搜索相关修改
日历插件的添加
将相关文件更新到项目中去。
新项目直接从xilutp中建立,开箱即用。
然后我用User模块下的Admin/的UserAdmin里的index列表做了示范:
注释原来的setSearch方法,添加搜索列,效果如下:
最后同原来的处理搜索条件方法一下,扩展自己的$map。
下拉和FormBuilder一样,可以传数组作为下拉项。
而且搜索表单的文本提示只用表单的tip显示,然后下拉的默认值,通过下拉数组的空值来显示,省去一个文本提示。如:
->addSearchItem('email_bind', 'select', '', '', ['' => '是否验证邮箱', '0' => '未验证', '1' => '已验证'])
如果没有空值的键名,默认为请选择,多个下拉就很难区分了。
这里主要讲一下日期范围搜索map的处理。
日期范围提交名为dates。是一个字符串。默认进来显示为空,表示列表搜索全部时间范围。让不为空时 取固定长度为2个日期区间值。
然后根据某一个字段的 egt 、elt。来做判断。
这部分代码比较常见,通常只有一个搜索项。然后我就在Admin/Controller/AdminController.class.php中封装了一个方法用于修改查询$map数组,将范围添加进去。
//扩展日期搜索map
public function extendDates(&$map, $field = 'update_time')
{
$dates = I('dates', '', 'trim');
if ($dates) {
$start_date = substr($dates, 0, 10);
$end_date = substr($dates, 11, 10);
$map[$field] = [
['egt', $start_date . ' 00:00:00'],
['lt', $end_date . ' 23:59:59'],
// ['exp', 'IS NOT NUll'],
];
}
// else {
// $start_date = datetime("-365 days", 'Y-m-d');
// $end_date = datetime('now', 'Y-m-d');
// }
}
传当前列表查询的$map 和比较的日期范围字段$field。
目前只实现了日期类型字段搜索,int类型的需要再加参数修改。
我们看一下UserAdmin里的index列表:
$map['id|username|nickname|email|mobile'] = array(
$condition,
$condition,
$condition,
$condition,
$condition,
'_multi' => true,
);
$email_bind = I('email_bind', '');
if ($email_bind) {
$map['email_bind'] = (int) $email_bind;
}
注意处理默认空时不加到map里搜索。
结尾
新加没多就的功能,如有bug 请原谅。
忘了说了,ListSearch里还有搜索表单action的修改:
if ($this->_search && $this->_search['url']) {
$this->assign('search_url', $this->_search['url']);
} else {
$this->assign('search_url', U(ACTION_NAME, '', false, true));
}
上一篇:菜单管理