!59 增加功能:重新设计搜索区域 UI

Merge pull request !59 from Argo/dev
This commit is contained in:
Argo 2020-01-18 12:25:10 +08:00 committed by Gitee
commit c972da88f5
16 changed files with 275 additions and 71 deletions

View File

@ -1,6 +1,7 @@
using Bootstrap.DataAccess;
using Bootstrap.Security;
using Longbow.Web.Mvc;
using System;
using System.Linq;
namespace Bootstrap.Admin.Query
@ -37,15 +38,19 @@ namespace Bootstrap.Admin.Query
var data = DictHelper.RetrieveDicts();
if (!string.IsNullOrEmpty(Category))
{
data = data.Where(t => t.Category?.Contains(Category) ?? false);
data = data.Where(t => t.Category.Contains(Category, StringComparison.OrdinalIgnoreCase));
}
if (!string.IsNullOrEmpty(Name))
{
data = data.Where(t => t.Name?.Contains(Name) ?? false);
data = data.Where(t => t.Name.Contains(Name, StringComparison.OrdinalIgnoreCase));
}
if (!string.IsNullOrEmpty(Define))
{
data = data.Where(t => t.Define.ToString() == (Define ?? ""));
data = data.Where(t => t.Define.ToString() == Define);
}
if (!string.IsNullOrEmpty(Search))
{
data = data.Where(t => t.Category.Contains(Search, StringComparison.OrdinalIgnoreCase) || t.Name.Contains(Search, StringComparison.OrdinalIgnoreCase) || t.Code.Contains(Search, StringComparison.OrdinalIgnoreCase));
}
var ret = new QueryData<BootstrapDict>();
ret.total = data.Count();

View File

@ -1,5 +1,6 @@
using Bootstrap.DataAccess;
using Longbow.Web.Mvc;
using System;
using System.Linq;
namespace Bootstrap.Admin.Query
@ -29,11 +30,15 @@ namespace Bootstrap.Admin.Query
var data = GroupHelper.Retrieves();
if (!string.IsNullOrEmpty(GroupName))
{
data = data.Where(t => t.GroupName?.Contains(GroupName) ?? false);
data = data.Where(t => t.GroupName.Contains(GroupName, StringComparison.OrdinalIgnoreCase));
}
if (!string.IsNullOrEmpty(Description))
{
data = data.Where(t => t.Description?.Contains(Description) ?? false);
data = data.Where(t => t.Description?.Contains(Description, StringComparison.OrdinalIgnoreCase) ?? false);
}
if (!string.IsNullOrEmpty(Search))
{
data = data.Where(t => t.GroupName.Contains(Search, StringComparison.OrdinalIgnoreCase) || (t.Description?.Contains(Search, StringComparison.OrdinalIgnoreCase) ?? false));
}
var ret = new QueryData<object>();
ret.total = data.Count();

View File

@ -6,37 +6,37 @@ using System.Linq;
namespace Bootstrap.Admin.Query
{
/// <summary>
///
///
/// </summary>
public class QueryMenuOption : PaginationOption
{
/// <summary>
///
///
/// </summary>
public string? Name { get; set; }
/// <summary>
///
///
/// </summary>
public string? ParentName { get; set; }
/// <summary>
///
///
/// </summary>
public string? Category { get; set; }
/// <summary>
///
///
/// </summary>
public string? IsResource { get; set; }
/// <summary>
///
///
/// </summary>
public string? AppId { get; set; }
/// <summary>
///
///
/// </summary>
/// <param name="userName"></param>
/// <returns></returns>
@ -45,15 +45,15 @@ namespace Bootstrap.Admin.Query
var data = MenuHelper.RetrieveMenusByUserName(userName);
if (!string.IsNullOrEmpty(ParentName))
{
data = data.Where(t => t.Name.Contains(ParentName) || (t.ParentName != null && t.ParentName.Contains(ParentName)));
data = data.Where(t => t.Name.Contains(ParentName, StringComparison.OrdinalIgnoreCase) || (t.ParentName != null && t.ParentName.Contains(ParentName, StringComparison.OrdinalIgnoreCase)));
}
if (!string.IsNullOrEmpty(Name))
{
data = data.Where(t => t.Name.Contains(Name));
data = data.Where(t => t.Name.Contains(Name, StringComparison.OrdinalIgnoreCase));
}
if (!string.IsNullOrEmpty(Category))
{
data = data.Where(t => t.Category.Contains(Category));
data = data.Where(t => t.Category.Contains(Category, StringComparison.OrdinalIgnoreCase));
}
if (!string.IsNullOrEmpty(IsResource))
{
@ -63,6 +63,10 @@ namespace Bootstrap.Admin.Query
{
data = data.Where(t => t.Application.Equals(AppId, StringComparison.OrdinalIgnoreCase));
}
if (!string.IsNullOrEmpty(Search))
{
data = data.Where(t => t.Name.Contains(Search, StringComparison.OrdinalIgnoreCase) || t.ParentName.Contains(Search, StringComparison.OrdinalIgnoreCase));
}
var ret = new QueryData<object>();
ret.total = data.Count();
switch (Sort)

View File

@ -1,5 +1,6 @@
using Bootstrap.DataAccess;
using Longbow.Web.Mvc;
using System;
using System.Linq;
namespace Bootstrap.Admin.Query
@ -29,11 +30,15 @@ namespace Bootstrap.Admin.Query
var data = RoleHelper.Retrieves();
if (!string.IsNullOrEmpty(RoleName))
{
data = data.Where(t => t.RoleName.Contains(RoleName));
data = data.Where(t => t.RoleName.Contains(RoleName, StringComparison.OrdinalIgnoreCase));
}
if (!string.IsNullOrEmpty(Description))
{
data = data.Where(t => t.Description.Contains(Description));
data = data.Where(t => t.Description.Contains(Description, StringComparison.OrdinalIgnoreCase));
}
if (!string.IsNullOrEmpty(Search))
{
data = data.Where(t => t.RoleName.Contains(Search, StringComparison.OrdinalIgnoreCase) || t.Description.Contains(Search, StringComparison.OrdinalIgnoreCase));
}
var ret = new QueryData<object>();
ret.total = data.Count();

View File

@ -1,5 +1,6 @@
using Bootstrap.DataAccess;
using Longbow.Web.Mvc;
using System;
using System.Linq;
namespace Bootstrap.Admin.Query
@ -29,11 +30,15 @@ namespace Bootstrap.Admin.Query
var data = UserHelper.Retrieves();
if (!string.IsNullOrEmpty(Name))
{
data = data.Where(t => t.UserName.Contains(Name));
data = data.Where(t => t.UserName.Contains(Name, StringComparison.OrdinalIgnoreCase));
}
if (!string.IsNullOrEmpty(DisplayName))
{
data = data.Where(t => t.DisplayName.Contains(DisplayName));
data = data.Where(t => t.DisplayName.Contains(DisplayName, StringComparison.OrdinalIgnoreCase));
}
if (!string.IsNullOrEmpty(Search))
{
data = data.Where(t => t.DisplayName.Contains(Search, StringComparison.OrdinalIgnoreCase) || t.Description.Contains(Search, StringComparison.OrdinalIgnoreCase) || t.UserName.Contains(Search, StringComparison.OrdinalIgnoreCase));
}
var ret = new QueryData<object>();
ret.total = data.Count();

View File

@ -19,26 +19,23 @@
@section query {
<form class="form-inline">
<div class="row">
<div class="form-group col-sm-6 col-md-auto">
<div class="form-group col-12">
<label class="control-label" for="txt_dict_cate">字典标签</label>
<input type="text" class="form-control" id="txt_dict_cate" data-provide="typeahead" />
<input type="text" class="form-control" id="txt_dict_cate" data-provide="typeahead" data-default-val="" />
</div>
<div class="form-group col-sm-6 col-md-auto">
<div class="form-group col-12">
<label class="control-label" for="txt_dict_name">字典名称</label>
<input type="text" class="form-control" id="txt_dict_name" />
<input type="text" class="form-control" id="txt_dict_name" data-default-val="" />
</div>
<div class="form-group col-sm-6 col-md-auto">
<div class="form-group col-12">
<label class="control-label" for="txt_dict_define">字典类型</label>
<input class="form-control" data-toggle="lgbSelect" />
<input class="form-control" data-toggle="lgbSelect" data-default-val="" />
<select data-toggle="lgbSelect" class="d-none" id="txt_dict_define">
<option value="">全部</option>
<option value="0">系统使用</option>
<option value="1">自定义</option>
</select>
</div>
<div class="form-group col-sm-6 col-md-auto flex-sm-fill justify-content-sm-end align-self-sm-end">
<button type="button" id="btn_query" class="btn btn-primary btn-fill"><i class="fa fa-search" aria-hidden="true"></i><span>查询</span></button>
</div>
</div>
</form>
}

View File

@ -9,16 +9,13 @@
@section query {
<form class="form-inline">
<div class="row">
<div class="form-group col-sm-auto">
<div class="form-group col-12">
<label class="control-label" for="txt_search_name">部门名称</label>
<input type="text" class="form-control" id="txt_search_name" />
<input type="text" class="form-control" id="txt_search_name" data-default-val="" />
</div>
<div class="form-group col-sm-auto">
<div class="form-group col-12">
<label class="control-label" for="txt_group_desc">部门描述</label>
<input type="text" class="form-control" id="txt_group_desc" />
</div>
<div class="form-group col-sm-auto flex-sm-fill justify-content-sm-end align-self-sm-end">
<button type="button" id="btn_query" class="btn btn-primary btn-fill"><i class="fa fa-search" aria-hidden="true"></i><span>查询</span></button>
<input type="text" class="form-control" id="txt_group_desc" data-default-val="" />
</div>
</div>
</form>

View File

@ -33,26 +33,26 @@
@section query {
<form class="form-inline">
<div class="row">
<div class="form-group col-sm-6 col-lg-auto">
<div class="form-group col-12">
<label class="control-label" for="txt_menus_name">菜单名称</label>
<input type="text" class="form-control" id="txt_menus_name" />
<input type="text" class="form-control" id="txt_menus_name" data-default-val="" />
</div>
<div class="form-group col-sm-6 col-lg-auto">
<div class="form-group col-12">
<label class="control-label" for="txt_parent_menus_name">父级菜单</label>
<input type="text" class="form-control" id="txt_parent_menus_name" />
<input type="text" class="form-control" id="txt_parent_menus_name" data-default-val="" />
</div>
<div class="form-group col-sm-6 col-lg-auto">
<div class="form-group col-12">
<label class="control-label" for="sel_menus_category">菜单类别</label>
<input class="form-control" data-toggle="lgbSelect" />
<input class="form-control" data-toggle="lgbSelect" data-default-val="" />
<select data-toggle="lgbSelect" class="d-none" id="sel_menus_category">
<option value="">全部</option>
<option value="0">系统菜单</option>
<option value="1">外部菜单</option>
</select>
</div>
<div class="form-group col-sm-6 col-lg-auto">
<div class="form-group col-12">
<label class="control-label" for="sel_menus_res">菜单类型</label>
<input class="form-control" data-toggle="lgbSelect" />
<input class="form-control" data-toggle="lgbSelect" data-default-val="" />
<select data-toggle="lgbSelect" class="d-none" id="sel_menus_res">
<option value="">全部</option>
<option value="0">菜单</option>
@ -60,9 +60,9 @@
<option value="2">按钮</option>
</select>
</div>
<div class="form-group col-sm-6 col-lg-auto">
<div class="form-group col-12">
<label class="control-label" for="sel_app">所属应用</label>
<input class="form-control" data-toggle="lgbSelect" />
<input class="form-control" data-toggle="lgbSelect" data-default-val="" />
<select data-toggle="lgbSelect" class="d-none" id="sel_app">
<option value="">全部</option>
@foreach (var kv in Model.Applications)
@ -71,9 +71,6 @@
}
</select>
</div>
<div class="form-group col-sm-6 col-lg-auto flex-sm-fill justify-content-sm-end align-self-sm-end">
<button type="button" id="btn_query" class="btn btn-primary btn-fill"><i class="fa fa-search" aria-hidden="true"></i><span>查询</span></button>
</div>
</div>
</form>
}

View File

@ -24,16 +24,13 @@
@section query {
<form class="form-inline">
<div class="row">
<div class="form-group col-sm-auto">
<div class="form-group col-12">
<label class="control-label" for="txt_search_name">角色名称</label>
<input type="text" class="form-control" id="txt_search_name" />
<input type="text" class="form-control" id="txt_search_name" data-default-val="" />
</div>
<div class="form-group col-sm-auto">
<div class="form-group col-12">
<label class="control-label" for="txt_role_desc">角色描述</label>
<input type="text" class="form-control" id="txt_role_desc" />
</div>
<div class="form-group col-sm-auto flex-sm-fill justify-content-sm-end align-self-sm-end">
<button type="button" id="btn_query" class="btn btn-primary btn-fill"><i class="fa fa-search" aria-hidden="true"></i><span>查询</span></button>
<input type="text" class="form-control" id="txt_role_desc" data-default-val="" />
</div>
</div>
</form>

View File

@ -9,16 +9,13 @@
@section query {
<form class="form-inline">
<div class="row">
<div class="form-group col-sm-auto">
<div class="form-group col-12">
<label class="control-label" for="txt_search_name">登录名称</label>
<input type="text" class="form-control" id="txt_search_name" maxlength="16" />
<input type="text" class="form-control" id="txt_search_name" maxlength="16" data-default-val="" />
</div>
<div class="form-group col-sm-auto">
<div class="form-group col-12">
<label class="control-label" for="txt_display_name">显示名称</label>
<input type="text" class="form-control" id="txt_display_name" maxlength="20" />
</div>
<div class="form-group col-sm-auto flex-sm-fill justify-content-sm-end align-self-sm-end">
<button type="button" id="btn_query" class="btn btn-primary btn-fill"><i class="fa fa-search" aria-hidden="true"></i><span>查询</span></button>
<input type="text" class="form-control" id="txt_display_name" maxlength="20" data-default-val="" />
</div>
</div>
</form>

View File

@ -52,14 +52,25 @@
</div>
</div>
</div>
<div class="modal fade" id="dialogAdvancedSearch" tabindex="-1" role="dialog" data-backdrop="static" aria-labelledby="mySearchModalLabel" aria-hidden="true">
<div class="modal-dialog modal-dialog-centered" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="mySearchModalLabel">查询条件</h5>
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button>
</div>
<div class="modal-body modal-query">
@RenderSection("query", false)
</div>
<div class="modal-footer">
<button type="button" id="btn_reset" class="btn btn-info btn-fill"><i class="fa fa-trash-o" aria-hidden="true"></i><span>重置</span></button>
<button type="button" id="btn_query" class="btn btn-primary btn-fill"><i class="fa fa-search" aria-hidden="true"></i><span>查询</span></button>
</div>
</div>
</div>
</div>
@RenderSection("customModal", false)
}
<div class="card">
<div class="card-header">查询条件</div>
<div class="card-body">
@RenderSection("query", false)
</div>
</div>
<div id="toolbar" class="d-none">
<div class="gear btn-group">
<button class="btn btn-secondary dropdown-toggle" data-toggle="dropdown" type="button"><i class="fa fa-gear"></i></button>
@ -93,4 +104,4 @@
@RenderSection("tableButtons", false)
</div>
</div>
@await RenderSectionAsync("body", false)
@await RenderSectionAsync("body", false)

View File

@ -531,3 +531,7 @@ pre {
outline: none;
color: #371ed4;
}
.modal-query .form-group input.form-control {
flex: 1 1 auto;
}

View File

@ -130,6 +130,12 @@
}
}
@media (min-width: 1120px) {
.bootstrap-table .fixed-table-toolbar .columns button i + span, .bootstrap-table .fixed-table-toolbar .search button i + span {
display: inline-block;
}
}
@media (min-width: 1200px) {
.modal-xl {
max-width: 1100px;

View File

@ -774,6 +774,10 @@ input.pending {
padding: 6px 20px;
}
.bootstrap-table .fixed-table-toolbar .columns button i + span, .bootstrap-table .fixed-table-toolbar .search button i + span {
display: none;
}
.fixed-table-toolbar .dropdown-menu {
min-width: unset;
}

View File

@ -353,6 +353,14 @@
pageList: [20, 40, 80, 120], //可供选择的每页的行数(*
showExport: true,
exportTypes: ['csv', 'txt', 'excel'],
advancedSearchModal: '#dialogAdvancedSearch',
search: true,
searchOnEnterKey: false,
searchTimeOut: 0,
showSearchClearButton: true,
showAdvancedSearchButton: true,
showButtonText: true,
showSearchButton: true, //是否显示搜索按钮
showColumns: true, //是否显示所有的列
showRefresh: true, //是否显示刷新按钮
showToggle: true, //是否显示详细视图和列表视图的切换按钮
@ -383,6 +391,35 @@
}
}
});
if (settings.search) {
// 自动收集 SearchText
var queryParams = settings.queryParams;
settings.queryParams = function (params) {
return $.extend({}, queryParams(params), { search: $('.bootstrap-table .fixed-table-toolbar .search-input').val() });
}
// 支持键盘回车搜索
$(document).on('keyup', '.bootstrap-table .fixed-table-toolbar .search-input', this, function (event) {
if (event.keyCode === 13) {
// ENTER
var $buttons = $(this).next();
var $search = $buttons.find('[name="search"]');
if ($search.length === 1) {
$search.trigger('click');
}
else {
// 无搜索按钮是使用 refresh 方法
event.data.bootstrapTable('refresh');
}
}
else if (event.keyCode === 27) {
// ESC
event.data.bootstrapTable('resetSearch');
}
});
}
this.bootstrapTable(settings);
$('.bootstrap-table .fixed-table-toolbar .columns .export .dropdown-menu').addClass("dropdown-menu-right");
var $gear = $(settings.toolbar).removeClass('d-none').find('.gear');
@ -396,6 +433,52 @@
e.data.bootstrapTable('refresh');
});
}
// 增加 Tooltip
if (settings.search) {
$('.bootstrap-table .fixed-table-toolbar .search-input').tooltip({
sanitize: false,
title: "输入任意字符串全局搜索 </br> Enter 搜索 ESC 清除搜索",
html: true
});
}
// 生成高级查询按钮
if (settings.showAdvancedSearchButton) {
// template
var $advancedSearchButtonHtml = $('<button class="btn btn-secondary" type="button" name="advancedSearch" title="高级搜索"><i class="fa fa-search-plus"></i><span>高级搜索</span></button>');
$advancedSearchButtonHtml.insertAfter($('.bootstrap-table .fixed-table-toolbar .search [name="clearSearch"]')).on('click', function () {
// 弹出高级查询对话框
$(settings.advancedSearchModal).modal('show');
});
// 高级搜索有值时颜色为红色
$(settings.advancedSearchModal).on('hide.bs.modal', function () {
var $modal = $(this)
var hasValue = false;
$modal.find('[data-default-val]').each(function (index, element) {
var $ele = $(element);
var val = $ele.attr('data-default-val');
if ($ele.prop('nodeName') === 'INPUT') {
if ($ele.hasClass('form-select-input')) {
hasValue = $ele.prev().val() !== val;
}
else {
hasValue = $ele.val() !== val;
}
}
if (hasValue) return false;
});
if (hasValue) $advancedSearchButtonHtml.removeClass('btn-secondary').addClass('btn-primary');
else $advancedSearchButtonHtml.removeClass('btn-primary').addClass('btn-secondary');
});
}
// fix bug 移除 Toolbar 按钮 Title 中的 Html
$('.bootstrap-table .fixed-table-toolbar button[title]').each(function (index, element) {
element.title = element.title.replace('<span>', '').replace('</span>', '');
});
return this;
},
lgbPopover: function (options) {
@ -526,6 +609,68 @@
$.extend($.fn.bootstrapTable.defaults.icons, {
refresh: 'fa-refresh'
});
// fix bug bootstrap-table showButtonText support mobile
// argo at 2020-01-18
$.extend($.fn.bootstrapTable.defaults, {
formatClearSearch: function formatClearSearch() {
return '<span>清空过滤</span>';
},
formatSearch: function formatSearch() {
return '搜索';
},
formatNoMatches: function formatNoMatches() {
return '<span>没有找到匹配的记录</span>';
},
formatPaginationSwitch: function formatPaginationSwitch() {
return '<span>隐藏/显示分页</span>';
},
formatPaginationSwitchDown: function formatPaginationSwitchDown() {
return '<span>显示分页</span>';
},
formatPaginationSwitchUp: function formatPaginationSwitchUp() {
return '<span>隐藏分页</span>';
},
formatRefresh: function formatRefresh() {
return '<span>查询</span>';
},
formatToggle: function formatToggle() {
return '<span>切换</span>';
},
formatToggleOn: function formatToggleOn() {
return '<span>显示卡片视图</span>';
},
formatToggleOff: function formatToggleOff() {
return '<span>隐藏卡片视图</span>';
},
formatColumns: function formatColumns() {
return '<span>列</span>';
},
formatColumnsToggleAll: function formatColumnsToggleAll() {
return '<span>切换所有</span>';
},
formatFullscreen: function formatFullscreen() {
return '<span>全屏</span>';
},
formatAllRows: function formatAllRows() {
return '<span>所有</span>';
},
formatAutoRefresh: function formatAutoRefresh() {
return '<span>自动刷新</span>';
},
formatExport: function formatExport() {
return '<span>导出数据</span>';
},
formatJumpTo: function formatJumpTo() {
return '<span>跳转</span>';
},
formatAdvancedSearch: function formatAdvancedSearch() {
return '<span>高级搜索</span>';
},
formatAdvancedCloseButton: function formatAdvancedCloseButton() {
return '<span>关闭</span>';
}
});
}
// extend bootstrap-toggle
@ -540,7 +685,7 @@
$(this).trigger('click.bs.toggle');
e.preventDefault();
});
}
};
}
if (window.NProgress) {

View File

@ -123,9 +123,34 @@
modal: '#dialogNew',
click: {
'#btn_query': function (element) {
if (this.options.bootstrapTable !== null) this.options.bootstrapTable.bootstrapTable('refresh');
if (this.options.bootstrapTable !== null) {
var options = this.options.bootstrapTable.bootstrapTable('getOptions');
if (options.advancedSearchModal) {
$(options.advancedSearchModal).modal('hide');
}
this.options.bootstrapTable.bootstrapTable('refresh');
}
handlerCallback.call(this, null, element, { oper: 'query' });
},
'#btn_reset': function () {
if (this.options.bootstrapTable !== null) {
var options = this.options.bootstrapTable.bootstrapTable('getOptions');
if (options.advancedSearchModal) {
$(options.advancedSearchModal).find('[data-default-val]').each(function (index, element) {
var $ele = $(element);
var val = $ele.attr('data-default-val');
if ($ele.prop('nodeName') === 'INPUT') {
if ($ele.hasClass('form-select-input')) {
$ele.prev().lgbSelect('val', val);
}
else {
$ele.val(val);
}
}
});
}
}
},
'#btn_add': function (element) {
this.dataEntity.reset();
if (this.options.modal.constructor === String) $(this.options.modal).modal("show");