里提供4种搜索类型(字符、数值、日期、多选值),每种搜索提供相应的输入选项:
字符类型:提供包含、等于、开头、结尾搜索选项。
数值类型:提供 =、>=、<、<=搜索选项。
日期类型:提供开始、结束搜索选项。
多选值:提供值的多选方式。
下面来实现搜索功能,首先是为列头绑定事件,这里需要找出那些可用于搜索的列头,前面已经提到过搜索支持的4种类型,在搜索中需要为这些列头设置相应的属性,这里自定义queryType属性,比如:
先不用关注上面使用的Lable服务器控件,这里暂时先只作为查询支撑控件。 接下来可以找出所有标有queryType属性的标签,这些标签的父控件即为可用于搜索的列头,为其绑定鼠标单击事件:
tableObj.find('[queryType]').each(function(n){ labelObj[n] = $(this); parentObj = labelObj[n].parent(); parentObj.bind('click', function(){ getSearchArea(labelObj[n]); }); }); //获取搜索区域 function getSearchArea(o){ }
getSearchArea方法里面,我们需要先创建搜索区域(一段标准HTML代码),设置其样式可浮动、绝对定位,创建后附加到页面中,并以列头作为参照物获取坐标并显示:
function setPosition(params){ //获取列头坐标 var tdObj = params.label.parent(); var left = tdObj.position().left + 5; var top = tdObj.position().top + 20; if(left + 200 > SCREEN_WIDTH){ left = SCREEN_WIDTH - 200; } //设置搜索区域坐标 searchMap.Item(params.containerId).Item('main').css({ left: left, top: top}); searchMap.Item(params.containerId).Item('main').show(); }
上面方法中的searchMap.Item(params.containerId).Item('main')为创建好的搜索主区域,先不关注它,后面再介绍。 然后获取所有搜索对象:升序、降序、清除、确定、取消,分别为其绑定相应的事件方法。 这样,搜索区域已经被创建好,点击列表头时将显示于表头下方,在本篇中,创建的搜索区域已经包含了所有搜索方式的4种输入框,并且为其定义唯一的编号,后面的操作只是根据搜索类型来显示或隐藏,大家可参照源文件进行对比,这里不进行描述。
接下来要思考的是如何获取搜索结果,从上面信息来看,每一次搜索都涉及到下面几个关键信息: 搜索字段、搜索类型、搜索条件、搜索内容。 因此,我们至少需要将这些关键信息传递给分页控件,最常用的方法的是将每类信息作为一个参数通过URL传参方式传递给分页控件,但这种方式会造成参数数量增多,而且扩展不灵活。 这里用另一种方式实现,我们定义一种数据协议,将获取到的每类信息按照“类型-值”的方式进行组合,最后将每一列的搜索结果作为一个整体,样式如下: columnName┝COLON┥VAL┝SEPARATOR┥ queryType┝COLON┥text┝SEPARATOR┥ condition┝COLON┥contain┝SEPARATOR┥ value┝COLON┥10┝SEPARATOR┥ ┝END┥ 这里以┝END┥作为多列的分隔符,┝SEPARATOR┥作为每种信息的分隔符,┝COLON┥作为各具体信息描述及结果的分隔符。 格式定义好了,可以以此为目标进行搜索实现,每一次搜索的结果都需要进行保存,用于下一次搜索的条件叠加。 这里用一个字典来保存搜索结果:
var searchResult = new Map(); //搜索结果,格式为:字段、搜索信息集合(顺序为:搜索类型、搜索条件、值)
前面提到过获取搜索主区域:searchMap.Item(params.containerId).Item('main')的方法,这是另一个字典对象,保存类搜索信息区域,控制显示及隐藏,定义为:
var searchMap = new Map(); //页面控件对象,格式为:各列唯一编号、对象类型、对象
在每一次搜索完成时,根据获取到的列、类型、搜索结果,组合成前面定义的数据格式,提交给后台进行处理,并保存至searchResult中,下面是一些以文本搜索方式例的关键代码:
//确定按钮点击事件 function okButtonClick(params){ searchByText(params); getSearchResult(params); //提交搜索条件 pagerObj.Page(1); searchMap.Item(params.containerId).Item('main').hide(); } //获取文本搜索内容 function searchByText(params){ if(params.queryType != 'text'){ return; } createSearchResult(params); searchResult.Item(params.columnName)[0] = params.queryType; //搜索类型 searchResult.Item(params.columnName)[1] = searchMap.Item(params.containerId).Item('textCondition').val(); //搜索条件 searchResult.Item(params.columnName)[2] = searchMap.Item(params.containerId).Item('textResult').val(); //搜索结果 } //添加搜索结果,格式为:字段名、搜索类型、搜索条件、结果 function createSearchResult(params){ if(!searchResult.Exists(params.columnName)){ searchResult.Add(params.columnName, new Array()); } } //获取搜索结果值,组合成搜索结果格式 function getSearchResult(params){ var result = ''; var keys = searchResult.Keys(); for(var i = 0; i < keys.length; i++){ result += 'columnName┝COLON┥' + keys[i] + '┝SEPARATOR┥'; result += 'queryType┝COLON┥' + searchResult.Item(keys[i])[0] + '┝SEPARATOR┥' result += 'condition┝COLON┥' + searchResult.Item(keys[i])[1] + '┝SEPARATOR┥' result += 'value┝COLON┥' for(var j = 2; j < searchResult.Item(keys[i]).length; j++){ if(j > 2){ result += '┝JOIN┥'; } result += searchResult.Item(keys[i])[j] ; } result += '┝SEPARATOR┥' result += '┝END┥'; } $('#' + searchResultId).val(result); }
至此,前台搜索处理已经结束。 接下来,在分页控件获取到提交的数据源后,对其进行数据解析,由于前面定义的数据协议在后台可以解析成键值对,我们可以对其键、值进行判断、处理,最终生成查询的WHERE条件,还是以文本搜索方式为例:
///
解析完成后的数据,在分页控件中进行调用,我们增加一个分页控件PagerBase,继承自FMPager,用于实现获取解析完成后的数据,并供其它具体分页控件调用:
public class PagerBase : FMPager { protected string orderSource = ""; protected override void _disibledevent=>base.OnLoad(e); //获取查询条件 string querySource = HTMLHelper.Form("querySource"); orderSource = HTMLHelper.Form("orderSource"); DataAnalyseUtil util = new DataAnalyseUtil(); WHERE = util.AnalysePagerWhere(querySource); } public override void DataBind() { base.DataBind(); } public string WHERE { get { return where; } set { where = value; } } private string where = ""; public string ORDER_BY { get { return orderBy; } set { orderBy = value; } } private string orderBy = ""; }
改造上一篇中使用的分页控件,将它的父类从FMPager改成PagerBase,将基类获取到的查询条件及排序条件带入:
///
这样,分页控件已经实现了按前台提交过来的搜索条件对数据进行的过滤。 最后来改造控件输出及前台页面显示。 控件输出,在原有的基础上为搜索列头添加搜索属性:
| | | | |
<%# Eval("NAME") %> | <%# Eval("VAL") %> | <%# Eval("INT_VAL")%> | <%# Eval("MUTIL_VAL")%> | <%# Eval("DATE_VAL")%> |
前台调用,增加对搜索对象PagerSearch的引用,PagerSearch是我们封装好的对象,上面已经提到了其中的一些关键方法:
var pagerObj = null; var searchObj = null; function LoadInfo(){ var url = 'AjaxHandler/ProcPager.aspx'; searchObj = new PagerSearch({ ajaxHandler: 'WebServices/QueryHandler.asmx/GetTestValues' }); pagerObj = new PagerObj({ containerId: 'divPager', url: url, searchObj: searchObj }); pagerObj.Page(1); }
到此为此,整个搜索功能已经全部实际,运行的搜索页面,点击每列的列头,就可以看到本篇前面的预览效果。
Demo下载
最新评论