下面是演示效果,请欣赏.
通过在输入区中输入要筛选的内容,将会自动匹配出你要找的记录.
但对于我们赛选条件更复杂的记录,该如何找寻呢? 我们可以点击右侧的"..."
接着就会出现下图
只要左键点击记录,此记录就会返回到之前的输入框中.
我们来看看代码如何实现
首先是Hander文件,做出处理自动检索的后台服务方法,
通过传递过来的筛选条件,调用做好的分页方法,去过滤出记录..
Handler
1 [WebService(Namespace = "http://tempuri.org/")]
2 [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
3 public class HospitalHandler : IHttpHandler
4 {
5
6 public void ProcessRequest(HttpContext context)
7 {
8 context.Response.ContentType = "text/plain";
9 int start = 0;
10 int limit = 10;
11 string sort = string.Empty;
12 string dir = string.Empty;
13 string query = string.Empty;
14
15 if (!string.IsNullOrEmpty(context.Request["start"]))
16 {
17 start = int.Parse(context.Request["start"]);
18 }
19
20 if (!string.IsNullOrEmpty(context.Request["limit"]))
21 {
22 limit = int.Parse(context.Request["limit"]);
23 }
24
25 if (!string.IsNullOrEmpty(context.Request["sort"]))
26 {
27 sort = context.Request["sort"];
28 }
29
30 if (!string.IsNullOrEmpty(context.Request["dir"]))
31 {
32 dir = context.Request["dir"];
33 }
34
35 if (!string.IsNullOrEmpty(context.Request["query"]))
36 {
37 query = context.Request["query"];
38 }
39 string strwhere = "";
40 int count;
41 if (query != "*")
42 {
43 strwhere = "FullName like '%" + query + "%'";
44 }
45
46 List<V_HospitalInfo> hospitals = V_HospitalController.Current.GetPaged(strwhere, "FullName ASC", start, limit, out count);
47 context.Response.Write(string.Format("{{totalCount:{1},'datas':{0}}}", JSON.Serialize(hospitals), count));
48
49 }
50
51 public bool IsReusable
52 {
53 get
54 {
55 return false;
56 }
57 }
58 }
59
60
然后是前台的代码
Store对象
<ext:Store runat="server" AutoLoad="false" ID="stoHospital">
<Reader>
<ext:JsonReader Root="datas" TotalProperty="totalCount">
<Fields>
<ext:RecordField Name="HospitalID" />
<ext:RecordField Name="FullName" />
<ext:RecordField Name="CityText" />
<ext:RecordField Name="AreaText" />
</Fields>
</ext:JsonReader>
</Reader>
</ext:Store>
看过Coolite的Custom Search范例的可能会问了,
ext:
HttpProxy 怎么没写?
其实本人是在DNN框架下使用的,所以这个文件的定位我写到了.cs代码中
Code
HttpProxy httpProxy = new HttpProxy();
httpProxy.Url = this.ModulePath + "http://www.cnblogs.com/VAP.Modules.Hospital/VAP.Modules.Hospital.HospitalAccount/HospitalHandler.ashx";
httpProxy.Method = HttpMethod.POST;
this.stoHospital.Proxy.Add(httpProxy);
stoHospital.DataBind();
当然,如果每此必要,你也可以像官网范例中,直接写上如。
<
ext:Store
runat
="server"
ID
="Store1"
>
<
Proxy
>
<
ext:HttpProxy
Method
="POST"
Url
="Plants.ashx"
/>
</
Proxy
>
下面是Combobox的代码
Code
Code
<script type="text/javascript">
var PopupSelectHospital = function(combobox,hidfield)
{
openHospital(combobox,hidfield);
}
</script>
<style type="text/css">
.search-item {
font: normal 11px tahoma, arial, helvetica, sans-serif;
padding: 3px 10px 3px 10px;
border: 1px solid #fff;
border-bottom: 1px solid #eeeeee;
white-space: normal;
color: #555;
}
.search-item h3 {
display: block;
font: inherit;
font-weight: bold;
color: #222;
}
.search-item h3 span {
float: right;
font-weight: normal;
margin: 0 0 5px 5px;
width: 180px;
display: block;
clear: none;
}
p { width: 650px; }
.ext-ie .x-form-text { position: static !important; }
</style>
<ext:Hidden runat="server" ID="hidHospital"></ext:Hidden>
<ext:ComboBox
ID="cboHospital"
runat="server"
FieldLabel="医院"
StoreID="stoHospital"
DisplayField="FullName"
ValueField="HospitalID"
TypeAhead="true"
LoadingText="查找中"
PageSize="10"
ItemSelector="div.search-item"
MinChars="0" >
<Template>
<tpl for=".">
<div class="search-item">
<h3><span>城市:{CityText}</span>{FullName}</h3>
地区:{AreaText}
</div>
</tpl>
</Template>
<Triggers>
<ext:FieldTrigger Icon="Clear" HideTrigger="true" />
<ext:FieldTrigger Icon="Ellipsis" Qtip="选择医院" />
</Triggers>
<Listeners>
<Select Handler="this.triggers[0].show();" />
<Blur Handler="#{hidHospital}.setValue(this.getValue());" />
<BeforeQuery Handler="this.triggers[0][ this.getRawValue().toString().length == 0 ? 'hide' : 'show']();" />
<TriggerClick Handler="if(index == 0) {this.clearValue();#{hidHospital}.setValue('');this.triggers[0].hide(); }else if(index==1){PopupSelectHospital(this,#{hidHospital});}" />
</Listeners>
</ext:ComboBox>
要点
1.建立了两个Trigger,一个处理清空内容(所检索到的记录或者弹出查找到的记录), 另一个就是弹出新页面检索记录.
Listeners几个事件就是针对是否隐藏"清空"按键的判断逻辑
2.仔细看,有一个ext:Hiddren, 真是一个关键点,其实本来根本没必要使用多一个Hiddren, 因为Combobox中的,Value和Text,就可以分别对应
一个显示值,和一个实际值,。。 我们从检索的下来框中选中的记录,也可以直接回填上这两个值, 但是实际上,我们使用SetValue想手动赋值给Combobox
值和显示值时,就发现,Value和Text都会被设置成同样的一个内容,我们不可能单独的修改掉其中一个,我们回传给检索框变得困难了,这使的应用起来相当麻烦.
google上也找到一些Ext下的偏门,但是本人没有试成功,所以,干脆,就用一个Hiddren单独存放这种实际值,再在一些Listeners中把值传递给Hiddren.
好的,我们看看.cs代码.
读取时:
Code
if (objPolicy.HospitalID != Null.NullGuid)
{
hidHospital.Value = objPolicy.HospitalID.ToString();
cboHospital.SetValue(objPolicy.HospitalFullname);
cboHospital.ShowTrigger(0);
}
else
{
cboHospital.ConcealTrigger(0);
cboHospital.Triggers[0].HideTrigger = true;
cboHospital.SetValue("");
}
ShowTrigger是显示Trigger,
ConcealTrigger是隐藏Trigger,
这个是隐藏那个"清空"的
更新时:
Code
if (!string.IsNullOrEmpty(this.hidHospital.Value.ToString()))
{
objPolicy.HospitalID = new Guid(this.hidHospital.Value.ToString());
}
else
{
objPolicy.HospitalID = Null.NullGuid;
}
下面是弹出的window代码
Code
<script type="text/javascript">
var hidCtrl;
var hidID;
var openHospital = function (Ctrl,Hid) {
hidCtrl=Ctrl;
hidID=Hid;
var window = <%= HospitalWindow.ClientID %>;
window.show();
}
var cellclickHospital = function (grid , rowIndex,columnIndex, e) {
var columnId = grid.getColumnModel().getColumnId(columnIndex); // Get column id
var record = grid.getStore().getAt(rowIndex); // Get the Record
if (columnId != 'EditColumn')
{
<%= HospitalWindow.ClientID %>.hide(null);
hidCtrl.setValue(record.data['FullName']);
hidID.setValue(record.data['HospitalID']);
hidCtrl.triggers[0].show();
}
}
</script>
GridPanel中写入
<Listeners>
<CellClick Fn="cellclickHospital"/>
</Listeners>
到这,就能实现一个功能健全的自动检索了