ASP.NET MVC无限级联异步下拉框(select)控件

前段时间参与一个公司的项目,使用ASP.NET MVC 3.0,其中有多处使用了级联下拉。

考虑到这种ajax异步调用代码重复且不方便调试,于是做了一个公用控件,实际是一个.NET MVC的PartialView。

PartialView:

SelectView.cshtml
@model Platform.Modules.Base.ViewModels.SelectViewModel
<select id="@Model.Id" name="@Model.Name" class="@Model.Class" style="@Model.Style"><option value='@Model.DefaultValue'>@Model.DefaultText</option></select>
<script type="text/javascript">
    $(function () {
        var actionUrl = '@Model.ActionUrl';
    var unselected = "<option value='@Model.DefaultValue'>@Model.DefaultText</option>";
    var tagId,textProperty,valueProperty,parentTagId,paramName,currentSelectedValue,requestMethod;
        tagId = '@Model.Id';
        textProperty='@Model.TextProperty';
        valueProperty='@Model.ValueProperty';
        parentTagId='@Model.ParentTagId';
        paramName='@Model.ParamName';
        currentSelectedValue='@Model.SelectedValue';
        requestMethod='@Model.RequestMethod.ToString()';
        @{if(String.IsNullOrEmpty(Model.ParentTagId)){
            <text>
                $.ajax({
                type: requestMethod,
                url: actionUrl+"?ts="+new Date().getTime(),
                cache:false,
                success: function(data){
                $("#" + tagId).empty();
                $("#" + tagId).append(unselected);
                $.each(data, function (i, item) {
                    if($(item).attr(valueProperty)==currentSelectedValue){
                        $("#" + tagId).append($("<option selected='selected' value='" + $(item).attr(valueProperty) + "'>" + $(item).attr(textProperty) + "</option>"));                    
                    }else{
                        $("#" + tagId).append($("<option value='" + $(item).attr(valueProperty) + "'>" + $(item).attr(textProperty) + "</option>"));
                    }
                });
            },
            complete:function()
            {
                if(currentSelectedValue!=null){
                    if($('#'+tagId).fireEvent)   
                        $('#'+tagId).fireEvent("onchange");
                    else   
                        $('#'+tagId).change();
                }
            }
            });
            </text>
        }else{
            <text>
            $("#" + parentTagId).change(function () {
                $('#'+tagId).empty();
                $('#'+tagId).append(unselected);

                if($('#'+tagId).fireEvent)   
                    $('#'+tagId).fireEvent("onchange");
                else   
                    $('#'+tagId).change();

                var parentValue = $(this).val();
                if (!parentValue) {
                    return;
                }

                $.ajax({
                type: requestMethod,
                url: actionUrl+"?ts="+new Date().getTime(),
                data: paramName+"=" + parentValue,
                cache:false,
                success: function(data){    
                    $.each(data, function (i, item) {
                        if($(item).attr(valueProperty)==currentSelectedValue){
                            $("#" + tagId).append($("<option selected='selected' value='" + $(item).attr(valueProperty) + "'>" + $(item).attr(textProperty) + "</option>"));                            
                        }else{
                            $("#" + tagId).append($("<option value='" + $(item).attr(valueProperty) + "'>" + $(item).attr(textProperty) + "</option>"));
                        }
                    });
                },
                complete:function()
                {
                    if(currentSelectedValue!=null){
                        if($('#'+tagId).fireEvent)   
                            $('#'+tagId).fireEvent("onchange");
                        else   
                            $('#'+tagId).change();
                    }
                }
            });
            });
            
            </text>
        }
        }
    });
</script>

 

该控件使用到的Model类:

SelectViewModel.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web.Mvc;

namespace Platform.Modules.Base.ViewModels
{
    public class SelectViewModel
    {
        /// <summary>
        /// select标签Id
        /// </summary>
        public String Id { get; set; }

        /// <summary>
        /// select标签Name
        /// </summary>
        public String Name { get; set; }

        /// <summary>
        /// json数据源元素中代表select>option>Text的属性
        /// </summary>
        public String TextProperty { get; set; }
        
        /// <summary>
        /// json数据源元素中代表select>option>value的属性
        /// </summary>
        public String ValueProperty { get; set; }
        /// <summary>
        /// 数据源获取地址
        /// </summary>
        public String ActionUrl { get; set; }

        /// <summary>
        /// select标签初始项文本,默认为空字符串
        /// </summary>
        public String DefaultText { get; set; }

        /// <summary>
        /// select标签初始项值,默认为空字符串
        /// </summary>
        public String DefaultValue{ get; set; }
        
        /// <summary>
        /// 获取数据时传递的参数名
        /// </summary>
        public String ParamName { get; set; }

        /// <summary>
        /// 父级下拉框的标签id
        /// 有父级必选
        /// </summary>
        public String ParentTagId { get; set; }

        /// <summary>
        /// 样式表
        /// </summary>
        public String Class { get; set; }

        /// <summary>
        /// 样式
        /// </summary>
        public String Style { get; set; }

        /// <summary>
        /// select标签当前选定项
        /// </summary>
        public String SelectedValue { get; set; }

        private FormMethod requestMethod = FormMethod.Get;

        /// <summary>
        /// 请求方式
        /// 默认为GET
        /// </summary>
        public FormMethod RequestMethod
        {
            get { return requestMethod; }
            set { requestMethod = value; }
        }
    }

}

 

Demo:

Ajax回调的Action
        public ActionResult GetProvinces()
        {
            var entities = locationService.GetProvinceList();
            return Json(entities, JsonRequestBehavior.AllowGet);
        }

        public ActionResult GetCities(String provinceCode)
        {
            var entities = locationService.GetCityList(new CityQuery() { ProvinceCode = provinceCode });
            return Json(entities, JsonRequestBehavior.AllowGet);
        }

        public ActionResult GetCounties(String cityCode)
        {
            var entities = locationService.GetCountyList(new CountyQuery() { CityCode = cityCode });
            return Json(entities, JsonRequestBehavior.AllowGet);
        }

        /// <summary>
        /// 测试页Action
        /// </summary>
        /// <returns></returns>
        public ActionResult SelectControlTest()
        {
            return View();
        }

 

测试页面(省市县三级联动)
@{
    ViewBag.Title = "SelectControlTest";
}
@using Platform.Modules.Base.ViewModels
<h2>SelectControlTest</h2>
            省:@{Html.RenderPartial("SelectView", new SelectViewModel()
              {
                  ActionUrl = Url.Action("GetProvinces", "Location"),
                  DefaultText = "---请选择---",
                  DefaultValue = "",
                  Id = "aaaaa",
                  Name = "aaaaa",
                  TextProperty = "Name",
                  ValueProperty = "Code",
                  Style = "width:173px",
              });}
              市:@{Html.RenderPartial("SelectView",new SelectViewModel(){
                    ActionUrl = Url.Action("GetCities", "Location"),
              DefaultText="---请选择---",
              DefaultValue="",
              Id="bbbbbb",
              ParentTagId="aaaaa",
              ParamName = "provinceCode",
              Name="bbbbbb",
              TextProperty="Name",
              ValueProperty = "Code",
              Style = "width:173px"
              });}
              县:@{Html.RenderPartial("SelectView",new SelectViewModel(){
                    ActionUrl = Url.Action("GetCounties", "Location"),
              DefaultText="---请选择---",
              DefaultValue="",
              Id="cccccc",
              ParamName = "cityCode",
              ParentTagId="bbbbbb",
              Name="cccccc",
              TextProperty="Name",
              ValueProperty="Code",
              Style = "width:173px"
              });}

 

理论上支持无限级联。。

支持Post,Get两种请求方式。默认使用Get方式。

注意:使用Get方式请求Action,返回JSON的时候一定要加JsonRequestBehavior.AllowGet。

posted @ 2013-03-05 15:46  无色无味  阅读(2558)  评论(8编辑  收藏  举报