在asp.net mvc3中使用jquery ui 的autocomplete
首先说没有使用json的情况,
这种情况就非常简单,
比如在/Home/Index页面中有一个
<p> @Html.TextBox("Text1") </p>
现在把它变成一个autocomplete
首先记得引用 jquery-1.5.1.js 和 jquery-ui-1.8.11.js
以及jquery.ui.all.css
然后就可以编写jquery 代码了:
<script type="text/javascript">
$(function () {
var availableTags = [
"黄1",
"黄2",
"黄3",
"BASIC",
"C",
"C++",
"Clojure",
"COBOL",
"ColdFusion",
"Erlang",
"Fortran",
"Groovy",
"Haskell",
"Java",
"JavaScript",
"Lisp",
"Perl",
"PHP",
"Python",
"Ruby",
"Scala",
"Scheme"
];
$("#Text1").autocomplete({
source: availableTags
});
})
autocomplete 里面的 source 设置为一个数组就可以了
当然,实际开发中,这个数组的来源一般是后台代码访问数据库所得到的,
并且以json的格式传过来
现在看看下一个例子:
比如我现在要做一个匹配教师名称的autocomplete ,
我在/Home/Index页面里面放两个input
<p>
@Html.TextBox("TeacherInput")
@Html.TextBox("TeacherNo")
</p>
TeacherInput是用来做自动匹配的,而TeacherNo使用了记录教师名字对应的教工号
现在看看后台代码:
首先写一个教师类
public class Teacher
{
public string TeacherNo { get; set; } //教工号
public string TeacherName { get; set; } //名字
public string PostTitle { get; set; } // 职称
}//end class
然后在HomeController里面读取数据库所存储的Teacher,并且放入一个数组内:
这里为了演示的简洁,就不从数据库读数据了,
直接硬编码算了:
public IEnumerable<Teacher> MyTeacherList()
{
List<Teacher> teacherList = new List<Teacher>();
Teacher t1=new Teacher { TeacherName="李小龙" , TeacherNo="001" , PostTitle="教授" };
Teacher t2 = new Teacher { TeacherName = "李逵", TeacherNo = "002", PostTitle = "讲师" };
Teacher t3 = new Teacher { TeacherName = "张飞", TeacherNo = "003", PostTitle = "副教授" };
Teacher t4 = new Teacher { TeacherName = "张三", TeacherNo = "004", PostTitle = "讲师" };
Teacher t5 = new Teacher { TeacherName = "曾哥", TeacherNo = "005", PostTitle = "教授" };
//上面的数据从数据库中得到,你懂的
teacherList.Add(t1);
teacherList.Add(t2);
teacherList.Add(t3);
teacherList.Add(t4);
teacherList.Add(t5);
return teacherList.AsEnumerable();
}
然后这个数组就可以用 JsonResult 返回给前台了!!
public JsonResult TeacherJson(string TeacherInput)
{
var formateData = MyTeacherList()
.Select(x => new {
TeacherName = x.TeacherName,
TeacherNo = x.TeacherNo ,
PostTitle=x.PostTitle});
formateData = formateData
.Where(x => x.TeacherName.Contains(TeacherInput));
return Json(formateData, JsonRequestBehavior.AllowGet);
}
大家可以看到这个方法里面有一个参数: TeacherInput
这个就是前台控件的名字了,
读者应该明白这是 asp.net mvc 可以将Request上下文对象的值作为动作方法的参数,
这里就不多解释了!!
现在我们看回前台:
@{
ViewBag.Title = "Home Page";
}
<h2>@ViewBag.Message</h2>
<p>
@Html.TextBox("TeacherInput")
@Html.TextBox("TeacherNo")
</p>
<script type="text/javascript">
$(function () {
$("#TeacherInput").autocomplete({
source: function (request, response) {
$.ajax({
url: '@Url.Action("TeacherJson", "Home")',
type: "POST",
dataType: "json",
data: { TeacherInput: request.term },
success: function (data) {
response(
$.map(
data,
function (item) {
return {
label: item.TeacherName,
value: item.TeacherNo ,
posttitle:item.PostTitle}
} //end function (item)
)//end map
); //end response
} //end success
}); //end ajax
}, //end source
focus: function (event, ui) {
$("#TeacherNo").val(ui.item.value);
return false;
}, //end focus
select: function (event, ui) {
$("#TeacherInput").val(ui.item.label);
return false;
} , //end select
minLength:0
}); //end autocomplete
}); //end function
</script>

从上面的代码可以看到,source对应的是ajax的内容,
ajax的url就是刚才后台代码写的TeacherJson
而data 根据teacher的内容重新定义,
label对应TeacherName
value对应TeacherNo
posttitle对应PostTitle
这里要说明为什么一定要有 label 和 value这两个名字呢???
因为jquery ui 里面的 autocomplete 默认情况下:是用label进行搜索,value进行显示!
所以为了我就这样子命名了,
当然也可以按照你喜欢的规则进行搜索和显示,这里就不演示了。
然后我们分析一下:focus
focus指的是下拉框选择的时候触发的事件
上下上下选择的时候TextBox("TeacherNo")就是显示 value 的内容
那么select事件指的是按回车确定的事件:
我把 label 填入了 TextBox("TeacherInput") 里面了
最后的minLength是最好理解的:匹配字符串的最短长度,
如果是1的话,就必须写一个字符才会有匹配的下拉框出现
写到这个是不是还是觉得autocomplete有点单调,
我们的teacher数组里面有还几属性,如果我想做出这个效果:

那么就要自己扩展一下autocomplete,写一个新的TeacherAutoComplete.
扩展的方法是用 widget !!
需要修改的只是下拉框显示的标签,所以只用修改原来的 _renderItem即可!!
修改一下之后就可以得到自己的控件TeacherAutoComplete!!
@{
ViewBag.Title = "Home Page";
}
<h2>@ViewBag.Message</h2>
<p>
@Html.TextBox("TeacherInput")
@Html.TextBox("TeacherNo")
</p>
<script type="text/javascript">
$.widget("kh.TeacherAutoComplete", $.ui.autocomplete, {
_renderItem: function (ul, item) {
return $("<li></li>")
.data("item.autocomplete", item)
.append("<a>" +"教师名:"+ item.label +"<br/> 教工号:" + item.value +" 职称:"+ item.posttitle+ "</a>")
.appendTo(ul);
}//end funtion
})//end widget
//来个json的
$("#TeacherInput").TeacherAutoComplete({
//这里就用TeacherAutoComplete,不是原本的autocomplete
source: function (request, response) {
$.ajax({
url: '@Url.Action("TeacherJson", "Home")',
type: "POST",
dataType: "json",
data: { TeacherInput: request.term },
success: function (data) {
response(
$.map(
data,
function (item) {
return { label: item.TeacherName, value: item.TeacherNo , posttitle:item.PostTitle}
} //end function (item)
)//end map
); //end response
} //end success
}); //end ajax
}, //end source
focus: function (event, ui) {
$("#TeacherNo").val(ui.item.value);
return false;
}, //end focus
select: function (event, ui) {
$("#TeacherInput").val(ui.item.label);
return false;
} , //end select
minLength:0
}); //end autocomplete
}); //end function
</script>
首先说没有使用json的情况,
这种情况就非常简单,
比如在/Home/Index页面中有一个
<p> @Html.TextBox("Text1") </p>
现在把它变成一个autocomplete
首先记得引用 jquery-1.5.1.js 和 jquery-ui-1.8.11.js
以及jquery.ui.all.css
然后就可以编写jquery 代码了:
<script type="text/javascript">
$(function () {
var availableTags = [
"黄1",
"黄2",
"黄3",
"BASIC",
"C",
"C++",
"Clojure",
"COBOL",
"ColdFusion",
"Erlang",
"Fortran",
"Groovy",
"Haskell",
"Java",
"JavaScript",
"Lisp",
"Perl",
"PHP",
"Python",
"Ruby",
"Scala",
"Scheme"
];
$("#Text1").autocomplete({
source: availableTags
});
})
</script>
autocomplete 里面的 source 设置为一个数组就可以了
当然,实际开发中,这个数组的来源一般是后台代码访问数据库所得到的,
并且以json的格式传过来
现在看看下一个例子:
比如我现在要做一个匹配教师名称的autocomplete ,
我在/Home/Index页面里面放两个input
<p>
@Html.TextBox("TeacherInput")
@Html.TextBox("TeacherNo")
</p>
TeacherInput是用来做自动匹配的,而TeacherNo使用了记录教师名字对应的教工号
现在看看后台代码:
首先写一个教师类
public class Teacher
{
public string TeacherNo { get; set; } //教工号
public string TeacherName { get; set; } //名字
public string PostTitle { get; set; } // 职称
}//end class
然后在HomeController里面读取数据库所存储的Teacher,并且放入一个数组内:
这里为了演示的简洁,就不从数据库读数据了,
直接硬编码算了:
public IEnumerable<Teacher> MyTeacherList()
{
List<Teacher> teacherList = new List<Teacher>();
Teacher t1=new Teacher { TeacherName="李小龙" , TeacherNo="001" , PostTitle="教授" };
Teacher t2 = new Teacher { TeacherName = "李逵", TeacherNo = "002", PostTitle = "讲师" };
Teacher t3 = new Teacher { TeacherName = "张飞", TeacherNo = "003", PostTitle = "副教授" };
Teacher t4 = new Teacher { TeacherName = "张三", TeacherNo = "004", PostTitle = "讲师" };
Teacher t5 = new Teacher { TeacherName = "曾哥", TeacherNo = "005", PostTitle = "教授" };
//上面的数据从数据库中得到,你懂的
teacherList.Add(t1);
teacherList.Add(t2);
teacherList.Add(t3);
teacherList.Add(t4);
teacherList.Add(t5);
return teacherList.AsEnumerable();
}
然后这个数组就可以用 JsonResult 返回给前台了!!
public JsonResult TeacherJson(string TeacherInput)
{
var formateData = MyTeacherList()
.Select(x => new {
TeacherName = x.TeacherName,
TeacherNo = x.TeacherNo ,
PostTitle=x.PostTitle});
formateData = formateData
.Where(x => x.TeacherName.Contains(TeacherInput));
return Json(formateData, JsonRequestBehavior.AllowGet);
}
大家可以看到这个方法里面有一个参数: TeacherInput
这个就是前台控件的名字了,
读者应该明白这是 asp.net mvc 可以将Request上下文对象的值作为动作方法的参数,
这里就不多解释了!!
现在我们看回前台:
@{
ViewBag.Title = "Home Page";
}
<h2>@ViewBag.Message</h2>
<p>
@Html.TextBox("TeacherInput")
@Html.TextBox("TeacherNo")
</p>
<script type="text/javascript">
$(function () {
$("#TeacherInput").autocomplete({
source: function (request, response) {
$.ajax({
url: '@Url.Action("TeacherJson", "Home")',
type: "POST",
dataType: "json",
data: { TeacherInput: request.term },
success: function (data) {
response(
$.map(
data,
function (item) {
return {
label: item.TeacherName,
value: item.TeacherNo ,
posttitle:item.PostTitle}
} //end function (item)
)//end map
); //end response
} //end success
}); //end ajax
}, //end source
focus: function (event, ui) {
$("#TeacherNo").val(ui.item.value);
return false;
}, //end focus
select: function (event, ui) {
$("#TeacherInput").val(ui.item.label);
return false;
} , //end select
minLength:0
}); //end autocomplete
}); //end function
</script>
从上面的代码可以看到,source对应的是ajax的内容,
ajax的url就是刚才后台代码写的TeacherJson
而data 根据teacher的内容重新定义,
label对应TeacherName
value对应TeacherNo
posttitle对应PostTitle
这里要说明为什么一定要有 label 和 value这两个名字呢???
因为jquery ui 里面的 autocomplete 默认情况下:是用label进行搜索,value进行显示!
所以为了我就这样子命名了,
当然也可以按照你喜欢的规则进行搜索和显示,这里就不演示了。
然后我们分析一下:focus
focus指的是下拉框选择的时候触发的事件
上下上下选择的时候TextBox("TeacherNo")就是显示 value 的内容
那么select事件指的是按回车确定的事件:
我把 label 填入了 TextBox("TeacherInput") 里面了
最后的minLength是最好理解的:匹配字符串的最短长度,
如果是1的话,就必须写一个字符才会有匹配的下拉框出现
写到这个是不是还是觉得autocomplete有点单调,
我们的teacher数组里面有还几属性,如果我想做出这个效果:
那么就要自己扩展一下autocomplete,写一个新的TeacherAutoComplete.
扩展的方法是用 widget !!
需要修改的只是下拉框显示的标签,所以只用修改原来的 _renderItem即可!!
修改一下之后就可以得到自己的控件TeacherAutoComplete!!
@{
ViewBag.Title = "Home Page";
}
<h2>@ViewBag.Message</h2>
<p>
@Html.TextBox("TeacherInput")
@Html.TextBox("TeacherNo")
</p>
<script type="text/javascript">
$.widget("kh.TeacherAutoComplete", $.ui.autocomplete, {
_renderItem: function (ul, item) {
return $("<li></li>")
.data("item.autocomplete", item)
.append("<a>" +"教师名:"+ item.label +"<br/> 教工号:" + item.value +" 职称:"+ item.posttitle+ "</a>")
.appendTo(ul);
}//end funtion
})//end widget
//来个json的
$("#TeacherInput").TeacherAutoComplete({
//这里就用TeacherAutoComplete,不是原本的autocomplete
source: function (request, response) {
$.ajax({
url: '@Url.Action("TeacherJson", "Home")',
type: "POST",
dataType: "json",
data: { TeacherInput: request.term },
success: function (data) {
response(
$.map(
data,
function (item) {
return { label: item.TeacherName, value: item.TeacherNo , posttitle:item.PostTitle}
} //end function (item)
)//end map
); //end response
} //end success
}); //end ajax
}, //end source
focus: function (event, ui) {
$("#TeacherNo").val(ui.item.value);
return false;
}, //end focus
select: function (event, ui) {
$("#TeacherInput").val(ui.item.label);
return false;
} , //end select
minLength:0
}); //end autocomplete
}); //end function
</script>