MVC 4表单中的动态DropDownLists

时间:2015-04-24 16:29:21

标签: javascript c# ajax asp.net-mvc

我的最终目标是能够在一个DropDownList中选择一个值,并且在进行了该选择之后,我希望根据在第一个中进行的选择来填充另一个DropDownList。我的表单应该有一个DropDownList,其中包含所有省份的省份列表和一个满是城市的DropDownList。

我是ASP MVC的新手,所以我不确定如何实现。如果必须在Winforms或WPF中完成,我将能够实现它,因为我知道数据是如何从我的业务逻辑传播到显示给用户的控件 - 但是在MVC中,我不知道如何做到这一点正确有效。我也在学习javascript和相关助手(例如jQuery),所以我需要一些帮助来使用像ajax这样的东西来实现我的目标。

以下是我已经拥有的以及我应该达到的目标:

我的模型(捕获用户的输入):

    public class CaptureCreateTrip
    {
        [Required]
        [Display(Name = "Trip ID")]
        public string TripID { get; set; }

        [Required]
        public string StartPointProvince { get; set; }

        [Required]
        public string StartPointCity { get; set; }

        [Required]
        public string EndPointProvince { get; set; }

        [Required]
        public string EndPointCity { get; set; }
    }

我的表格:

请记住,我刚刚插入ViewBag引用作为占位符,直到我可以用动态数据替换它。

@using (Html.BeginForm("CreateOneWayTrip", "Trips"))
        {
            @Html.ValidationSummary(false);
            <fieldset>
                <legend>Enter Your Trip Details</legend>

                <label>Start Point</label>
                @Html.DropDownListFor(m => m.StartPointProvince, (SelectList)ViewBag.Provinces);
                @Html.DropDownListFor(m => m.StartPointCity, (SelectList)ViewBag.Cities);

                <label>End Point</label>
                @Html.DropDownListFor(m => m.EndPointProvince, (SelectList)ViewBag.Provinces);
                @Html.DropDownListFor(m => m.EndPointCity, (SelectList)ViewBag.Cities);

                <p style="float: none; text-align: center;">
                    <button type="submit" value="Create" class="btn btn-info btn-circle btn-lg">
                        <i class="fa fa-check"></i>
                    </button>

                    <button type="submit" value="Create" class="btn btn-warning btn-circle btn-lg">
                        <i class="fa fa-times"></i>
                    </button>
                </p>
            </fieldset>
        }

控制器:

        //To Show Create Page
        public ActionResult Create()
        {
            return View();
        }

        // To Get Data after post
        [HttpPost]
        public ActionResult Create(Models.CaptureCreateTrip trip)
        {
            Models.CaptureCreateTrip t = trip;

            return Redirect("~/Trips/Index");
        }

        //Will I need a controller to get json data?

此外,我必须在我的页面中包含哪些javascript(1)在下拉列表中选择更改事件触发事件,以及(2)获取适当的数据(所选省份的城市列表)。

更新:

以下是生成的页面源代码段:

<select Id="province_dll" class="form-control" data-val="true" data-val-required="The StartPointProvince field is required." id="StartPointProvince" name="StartPointProvince"><option value="NC">Northern Cape</option>
<option value="FS">Free State</option>
<option value="WC">Western Cape</option>
</select>
                <select Id="city_dll" class="form-control" data-val="true" data-val-required="The StartPointCity field is required." id="StartPointCity" name="StartPointCity"><option value="NC">Kimberley</option>
<option value="FS">Boshof</option>
<option value="WC">Barkley</option>
</select>

这是我写的javascript:

$("province_dll").change(function () {
        $.ajax({
            url: 'getCities/Trips',
            type: 'post',
            data: {
                provinceId: $("province_dll").val()
            }
        }).done(function (response) {
            $("cities_dll").html(response);
        });
    });

这是我的控制器(ps。数据只是测试数据,稍后将与db连接):

    [HttpPost]
    public ActionResult getCicites(int provinceId)
    {
        var lstCities = new SelectList(new[] { "City1", "City2", "City3" });

        return Content(String.Join("", lstCities));
    }

然而它仍然无效 - 当我在第一个DropDownList中选择不同的值时,没有任何反应。

2 个答案:

答案 0 :(得分:2)

您应该在省ddl的change事件中创建一个ajax调用。 此呼叫将请求某个操作并返回所选省份的城市。

$("province_dll").change(function(){
    $.ajax({
         url: 'getCitiesController/getCitiesAction',
         type: 'post',
         data: {
               provinceId: provinceIdVar
         }
    }).done(function(response){
         $("cities_dll").html(response);
    }); 
});

在行动中:

[HttpPost]
public ActionResult getCicitesAction(int provinceId)
{
     var cities = db.cities.Where(a => a.provinceId == provinceId).Select(a => "<option value='" + a.cityId + "'>" + a.cityName + "'</option>'";

     return Content(String.Join("", cities));
}

答案 1 :(得分:0)

所以我假设第一个下拉列表按原样在ViewBag中传递,但是第二个下拉列表需要根据第一个列表中选择的任何项目进行填充。这是对的吗?

基本上,这相当于从dropbox1选择的视图进行AJAX调用,从控制器中的JsonResult操作中获取返回的数据,并从中构建第二个下拉列表。

通过点点连接,您可能会发现the following post提供了您需要的大部分内容。

从那篇文章:

查看:

<script type="text/javascript">
$('body').on('change', '.combo', function () {
   var selectedValue = $(this).val();
   alert(selectedValue);
   $.get("/Home/getcity", { country: selectedValue }, function (data) {
       $("#tese").html(data);
       $(".combo2").html("<option value = \"\"></option>")
       $.each(data, function (index, value) {
          $(".combo2").append("<option value = \"" + value + "\">" + value + "</option>");
       });
       $(".combo2").html()
   });
});
</script>

和控制器:

public JsonResult getCity(string country)
{
    var temp = (from cntry in db.Table3.OrderBy(s => s.country)
                where (string.Compare(cntry.country, country) == 0)
                select cntry.city).ToList();
    return Json(temp, JsonRequestBehavior.AllowGet);
}

当然,示例稍有不同,但一般方法是相同的:找到所选值并发出AJAX请求;使用Linq,获取第二个选择列表的必要数据;将结果返回给Json对象中的视图。