在 ASP.NET MVC 3 中创建多列自动完成/组合框






4.50/5 (8投票s)
在 ASP.NET MVC3 中创建一个多列组合框/自动完成/下拉列表。
引言
这段代码用于为 ASP.NET MVC3 应用程序创建一个多列自动完成功能。
背景
ASP.NET MVC3 不支持组合框或多列下拉列表。因此,我在 MVC 3 中创建了一个自定义操作控件。通过它,我们可以在 asp.net MVC 中实现多列组合框的功能。
为了实现这一点,我们的应用程序使用了通过 SQL Server 2008 r2 数据库“ProEnhance”生成的 Entity Framework 模型 (.edmx)。
代码使用 Json 结果通过 ajax 绑定来绑定数据。
使用代码
1. 首先,我们需要创建一个简单的数据库,其中包含两个简单的表:employee 和 projects。下面是生成表的脚本。
USE [ProEnhance]
GO
/****** Object: Table [dbo].[EmployeeMast] Script Date: 11/01/2012 18:06:04 ******/
CREATE TABLE [dbo].[EmployeeMast](
[Id] [int] IDENTITY(1,1) NOT NULL,
[EmpCode] [varchar](50) NULL,
[MachineCode] [varchar](50) NULL,
[FirstName] [nvarchar](150) NULL,
[LastName] [nvarchar](150) NULL,
[DisplayName] [nvarchar](400) NULL,
[Address] [nvarchar](250) NULL,
[ProjectId] [int] NULL,
CONSTRAINT [PK_EmployeeMast] PRIMARY KEY CLUSTERED
(
[Id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
/****** Object: Table [dbo].[ProjectMast] Script Date: 11/01/2012 18:06:58 ******/
CREATE TABLE [dbo].[ProjectMast](
[Id] [int] IDENTITY(1,1) NOT NULL,
[ProjectName] [nvarchar](150) NULL,
[ProjectDesc] [nvarchar](500) NULL,
[PlatformId] [int] NULL,
CONSTRAINT [PK_ProjectMast] PRIMARY KEY CLUSTERED
(
[Id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
2. 现在控制器为上述数据库创建 Edmx
3. 创建控制器以创建自定义控件。以下是控制器代码。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using ComboDemo.Models;
namespace ComboDemo.Controllers
{
public class CustomeControlsController : Controller
{
//
// GET: /CustomeControls/
public ActionResult Index()
{
return View();
}
public ActionResult MultiColumnComboBox(string SearchFor, string ControlId)
{
ViewBag.ProcId = SearchFor.Trim();
ViewBag.ControlBlockId = "block" + ControlId.Trim();
ViewBag.ControlId = ControlId.Trim();
ViewBag.ControlTxtId = "txt" + ControlId.Trim();
return View();
}
public JsonResult LoadComboData(string strSearch, string SearchFor)
{
ProEnhanceEntities db = new ProEnhanceEntities();
strSearch = strSearch.Trim();
if (SearchFor.Trim() == "employee")
{
var res = (from E in db.EmployeeMasts
where E.DisplayName.ToLower().Contains(strSearch.ToLower()) || E.EmpCode.ToLower().Contains(strSearch.ToLower()) || E.Address.ToLower().Contains(strSearch.ToLower())
select new
{
E.EmpCode,
E.DisplayName,
E.Address
}).ToList();
return Json(res, JsonRequestBehavior.AllowGet);
}
if (SearchFor.Trim() == "project")
{
var res = (from P in db.ProjectMasts
where P.ProjectDesc.ToLower().Contains(strSearch.ToLower()) || P.ProjectName.ToLower().Contains(strSearch.ToLower())
select P).ToList();
return Json(res, JsonRequestBehavior.AllowGet);
}
return Json(null, JsonRequestBehavior.AllowGet);
}
}
}
4. 创建 MultipleColumnCombobox 操作的视图。以下是它的代码。使用 jQuery 为 Input 控件生成自动完成功能。
@{
Layout = null;
}
<style type="text/css">
table td
{
padding: 3px 5px;
margin: 0;
}
a:link
{
text-decoration: none;
cursor: pointer;
}
.tdHeader
{
background-color: #CEF6F5;
}
.DataBlock
{
max-width: 520px;
min-width: 215px;
max-height: 200px;
overflow: auto;
background-color: #fff;
}
.renderpart
{
z-index: 99999;
position: absolute;
}
</style>
<input type="hidden" id="@ViewBag.ProcId" name="@ViewBag.ProcId" value=""/>
<input type="hidden" id="@ViewBag.ControlId" name="@ViewBag.ControlId" value=""/>
<input type="text" name="@ViewBag.ControlTxtId" id="@ViewBag.ControlTxtId" autocomplete="off"/>
<div class="@ViewBag.ControlTxtId renderpart">
<div class="DataBlock">
<div id="@ViewBag.ControlBlockId" style="max-width: 520px;">
</div>
</div>
</div>
<script src="../../Scripts/jquery-1.7.1.js" type="text/javascript"></script>
<script src="../../Scripts/json.debug.js" type="text/javascript"></script>
<script type="text/javascript">
$(document).ready(function () {
$(".renderpart").hide();
var txtid = "#" + '@ViewBag.ControlTxtId';
var renderpart = "." + '@ViewBag.ControlTxtId';
var selectlinkvalueid = ".Get" + '@ViewBag.ProcId';
$(selectlinkvalueid).live("click", function () {
var value = $(this).attr('id');
var valueText = $(this).attr('title');
$("#@ViewBag.ControlId").val(value);
$(txtid).val(valueText);
$(renderpart).slideUp("slow");
});
$(txtid).keyup(function () {
var value = $(txtid).val();
var Procvalue = '@ViewBag.ProcId';
var controlid = "#" + '@ViewBag.ControlBlockId';
value = encodeURI(value);
if (value.length > 2) {
$.ajaxSetup({ cache: false });
$.getJSON("/CustomeControls/LoadComboData", { strSearch: " " + value, ProcId: " " + Procvalue }, function (data) {
$(controlid).html("");
var activecols = $("#hdnActiveColumns").val();
var htmlrow = "";
var tempprocId = '@ViewBag.ProcId';
var jsondata = JSON.stringify(data);
$(controlid).html(CreateDynamicTable(jsondata, tempprocId));
$(renderpart).slideDown("slow");
});
$.ajaxSetup({ cache: true });
}
else {
$(renderpart).slideUp("slow");
}
});
$(txtid).focusin(function () {
var txtid = "#" + '@ViewBag.ControlTxtId';
var value = $(txtid).val();
var Procvalue = '@ViewBag.ProcId';
var controlid = "#" + '@ViewBag.ControlBlockId';
value = encodeURI(value);
if (value.length > 2) {
$.ajaxSetup({ cache: false });
$.getJSON("/CustomeControls/LoadComboData", { strSearch: " " + value, ProcId: " " + Procvalue }, function (data) {
$(controlid).html("");
var htmlrow = "";
var tempprocId = '@ViewBag.ProcId';
var jsondata = JSON.stringify(data);
$(controlid).html(CreateDynamicTable(jsondata, tempprocId));
$(renderpart).slideDown("slow");
});
$.ajaxSetup({ cache: true });
}
else {
$(renderpart).slideUp("slow");
}
});
function CreateDynamicTable(objArray, tempprocId) {
var array = JSON.parse(objArray);
var str = '<table style="width:100%;">';
str += '<tr>';
for (var index in array[0]) {
str += '<th scope="col">' + index + '</th>';
}
str += '</tr>';
str += '<tbody>';
var flag = false;
var ids;
for (var i = 0; i < array.length; i++) {
str += (i % 2 == 0) ? '<tr>' : '<tr>';
for (var index in array[i]) {
if (flag == false) {
ids = array[i][index];
flag = true;
}
str += '<td><a id="' + ids + '" class="Get' + tempprocId + '" title="' + array[i][index] + '" href="#">' + array[i][index] + '</a></td>';
}
str += '</tr>';
}
str += '</tbody>';
str += '</table>';
return str;
}
});
$(document).click(function (evt) {
var renderpart = "." + '@ViewBag.ControlTxtId';
var theElem = (evt.srcElement) ? evt.srcElement : evt.target;
if (theElem.id == "main" || theElem.id == "sub1") {
$(renderpart).slideUp("fast");
}
});
</script>
5. 现在只需使用参数调用我们的操作即可渲染一个自定义自动完成控件。
@{
ViewBag.Title = "Index";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<h2>
Index</h2>
<h4>
Render Custom action to generate Multiple column Combo.</h4>
<table>
<tr>
<td>
Employees:
</td>
<td>
@{Html.RenderAction("MultiColumnComboBox", "CustomeControls", new { ControlFor = "employee", ControlId = "comboEmp" });}
</td>
</tr>
<tr>
<td>
Projects:
</td>
<td>
@{Html.RenderAction("MultiColumnComboBox", "CustomeControls", new { ControlFor = "project", ControlId = "comboPrj" });}
</td>
</tr>
</table>