MVC三层级联方式(ListBox)

三层级联方式,比如常见的乘法口诀表,这里使用ListBox,因为需要同时多选。

 

[Get]

[Post]后,保存当时选择的效果,同时为防止页面显示的效果和浏览器中的参数不一致,所以Post后同时回到HttpGet

 

分析:

采用三个ListBox,分别为L1L2L3

 

操作1L1选择后,需要在L2中显示对应的可选结果,并且L1可多选,在L2 中显示的结果中需要去重复。

比如:

(1)L1选中6,那么在L2中需要显示6789

(2)L1选中67,那么在L2中需要显示6789789,考虑到去重复,那么在 L2中应该显示6789

 

操作2:在L1选择后,可以从L2中显示的选项中进行选择,同样L2中可以同时选择多项。L2选择之后,L3中显示相应的内容,这里的L3显示的内容有L1L2同时决 定而不是仅仅有L2决定。

比如:

(1)L1选中67,那么L2中显示的内容能够有6789,这里选择789三项,在 L3显示的内容应该是由(67),(68),(69) 77),(78),(79 取得,这里的结果是424854495663(这里也需要考虑去重复,当然这 里没有重复)。同样在L3中也可以多选。

 

点击Gosubmit按钮,提交数据,要显示提交的内容。

 

 

实现:

HomeController  和 Index Action 以及Index.cshtml

1)模拟一个数据表,该表中存储的乘法表中所有内容

 

public class DbRecord
        {
            public int Id { get; set; }
            public string ValueFirst { get; set; }
            public string ValueSecord { get; set; }
            public string ValueThird { get; set; }
        }
        public List<DbRecord> DbRecords;

        public HomeController()
        {
            this.DbRecords = new List<DbRecord>();
            int index = 1;
            for (int i = 1; i <= 9; i++)
            {
                for (int j = i; j <= 9; j++)
                {
                    DbRecord dbItem = new DbRecord();
                    dbItem.Id = index;
                    dbItem.ValueFirst = i.ToString();
                    dbItem.ValueSecord = j.ToString();
                    dbItem.ValueThird = (i * j).ToString();
                    index++;
                    this.DbRecords.Add(dbItem);
                }
            }

        }

  

2)初始化ListBoxL1L2L3)  ListBoxGetInit()

  

      public class Item

        {

            public int Id { get; set; }

            public string Value { get; set; }

        }

 

        public ActionResult ListBoxGetInit()

        {

            List<Item> list = new List<Item>();

            var L1 = (from temp 

                      in this.DbRecords 

                      select temp.ValueFirst).Distinct().ToList();

 

            for (int i = 0; i < L1.Count(); i++)

                list.Add(new Item { Id = i, Value = L1[i] });

            List<Item> list1 = new List<Item>();

            ViewBag.L1 = new MultiSelectList(list, "Value", "Value");

            ViewBag.L2 = new MultiSelectList(list1, "Value", "Value");

            ViewBag.L3 = new MultiSelectList(list1, "Value", "Value");

 

            return null;

        }

  

 

(3)处理Post的数据,并且保存Post的内容,显示在ListBox中。

PostInit()用在具体的Action [HttpPost]中调用,将表单中提交的内容拼成字符串,发送给对应的Action[HttpGet].

       public ActionResult PostInit(FormCollection values,string actionName)

        {

            string joinString = null;

            for (int i = 0; i < values.Count; i++)

            {

                joinString += values.Keys[i] + "=" + values[i] + "&";

            }

 

            return RedirectToAction(actionName, new { post = joinString });

        }

 

  

           


ListBoxPostInit在具体的Action[HttpGet]中调用,将之前PostInit()传递过来的参数进行处理,显示上次提交的值,并且L1显示所有可选的值,可以再次重新选择。

        

public ActionResult ListBoxPostInit(string post)

        {

            List<Item> list = new List<Item>();

            var L1 = (from temp 

                          in this.DbRecords 

                          select temp.ValueFirst

                      ).Distinct().ToList();

            for (int i = 0; i < L1.Count(); i++)

                list.Add(new Item { Id = i, Value = L1[i] });

 

            List<PostName> input = ParseParam(post);

 

            foreach (var item in input)

            {

                switch (item.Name)

                {

                    case "L1": ViewBag.L1 = 

                        new MultiSelectList(

                            list

                            , "Value"

                            , "Value"

                            ,item.Value.Split(',')

                            );break;

                    case "L2": ViewBag.L2 = 

                        new MultiSelectList(

                            ParseItem(item.Value)

                            , "Value"

                            , "Value"); break;

                    case "L3": ViewBag.L3 = 

                        new MultiSelectList(

                            ParseItem(item.Value)

                            , "Value"

                            , "Value"); break;

                    default: break;

                }

            }

  

 

 

        


ParseItem 已经拼成字符串的参数中的Value值,还原成List<Item>

       

 public static List<Item> ParseItem(string param)

        {

            List<Item> list = new List<Item>();

            List<string> stringTemp = param.Split(',').ToList();

            for (int i = 0; i < stringTemp.Count(); i++)

            {

                list.Add(new Item { Id = i, Value = stringTemp[i] });

            }

            return list;

        }

        public class PostName

        {

            public string Name { get; set; }

            public string Value { get; set; }

        }

  

ParseParam将已经拼成字符串的参数转换成NameValue一一对应。

        public static List<PostName> ParseParam(string param)

        {

            List<PostName> results = new List<PostName>();

            string input = System.Web.HttpUtility.UrlDecode(param);

            if (input == null)

                return results;

            string[] inputSplit = input.Split('&');

            for (int i = 0; i < inputSplit.Length; i++)

            {

                string[] arr = inputSplit[i].Split('=');

                if (arr.Length == 2)

                {

                    PostName pn = new PostName

                    {

                        Name = arr[0],

                        Value = arr[1]

                    };

                    results.Add(pn);

                }

            }

            return results;

        }

 

  


(3)Json  GetList(string id) 和 GetListCombine(string id1, string id2)

 

     

   public JsonResult GetList(string id)

        {

            string[] stringSplit1 = null;

 

            if (id != null)

            {

                stringSplit1 = id.Split(',');

            }

            

            List<string> listString = new List<string>();

            List<Item> list = new List<Item>();

 

            listString = (from temp 

                              in this.DbRecords 

                              where (stringSplit1.Contains(temp.ValueFirst)) 

                              select temp.ValueSecord

                              ).Distinct().ToList();

 

            for (int i = 0; i < listString.Count(); i++)

            {

                list.Add(new Item { Id = i, Value = listString[i] });

            }

            var d = list;

            return Json(d, JsonRequestBehavior.AllowGet);

        }

 

 

        


         public JsonResult GetListCombine(string id1, string id2)

        {

            string[] stringSplit1 = null;

            string[] stringSplit2 = null;

 

            if (id1 != null)

            {

                stringSplit1 = id1.Split(',');

            }

 

            if (id2 != null)

            {

                stringSplit2 = id2.Split(',');

            }

 

            List<string> listString = new List<string>();

            List<Item> list = new List<Item>();

 

            listString = (from temp 

                              in this.DbRecords 

                              where (stringSplit1.Contains(temp.ValueFirst)

                                        &&stringSplit2.Contains(temp.ValueSecord) ) 

                              select temp.ValueThird

                              ).Distinct().ToList();

 

            for (int i = 0; i < listString.Count(); i++)

            {

                list.Add(new Item { Id = i, Value = listString[i] });

            }

 

            var d = list;

            return Json(d, JsonRequestBehavior.AllowGet);

        }

  

 


前台ListBox定义和JQ

 

@{
    ViewBag.Title = "Index";
}

<h2>乘法口诀表</h2>
@using (Html.BeginForm())
{
    <table>
        <tr>
            <td>
                @Html.ListBox("L1", null, new { @class = "edit" ,onchange = "GetList(this)", @style = "height:200px;200px" })
            </td>
            <td>*</td>
            <td>
                @Html.ListBox("L2", null, new { @class = "edit", onchange = "GetListCombine(this)", @style = "height:200px;200px" })
            </td>
            <td>=</td>
            <td>
                @Html.ListBox("L3", null, new { @class = "edit", @style = "height:200px;200px" })
            </td>
        </tr>
    </table>
    <input type="submit" value="Go" />
}


<script type="text/javascript">
    function GetList(id) {
        $("#L2").empty(); //清空
        $("#L3").empty(); //清空
        $.ajax({
            url: '/Home/GetList/' + $("#L1").val(),
            type: "get",
            datatype: "json",
            success: function (data) {
                if (data.length == 0) {
                    $("<option></option>")
                    .val("0")
                    .text("请选择...")
                    .appendTo($("#L2"));
                }
                $.each(data, function (i, item) {
                    $("<option></option>")
                    .val(item["Value"])
                    .text(item["Value"])
                    .appendTo($("#L2"));
                });
            }
        });
    }
</script>



<script type="text/javascript">
    function GetListCombine(id1,id2) {
        $("#L3").empty(); //清空
        $.ajax({
            url: '/Home/GetListCombine/?' +'id1='+ $("#L1").val()+'&id2='+$("#L2").val(),
            type: "get",
            datatype: "json",
            success: function (data) {
                if (data.length == 0) {
                    $("<option></option>")
                    .val("0")
                    .text("请选择...")
                    .appendTo($("#L3"));
                }
                $.each(data, function (i, item) {
                    $("<option></option>")
                    .val(item["Value"])
                    .text(item["Value"])
                    .appendTo($("#L3"));
                });
            }
        });
    }
</script>

 

  

 

 


Action的代码

 

       public ActionResult Index(string post)

        {

            if (post == null)

            {

                ListBoxGetInit();

            }

            else

            {

                ListBoxPostInit(post);

            }

 

            return View();

        }

 

        [HttpPost]

        public ActionResult Index(FormCollection values)

        {

            return PostInit(values, "Index");

        }

  

补充:

(1)为了在Post之后可以在之前Post的结果中继续选择选项,而不是上面Post的结果中只是显示了上次Post的参数。

(2)处理特殊的数据,比如空,这里我们的null使用(EMPTY)表示,保证数据的完整新。

比如

(1)中的结果如下

[Get]

[Post]

(2)中的结果如下,含有null的处理

[Get]

[Post]

代码修改如下:

定义新的变量EMPTY保存现在null的显示方式。

public const string EMPTY = "(EMPTY)";

在HomeController中增加几条测试数据,因为需要null的记录。

//add three special case
            this.DbRecords.Add(new DbRecord 
                            { Id = index
                                , ValueFirst = null
                                , ValueSecord = "10"
                                , ValueThird = "100" 
                            });
            index++;
            this.DbRecords.Add(new DbRecord 
                            { Id = index
                                , ValueFirst = null
                                , ValueSecord = null
                                , ValueThird = "1000" 
                            });
            index++;
            this.DbRecords.Add(new DbRecord 
                            { Id = index
                                , ValueFirst = "9"
                                , ValueSecord = "10"
                                , ValueThird = null 
                            });

  

增加处理null的方法,HandleEmpty(),将(EMPTY)转成null,用于GetList()和GetListCombine()中的查询。

        public void HandleEmpty(string[] input)
        {
                for (int i = 0; i < input.Length; i++)
                {
                    if (input[i] == EMPTY)
                        input[i] = null;
                }
                   
        }

  

需要将Json,GetList()和GetListCombine()拆开,因为要多次获取List<Item>,并且需要特殊处理null。

 public JsonResult GetList(string id)
        {
            
            var d = this.GetListItem(id);
            return Json(d, JsonRequestBehavior.AllowGet);
        }

        public List<Item> GetListItem(string id)
        {
            string[] stringSplit1 = null;

            if (id != null)
            {
                stringSplit1 = id.Split(',');
                HandleEmpty(stringSplit1);
            }

            List<string> listString = new List<string>();
            List<Item> list = new List<Item>();

            listString = (from temp
                              in this.DbRecords
                          where (stringSplit1.Contains(temp.ValueFirst))
                          select temp.ValueSecord
                              ).Distinct().ToList();

            for (int i = 0; i < listString.Count(); i++)
            {
                if (listString[i] != null)
                {
                    list.Add(new Item { Id = i, Value = listString[i] });
                }
                else
                {
                    list.Add(new Item { Id = i, Value = EMPTY });
                }
            }
            return list;
        }

拆开GetListConbine()

        public JsonResult GetListCombine(string id1, string id2)
        {

            var d = GetListCombineItem(id1, id2);
            return Json(d, JsonRequestBehavior.AllowGet);
        }

        public List<Item> GetListCombineItem(string id1, string id2)
        {
            string[] stringSplit1 = null;
            string[] stringSplit2 = null;

            if (id1 != null)
            {
                stringSplit1 = id1.Split(',');
                HandleEmpty(stringSplit1);
            }

            if (id2 != null)
            {
                stringSplit2 = id2.Split(',');
                HandleEmpty(stringSplit2);
            }

            List<string> listString = new List<string>();
            List<Item> list = new List<Item>();

            listString = (from temp
                              in this.DbRecords
                          where (stringSplit1.Contains(temp.ValueFirst)
                                    && stringSplit2.Contains(temp.ValueSecord))
                          select temp.ValueThird
                              ).Distinct().ToList();

            for (int i = 0; i < listString.Count(); i++)
            {
                if (listString[i] != null)
                {
                    list.Add(new Item { Id = i, Value = listString[i] });
                }
                else
                {
                    list.Add(new Item { Id = i, Value = EMPTY });
                }
            }
            return list;

        }

  

修改ListBoxGetInit()方法中初始化L1的部分代码,将for (int i = 0; i < L1.Count(); i++) 函数体修改即可

            for (int i = 0; i < L1.Count(); i++)
            {
                if (L1[i] != null)
                {
                    list.Add(new Item { Id = i, Value = L1[i] });
                }
                else
                {
                    list.Add(new Item { Id = i, Value = EMPTY });
                }
            }

  

修改ListBoxPostInit(),保存上次Post默认选择的结果如下:

        public ActionResult ListBoxPostInit(string post)
        {
            List<Item> list = new List<Item>();
            var L1 = (from temp
                          in this.DbRecords
                      select temp.ValueFirst
                      ).Distinct().ToList();
            for (int i = 0; i < L1.Count(); i++)
            {
                if (L1[i] != null)
                {
                    list.Add(new Item { Id = i, Value = L1[i] });
                }
                else
                {
                    list.Add(new Item { Id = i, Value = EMPTY });
                }
            }

            List<PostName> input = ParseParam(post);
            string idL1 = null;
            string idL2 = null;
            foreach (var item in input)
            {
                switch (item.Name.ToUpper())
                {
                    case "L1": ViewBag.L1 =
                        new MultiSelectList(
                            list
                            , "Value"
                            , "Value"
                            , item.Value.Split(',')
                            ); 
                            idL1=item.Value;
                            break;
                    case "L2": ViewBag.L2 =
                        new MultiSelectList(
                            GetListItem(idL1)
                            , "Value"
                            , "Value"
                            ,item.Value.Split(',')
                            );
                            idL2=item.Value; 
                            break;
                    case "L3": ViewBag.L3 =
                        new MultiSelectList(
                            GetListCombineItem(idL1,idL2)
                            , "Value"
                            , "Value"
                            ,item.Value.Split(',')
                            ); break;
                    default: break;
                }
            }
            return null;
        }

  

 

原文地址:https://www.cnblogs.com/chinazhoumin/p/4102659.html