三级或多级联动的场景经常会碰到,比如省、市、区,比如品牌、车系、车型,比如类别的多级联动......我们首先想到的是用三个select来展示,这是最通常的做法。但在另外一些场景中,比如确定搜索条件的时候,对于三级联动来说,可能选择1个,2个,或3个条件,我想,以下的方式可能更适合:
以上,可以只选择品牌,或同时选择品牌、车系,或同时选择品牌、车系、车型,最后把选择的内容展示到input上,并以逗号隔开。
可以实现的功能包括:
界面的构成如下:
实现的思路大致这样:
领域先行,首先是有关品牌、车系、车型的模型:
public class CarCategory { public int Id { get; set; } public string Name { get; set; } public int PId { get; set; } public string FirstLetter { get; set; } public string AnchorName { get; set; } public int Level { get; set; } }
在ASP.NET MVC4中,在Shared/Layout.cshtml中,该有的css,js都必须有:
<head> <meta charset="utf-8" /> <meta name="viewport" content="width=device-width" /> <title>@ViewBag.Title</title> @Styles.Render("~/Content/css") @RenderSection("styles", required: false) <link href="~/bootstrap/css/bootstrap.min.css" rel="stylesheet" /> @Scripts.Render("~/bundles/jquery") <script src="~/bootstrap/js/bootstrap.min.js"></script> </head> <body> @RenderBody() @RenderSection("scripts", required: false) </body>
模拟一个数据库,该数据库类可以获取到所有的品牌、车系、车型,以及根据品牌Id或车系Id获取对应的车系和车型。
public class Database { public static IEnumerable<CarCategory> GetCarCategories() { return new List<CarCategory>() { new CarCategory(){Id = 0, Name = "奥迪",FirstLetter = "A",AnchorName = "aa", Level = 1, PId = -1}, new CarCategory(){Id = 1, Name = "奥斯顿·马丁",FirstLetter = "A",AnchorName = "aa", Level = 1, PId = -1}, new CarCategory(){Id = 2, Name = "宝骏",FirstLetter = "B",AnchorName = "bb", Level = 1, PId = -1}, new CarCategory(){Id = 3, Name = "巴博斯",FirstLetter = "B",AnchorName = "bb", Level = 1, PId = -1}, new CarCategory(){Id = 4, Name = "北汽威旺",FirstLetter = "B",AnchorName = "bb", Level = 1, PId = -1}, new CarCategory(){Id = 5, Name = "北汽制造",FirstLetter = "B",AnchorName = "bb", Level = 1, PId = -1}, new CarCategory(){Id = 6, Name = "奔驰",FirstLetter = "B",AnchorName = "bb", Level = 1, PId = -1}, new CarCategory(){Id = 7, Name = "别克",FirstLetter = "B",AnchorName = "bb", Level = 1, PId = -1}, new CarCategory(){Id = 8, Name = "宾利",FirstLetter = "B",AnchorName = "bb", Level = 1, PId = -1}, new CarCategory(){Id = 9, Name = "保时捷",FirstLetter = "B",AnchorName = "bb", Level = 1, PId = -1}, new CarCategory(){Id = 10, Name = "比亚迪",FirstLetter = "B",AnchorName = "bb", Level = 1, PId = -1}, new CarCategory(){Id = 11, Name = "奔腾",FirstLetter = "B",AnchorName = "bb", Level = 1, PId = -1}, new CarCategory(){Id = 12, Name = "标致",FirstLetter = "B",AnchorName = "bb", Level = 1, PId = -1}, new CarCategory(){Id = 13, Name = "本田",FirstLetter = "B",AnchorName = "bb", Level = 1, PId = -1}, new CarCategory(){Id = 14, Name = "宝马",FirstLetter = "B",AnchorName = "bb", Level = 1, PId = -1}, new CarCategory(){Id = 15, Name = "北京汽车",FirstLetter = "B",AnchorName = "bb", Level = 1, PId = -1}, new CarCategory(){Id = 16, Name = "昌河",FirstLetter = "C",AnchorName = "cc", Level = 1, PId = -1}, new CarCategory(){Id = 17, Name = "长安",FirstLetter = "C",AnchorName = "cc", Level = 1, PId = -1}, new CarCategory(){Id = 18, Name = "长城",FirstLetter = "C",AnchorName = "cc", Level = 1, PId = -1}, new CarCategory(){Id = 19, Name = "奥迪A4",FirstLetter = "A",AnchorName = "", Level = 2, PId = 0}, new CarCategory(){Id = 20, Name = "奥迪A6L",FirstLetter = "A",AnchorName = "", Level = 2, PId = 0}, new CarCategory(){Id = 21, Name = "奥迪Q3",FirstLetter = "A",AnchorName = "", Level = 2, PId = 0}, new CarCategory(){Id = 22, Name = "奥迪A4舒适版",FirstLetter = "A",AnchorName = "", Level = 3, PId = 19}, new CarCategory(){Id = 23, Name = "奥迪A4尊贵版",FirstLetter = "A",AnchorName = "", Level = 3, PId = 19}, new CarCategory(){Id = 24, Name = "奥迪A6L舒适版",FirstLetter = "A",AnchorName = "", Level = 3, PId = 20}, new CarCategory(){Id = 25, Name = "奥迪A6L黄金版",FirstLetter = "A",AnchorName = "", Level = 3, PId = 20}, new CarCategory(){Id = 26, Name = "奥迪Q3舒适版",FirstLetter = "A",AnchorName = "", Level = 3, PId = 21}, new CarCategory(){Id = 27, Name = "奥迪Q3至尊版",FirstLetter = "A",AnchorName = "", Level = 3, PId = 21}, }; } //根据品牌或车系I获取所有车系或车型 public static IEnumerable<CarCategory> GetCarCategoriesByPId(int pid) { return GetCarCategories().Where(c => c.PId == pid); } }
在HomeController中,在前端页面加载的时候,这里提供一个分组好的所有品牌的json格式给前端;当前端把鼠标移动到某个品牌上,这里根据品牌Id返回车系的json格式给前端;当前端把鼠标移动到某个车系上,这里根据车系Id返回车型的json格式给前端。
public class HomeController : Controller { public ActionResult Index() { return View(); } //获取所有品牌 public ActionResult GetPinPai() { var allPinPai = Database.GetCarCategories().Where(c => c.Level == 1).OrderBy(c => c.Id); var result = from p in allPinPai group p by new { p.FirstLetter, p.AnchorName } into g select new {firstletter = g.Key.FirstLetter, anchor = g.Key.AnchorName, pinpais = g}; return Json(result, JsonRequestBehavior.AllowGet); } //根据品牌Id获取车系 [HttpPost] public ActionResult GetCheXiByPId(int pid) { var allCheXi = Database.GetCarCategoriesByPId(pid).OrderBy(c => c.Id); var result = from c in allCheXi select new {chexi = c.Name, cxid = c.Id, parentId = c.PId}; return Json(result); } //根据车系Id获取车型 [HttpPost] public ActionResult GetCheXingByCxId(int cxid) { var allCheXing = Database.GetCarCategoriesByPId(cxid).OrderBy(c => c.Id); var result = from c in allCheXing select new { chexing = c.Name, chexingid = c.Id, parentId = c.PId }; return Json(result); } }
在Home/Index.cshtml视图中,品牌、车系、车型内容都是先填充到tmpl模版中,然后追加到页面某个区域上的。
@{ ViewBag.Title = "Index"; Layout = "~/Views/Shared/_Layout.cshtml"; } @section styles { <link href="~/Content/CarSelect.css" rel="external nofollow" rel="stylesheet" /> } <div> <input type="text" id="mychoice"> <span> <button type="button">∨</button> </span> </div> <div id="carcategory-picker-outer"> <a href="javascript:void(0)" rel="external nofollow" ></a> <div id="carcategory-picker-inner"> <div id="pinpai"> <h6>请选择品牌</h6> <div id="PreLetter"> <a href="#aa" rel="external nofollow" >A</a> <a href="#bb" rel="external nofollow" >B</a> <a href="#cc" rel="external nofollow" >C</a> <a href="#dd" rel="external nofollow" >D</a> <a href="#ff" rel="external nofollow" >F</a> <a href="#gg" rel="external nofollow" >G</a> <a href="#hh" rel="external nofollow" >H</a> <a href="#jj" rel="external nofollow" >J</a> <a href="#kk" rel="external nofollow" >K</a> <a href="#ll" rel="external nofollow" >L</a> <a href="#mm" rel="external nofollow" >M</a> <a href="#nn" rel="external nofollow" >N</a> <a href="#oo" rel="external nofollow" >O</a> <a href="#qq" rel="external nofollow" >Q</a> <a href="#rr" rel="external nofollow" >R</a> <a href="#ss" rel="external nofollow" >S</a> <a href="#ww" rel="external nofollow" >W</a> <a href="#xx" rel="external nofollow" >X</a> <a href="#yy" rel="external nofollow" >Y</a> <a href="#zz" rel="external nofollow" >Z</a> </div> <div id="AllPinPai"> </div> </div> <div id="chexi"> <h6>请选择车系</h6> <div id="AllCheXi"> </div> </div> <div id="chexin"> <h6>请选择车型</h6> <div id="AllCheXing"> </div> </div> </div> </div> @section scripts { <script src="~/Scripts/jquery.tmpl.min.js"></script> <script type="text/javascript"> $(function() { //加载所有品牌 $.getJSON("@Url.Action("GetPinPai", "Home")", function(data) { $("#pinpaiTemplate").tmpl(data).appendTo("#AllPinPai"); }); //点击input弹出品牌车系车型选择 $("#mychoice").on("click", function() { $("#carcategory-picker-outer").css("display", "block"); $("body").bind("mousedown", onBodyDown);//绑定鼠标单击事件 }); //点击关闭按钮隐藏品牌车系车型选择 $(".cancel").on("click", function() { hideMenu(); }); //给所有品牌加上鼠标移动上事件 $("#AllPinPai").on("mouseover", ".ppm", function() { $(this).addClass("selected"); $("#chexi").css("display", "block"); $.post("@Url.Action("GetCheXiByPId","Home")", { "pid": $(this).attr("pid") }, function (data) { $("#AllCheXi").empty(); $("#AllCheXing").empty(); $("#chexiTemplate").tmpl(data).appendTo("#AllCheXi"); }); }); //给所有品牌加上鼠标移去事件 $("#AllPinPai").on("mouseout", ".ppm", function () { $(this).removeClass("selected"); }); //品牌点击事件 $("#AllPinPai").on("click", ".ppm", function () { $("#mychoice").val(""); $("#mychoice").val($(this).text()); hideMenu(); }); //给车系加上鼠标移动上事件 $("#AllCheXi").on("mouseover", ".cxm", function () { //取取当前车系的父类Id var parentId = $(this).attr("parentid"); //把品牌中该父类添加selected这个类 $("#AllPinPai").find("a[pid="" + parentId + ""]").addClass("selected"); $(this).addClass("selected"); $("#chexin").css("display", "block"); $.post("@Url.Action("GetCheXingByCxId","Home")", { "cxid": $(this).attr("pid") }, function (data) { $("#AllCheXing").empty(); $("#chexingTemplate").tmpl(data).appendTo("#AllCheXing"); }); }); //给车系加上鼠标移去事件 $("#AllCheXi").on("mouseout", ".cxm", function () { $(this).removeClass("selected"); //取取当前车系的父类Id var parentId = $(this).attr("parentid"); //把品牌中该父类添加selected这个类 $("#AllPinPai").find("a[pid="" + parentId + ""]").removeClass("selected"); }); //车系点击事件 $("#AllCheXi").on("click", ".cxm", function () { $("#mychoice").val(""); //取取当前车系的父类Id var parentId = $(this).attr("parentid"); $("#mychoice").val($("#AllPinPai").find("a[pid="" + parentId + ""]").text() + "," + $(this).text()); hideMenu(); }); //给车型加上鼠标移上事件 $("#AllCheXing").on("mouseover", ".cxim", function () { //取出车型的父类id var parentId = $(this).attr("parentid"); //把车系中该父类添加selected这个类 $("#AllCheXi").find("a[pid="" + parentId + ""]").addClass("selected"); //取出车系的父类id var parentparentId = $("#AllCheXi").find("a[pid="" + parentId + ""]").attr("parentid"); //把品牌中该父类添加selected这个类 $("#AllPinPai").find("a[pid="" + parentparentId + ""]").addClass("selected"); }); //给车型加上鼠标移去事件 $("#AllCheXing").on("mouseout", ".cxim", function () { //取出车型的父类id var parentId = $(this).attr("parentid"); //把车系中该父类添加selected这个类 $("#AllCheXi").find("a[pid="" + parentId + ""]").removeClass("selected"); //取出车系的父类id var parentparentId = $("#AllCheXi").find("a[pid="" + parentId + ""]").attr("parentid"); //把品牌中该父类添加selected这个类 $("#AllPinPai").find("a[pid="" + parentparentId + ""]").removeClass("selected"); }); //车型点击事件 $("#AllCheXing").on("click", ".cxim", function () { $("#mychoice").val(""); //取出车型的父类id var parentId = $(this).attr("parentid"); //取出车系的父类id var parentparentId = $("#AllCheXi").find("a[pid="" + parentId + ""]").attr("parentid"); $("#mychoice").val($("#AllPinPai").find("a[pid="" + parentparentId + ""]").text() + "," + $("#AllCheXi").find("a[pid="" + parentId + ""]").text() + "," + $(this).text()); hideMenu(); }); }); //隐藏树并解除绑定 function hideMenu() { $("#carcategory-picker-outer").fadeOut("fast"); $("body").unbind("mousedown", onBodyDown); } //鼠标单击空白处事件 function onBodyDown(event) { if (!(event.target.id == "mychoice" || event.target.id == "carcategory-picker-outer" || $(event.target).parents("#carcategory-picker-outer").length > 0)) { hideMenu(); } } </script> <script id="pinpaiTemplate" type="text/x-jQuery-tmpl"> <dl> <dt id="${anchor}">${firstletter}</dt> {{if pinpais}} {{each pinpais}}<dd><a pid="${$value.Id}">${$value.Name}</a></dd>{{/each}} {{else}} <dd>没有此品牌</dd> {{/if}} </dl> </script> <script id="chexiTemplate" type="text/x-jQuery-tmpl"> <dl> <dd><a pid="${cxid}" parentid="${parentId}">${chexi}</a></dd> </dl> </script> <script id="chexingTemplate" type="text/x-jQuery-tmpl"> <dl> <dd><a pid="${chexingid}" parentid="${parentId}">${chexing}</a></dd> </dl> </script> }
css部分如下,关闭按钮可自找。
#carcategory-picker-outer { background: #f9f9f9; padding: 10px; width: 640px; height: 380px; position: relative; display: none; } #PreLetter { border: 0px solid blue; width: 21px; float: left; } #PreLetter a:link{ display: block; text-decoration: none; clear: both; font-size: 10px; text-align: center; padding-top: 0px; border: 1px solid #e3e3e3; width: 15px; height: 15px; background-color: #e9e9e9; margin-top: 2px; font-weight: bold; } #PreLetter a:hover { border: 1px solid blue; } #PreLetter a:visited { border: 1px solid #e3e3e3; } #pinpai { border: 0px solid green; float: left; } #AllPinPai { border: 1px solid #e3e3e3; margin-left: 5px; float: left; padding-bottom: 0px; width: 120px; height: 340px; overflow-y: auto; } #AllPinPai dl dd a { text-decoration: none; display: block; padding-left: 10px; } #AllPinPai dl dd { padding-left: 0px; } #AllPinPai dl dd a:hover { /*background-color: gray;*/ color: white; } #AllPinPai dl { margin-bottom: 5px; } #chexi { border: 0px solid orange; float: left; margin-left: 10px; display: none; } #AllCheXi { width: 150px; height: 340px; overflow-y: auto; border: 1px solid #e3e3e3; } #AllCheXi dl dd a { text-decoration: none; display: block; padding-left: 10px; } #AllCheXi dl dd { padding-left: 0px; } #AllCheXi dl dd a:hover { color: white; } #AllCheXi dl { margin-bottom: 5px; } #chexin { border: 0px solid red; float: left; margin-left: 10px; display: none; } #AllCheXing { width: 300px; height: 340px; overflow-y: auto; border: 1px solid #e3e3e3; } #AllCheXing dl dd a { text-decoration: none; display: block; padding-left: 10px; } #AllCheXing dl dd { padding-left: 0px; } #AllCheXing dl dd a:hover { background-color: gray; color: white; } #AllCheXing dl { margin-bottom: 5px; } dt { background-color: #e9e9e9; padding-left: 10px; } dl { border: 0px solid red; } dd { padding-left: 10px; line-height: 15px; margin-top: 5px; margin-bottom: 0px; border: 0px solid blue; /*background-color: gray;*/ } .selected { background-color: gray; color: white; } .cancel { width: 20px; height: 17px; position: absolute; display: block; top: 20px; right: 20px; background-image: url("../img/close.png"); border: 1px solid orangered; background-color: orangered; } .input-group { width: 640px; }
以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,谢谢大家对的支持。如果你想了解更多相关内容请查看下面相关链接
相关文章:
1. ASP.NET MVC前台动态添加文本框并在后台使用FormCollection接收值2. ASP.NET MVC通过勾选checkbox更改select的内容3. ASP.NET MVC使用JSAjaxFileUploader插件实现单文件上传4. ASP.NET MVC使用异步Action的方法5. ASP.NET MVC实现登录后跳转到原界面6. ASP.NET MVC使用Quartz.NET执行定时任务7. ASP.NET MVC把数据库中枚举项的数字转换成文字8. ASP.NET MVC增加一条记录同时添加N条集合属性所对应的个体9. ASP.NET MVC使用Log4Net记录异常日志并跳转到静态页10. ASP.NET MVC使用jQuery的Load方法加载静态页面及注意事项