改變
原來的后臺只支持一個字段進行搜索,搜索名為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));
}
上一篇:菜單管理