具有动态下拉列表的MVC编辑表单 - 如何设置初始值

时间:2017-09-23 19:41:48

标签: c# jquery asp.net asp.net-mvc asp.net-mvc-4

我正在使用MVC,C#和Entity Framework。 我模型上的对象是:

-------- Id,姓名

城市 ------- Id,Name,StateId

TheObject ---- Id,Name,StateId,CityId

我想为 TheObject 创建一个编辑表单。 编辑表单有2个动态创建的下拉列表州和城市,城市列表取决于在州列表上进行的选择。 问题是下拉列表已正确填充,但是当编辑表单打开时,这两个下拉列表处于空状态,并且没有为已编辑的对象选择实际值。

编辑视图的部分代码是:

<div class="form-group">
        @Html.LabelFor(u => u.State, new { @class = "control-label col-md-2" })
        <div class="col-md-10">
            @Html.DropDownListFor(u => u.State,
          new SelectList(ViewBag.State, "Id", "Name"),
          "Choose State",
          new { @class = "form-control", @onchange = "selectCities()" })
            @Html.ValidationMessageFor(u => u.State, "", new { @class = "text-danger" })
        </div>
    </div>

    <div class="form-group">
        @Html.LabelFor(u => u.City, new { @class = "control-label col-md-2" })
        <div class="col-md-10">
            @Html.DropDownListFor(u => u.City,
   new SelectList(Enumerable.Empty<SelectListItem>(), "Id", "Name"),
          "Choose City",
          new { @class = "form-control" })
            @Html.ValidationMessageFor(u => u.City, "", new { @class = "text-danger" })
        </div>
    </div>

function selectCities() {
    debugger;
    var stateId = $("#State").val();
    $.ajax({
        url: '/Home/selectCities',
        type: 'POST',
        datatype: 'application/json',
        contentType: 'application/json',
        data: JSON.stringify({ stateId: +stateId }),
        success: function (result) {
            $("#City").html("");
            $("#City").append
            ($('<option></option>').val(null).html("---choose City---"));
            $.each($.parseJSON(result), function (i, cty)
            { $("#City").append($('<option></option>').val(cty.Id).html(cty.Name)) })

        },
        error: function () { alert("Error !") },
    });
}

控制器的部分代码是:

private void Fill_StateDropDownList()
    {
        var st = from d in db.States
                  orderby d.Name
                  select d;
        ViewBag.State = st.ToList();
    }

  [HttpPost]
    public ActionResult selectCities(string stId)   
    {  

       List < City > lstcity = new List < City > ();  
        int stateiD = Convert.ToInt32(stId);
        lstgrupet = (from d in db.Citys
                  where d.StateID==stateiD
                 select d).ToList();  
       string result= JsonConvert.SerializeObject(lstgrupet, Formatting.Indented,
       new JsonSerializerSettings { ReferenceLoopHandling = ReferenceLoopHandling.Ignore});
       return Json(result, JsonRequestBehavior.AllowGet);
    } 

public ActionResult Edit(int? id)
    {
        if (id == null)
        {
            return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
        }
      TheObject obj = db.TheObjects.Find(id);
        if (obj == null)
        {
            return HttpNotFound();
        }
        Fill_StateDropDownList()            
        return View(obj);
    }

    [HttpPost, ActionName("Edit")]
    [ValidateAntiForgeryToken]
    public ActionResult EditPost(int? id)
    {
        if (id == null)
        {
            return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
        }
        var theobjectToUpdate = db.TheObjects.Find(id);

        if (TryUpdateModel(theobjectToUpdate, "",
           new string[] { "Name","StateId","CityId" }))
        {
                try
                {
                    db.SaveChanges();
                    return RedirectToAction("Index");
                }
                catch (Exception)
                {
                    ModelState.AddModelError("", "Error.");
                }

        }
        Fill_StateDropDownList()
        return View(theobjectToUpdate);
    }

2 个答案:

答案 0 :(得分:0)

实际上SelectList有一个带有selectedValue

参数的构造

现在你应该知道怎么做了

在编辑视图

<div class="form-group">
    @Html.LabelFor(u => u.State, new { @class = "control-label col-md-2" })
    <div class="col-md-10">
        @Html.DropDownListFor(u => u.State,
      new SelectList(ViewBag.State, "Id", "Name", Model.State),
      "Choose State",
      new { @class = "form-control", @onchange = "selectCities()" })
        @Html.ValidationMessageFor(u => u.State, "", new { @class = "text-danger" })
    </div>
</div>

答案 1 :(得分:0)

您已经拥有已保存的州和城市值。您所要做的就是根据保存的州ID加载城市子集,并使用该集合呈现城市的下拉列表

DropDownListFor辅助方法将从SELECT元素中选择相应的选项,只要视图模型的City属性值与选项的value属性值之一匹配即可。

public ActionResult Edit(int? id)
{
    if (id == null)
    {
        return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
    }
    TheObject obj = db.TheObjects.Find(id);
    if (user == null)
    {
        return HttpNotFound();
    }
    Fill_StateDropDownList() 
    FillCities(obj.State);           
    return View(obj);
}
private void FillCities(int stateId)
{
   ViewBag.CityList = db.Cities
                       .Where(g => g.StateId== stateId)
                       .Select(f => new SelectListItem() { 
                                                            Value = f.Id.ToString(), 
                                                            Text = f.Name })
                       .ToList();
}

对视图进行调整

var cityList = new List<SelectListItem>();
if (ViewBag.CityList != null)
{
    cityList =ViewBag.CityList as List<SelectListItem>;
}
@Html.DropDownListFor(u => u.City, cityList , "Choose City")

另一种选择是在页面加载上进行ajax调用(文档准备好根据状态下拉列表的值获取城市)。如果您有多个嵌套下拉列表,它会变得复杂。(最终在回调地狱中)