搜索

查看: 3136|回复: 11

[ASP.NET] ASP.NET MVC实现城市或车型三级联动

[复制链接]
发表于 2023-5-4 11:33:28 | 显示全部楼层 |阅读模式
Editor 2023-5-4 11:33:28 3136 11 看全部
三级或多级联动的场景经常会碰到,比如省、市、区,比如品牌、车系、车型,比如类别的多级联动......我们首先想到的是用三个select来展示,这是最通常的做法。但在另外一些场景中,比如确定搜索条件的时候,对于三级联动来说,可能选择1个,2个,或3个条件,我想,以下的方式可能更适合:

20229183539371.png

20229183539371.png


以上,可以只选择品牌,或同时选择品牌、车系,或同时选择品牌、车系、车型,最后把选择的内容展示到input上,并以逗号隔开。

20229183539372.png

20229183539372.png


可以实现的功能包括:
  • 点击最上面的input弹出div,此时只显示品牌区域
  • 点击最左边拼音首字母,导航到对应的品牌上
  • 当把鼠标移动到某个品牌上,品牌为选中状态,其对应的车系显示在车系区域
  • 当鼠标不在任何品牌上,所有品牌都为不选中状态
  • 当把鼠标移动到某个车系上,车系为选中状态,其对应的车型显示在车型区域,选中车系的所属品牌也为选中状态
  • 当鼠标不在任何车系上,所有车系、品牌都为不选中状态
  • 当把鼠标移动到某个车型上,车型为选中状态,选中车型的所属车系为选中状态,选中车系所属品牌为选中状态
  • 当鼠标不在任何车型上,所有车型、车系、品牌为不选中状态
  • 点击品牌,品牌显示到input上
  • 点击车系,品牌、车系显示到input上,并以逗号隔开
  • 点击车型,品牌、车系、车型显示到input上,并以逗号隔开
  • 点击div上的关闭按钮或者页面空白区域,div隐藏
    界面的构成如下:

    20229183539373.png

    20229183539373.png


  • 最上面的是一个input
  • 品牌、车系、车型被包裹在一个div中,点击关闭按钮或点击空白处关闭的就是这个div
  • 品牌区域是一个div,分为首字母导航div和品牌显示div
  • 车系区域是一个div
  • 车型区域是一个div
  • 品牌、车系、车型内的内容是一些dl, dt, dd的html元素
  • 样式的事情交给css
    实现的思路大致这样:
  • 给input点击事件,点击弹出品牌、车系、车型显示的div,并绑定页面空白区域的点击事件
  • 导航首字母指向锚点,品牌按首字母分类并提供锚点id
  • 在控制器中把品牌按照首字母分类,以json格式返回到前端,填充到tmpl模版,再追加到页面品牌区域
  • 给品牌添加鼠标移上事件,品牌为选中状态,对应的车系显示在车系区域
  • 给品牌添加鼠标移去事件
  • 给品牌添加点击事件,把点击品牌显示到input上
  • 给车系添加鼠标移上事件,当前车系为选中状态,其对应的车型显示在车型区域,其所属的品牌为选中状态
  • 给车系添加鼠标移去事件
  • 给车系添加点击事件,把点击车系和所属品牌显示到input上,以逗号隔开
  • 给车型添加鼠标移上事件,当前车型为选择状态,其所属父类车系为选中状态,车型所属父类品牌也为选中状态
  • 给车型添加点击事件,把点击车型和所属车系、品牌显示到input上,以逗号隔开
  • 给关闭按钮添加点击事件,关闭div,并解除页面空白区域点击事件的绑定
    领域先行,首先是有关品牌、车系、车型的模型:
        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; }
        }
  • PId属性用来表示父类Id,车系的父类Id为某个品牌Id,车型的父类Id为某个车系Id
  • FirstLetter属性用来表示首字母,作为分组的条件
  • AnchorName属性用来表示品牌的锚点id,车系和车型此项为空
    在ASP.NET MVC4中,在Shared/Layout.cshtml中,该有的css,js都必须有:

       
       
        @ViewBag.Title
        @Styles.Render("~/Content/css")
        @RenderSection("styles", required: false)
       
        @Scripts.Render("~/bundles/jquery")
       

        @RenderBody()
       
        @RenderSection("scripts", required: false)

    模拟一个数据库,该数据库类可以获取到所有的品牌、车系、车型,以及根据品牌Id或车系Id获取对应的车系和车型。
       public class Database
        {
            public static IEnumerable GetCarCategories()
            {
                return new List()
                {
                     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 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
    {
       
    }
       
       
            
       

        [/url]
       
            
                请选择品牌
                
                    [url=#aa]A

                    B
                    C
                    D
                    F
                    G
                    H
                    J
                    K
                    L
                    M
                    N
                    O
                    Q
                    R
                    S
                    W
                    X
                    Y
                    Z
                
                
                
            
            
                请选择车系
                
               
                
            
            
                请选择车型
                
                   
                
            
       
    @section scripts
    {
       
       
       
       
       
       
       
       
    }
    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;
    }
    以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,谢谢大家对知鸟论坛的支持。如果你想了解更多相关内容请查看下面相关链接
  • 回复

    使用道具 举报

    发表于 2023-6-28 19:36:05 | 显示全部楼层
    贺老师 2023-6-28 19:36:05 看全部
    我看不错噢 谢谢楼主!知鸟论坛越来越好!
    回复

    使用道具 举报

    发表于 2023-6-30 02:29:17 | 显示全部楼层
    123456833 2023-6-30 02:29:17 看全部
    楼主发贴辛苦了,谢谢楼主分享!我觉得知鸟论坛是注册对了!
    回复

    使用道具 举报

    发表于 2023-6-30 02:46:03 | 显示全部楼层
    贰十岁装成熟装s 2023-6-30 02:46:03 看全部
    这东西我收了!谢谢楼主!知鸟论坛真好!
    回复

    使用道具 举报

    发表于 2023-6-30 03:35:15 | 显示全部楼层
    井底燕雀傥 2023-6-30 03:35:15 看全部
    楼主,我太崇拜你了!我想我是一天也不能离开知鸟论坛
    回复

    使用道具 举报

    发表于 2023-7-4 00:16:45 | 显示全部楼层
    丁侦球 2023-7-4 00:16:45 看全部
    论坛不能没有像楼主这样的人才啊!我会一直支持知鸟论坛
    回复

    使用道具 举报

    发表于 2023-7-5 03:27:15 | 显示全部楼层
    dxf17 2023-7-5 03:27:15 看全部
    楼主,我太崇拜你了!我想我是一天也不能离开知鸟论坛
    回复

    使用道具 举报

    发表于 2023-7-5 14:35:43 | 显示全部楼层
    哈哈SE7 2023-7-5 14:35:43 看全部
    楼主太厉害了!楼主,I*老*虎*U!我觉得知鸟论坛真是个好地方!
    回复

    使用道具 举报

    发表于 2023-7-6 09:29:37 | 显示全部楼层
    我是的十八簿 2023-7-6 09:29:37 看全部
    楼主,大恩不言谢了!知鸟论坛是最棒的!
    回复

    使用道具 举报

    发表于 2023-7-6 14:16:20 | 显示全部楼层
    伊索谗言 2023-7-6 14:16:20 看全部
    这东西我收了!谢谢楼主!知鸟论坛真好!
    回复

    使用道具 举报

    • 您可能感兴趣
    点击右侧快捷回复 【请勿灌水】
    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则 返回列表

    RSS订阅| SiteMap| 小黑屋| 知鸟论坛
    联系邮箱E-mail:zniao@foxmail.com
    快速回复 返回顶部 返回列表