MVC DropDownList OnChange更新其他表单字段

本文关键字:表单 字段 其他 更新 DropDownList OnChange MVC | 更新日期: 2023-09-27 18:25:23

我是MVC的新手(我正在从传统ASP.Net的黑暗面转移过来),我知道SO更像是一个"为什么不起作用",但作为MVC的新手,我只是想问一下是如何实现的——我真的没有任何代码或标记,因为我现在不知道如何实现。

对,用一个类似的例子。。。我有一个表单,它有一个"小部件"列表的下拉列表(感谢SO,让它发挥作用)。。。然后还有其他具有"默认"值的字段(长度/高度/宽度)。

显示表单时,会显示下拉菜单,但L/H/W的表单字段为空/禁用,直到用户从DDL中选择一个为止。

现在,在classic ASP.Net世界中,您将在"onselectedindexchange"上执行PostBack,查看所选项目,然后使用"主窗口小部件条目"版本的值更新L/H/W字段。

由于MVC没有post-back。。。这是如何实现的?

MVC DropDownList OnChange更新其他表单字段

在Asp.NetMVC中,当控件值发生更改时,没有像在web窗体中那样的回发行为。您仍然可以发布表单,在操作方法中,您可以读取选定的值(已发布的值)并加载文本框的值,然后再次呈现页面。这是完整的表单过帐。但使用ajax有更好的方法可以做到这一点,这样用户就不会经历完整的页面重新加载。

您所做的是,当用户更改下拉列表时,获取所选项目的值,并调用服务器以获取您想要在输入字段中显示的数据并设置这些数据。

为页面创建视图模型。

public class CreateViewModel
{
    public int Width { set; get; }
    public int Height{ set; get; }
    public List<SelectListItem> Widgets{ set; get; }
    public int? SelectedWidget { set; get; }    
}

现在在GET操作中,我们将创建一个这样的对象,初始化Widgets属性并发送到视图

public ActionResult Create()
{
  var vm=new CreateViewModel();
  //Hard coded for demo. You may replace with data form db.
  vm.Widgets = new List<SelectListItem>
            {
                new SelectListItem {Value = "1", Text = "Weather"},
                new SelectListItem {Value = "2", Text = "Messages"}
            };
 return View(vm);
}

以及强类型为CreateViewModel 的创建视图

@model ReplaceWithYourNamespaceHere.CreateViewModel
@using(Html.BeginForm())
{
    @Html.DropDownListFor(s => s.SelectedWidget, Model.Widgets, "Select");
    <div id = "editablePane" >
         @Html.TextBoxFor(s =>s. Width,new { @class ="myEditable", disabled="disabled"})
         @Html.TextBoxFor(s =>s. Height,new { @class ="myEditable", disabled="disabled"})
    </div>
}

上面的代码将为SELECT元素呈现html标记,并为Width和Height呈现2个输入文本字段。(在页面上执行"查看源代码",然后参阅)

现在我们将有一些jQuery代码,它监听SELECT元素的change事件并读取所选项值,对服务器进行ajax调用以获取所选小部件的Height和Width。

<script type="text/javascript">
 $(function(){
      $("#SelectedWidget").change(function() {
            var t = $(this).val();
            if (t !== "") {               
                $.post("@Url.Action("GetDefault", "Home")?val=" + t, function(res) {
                    if (res.Success === "true") {
                      //enable the text boxes and set the value
                        $("#Width").prop('disabled', false).val(res.Data.Width);
                        $("#Height").prop('disabled', false).val(res.Data.Height);
                    } else {
                        alert("Error getting data!");
                    }
                });
            } else {
                //Let's clear the values and disable :)
                $("input.editableItems").val('').prop('disabled', true);
            }
        });
 });
</script>

我们需要确保在HomeController中有一个名为GetDetault的操作方法来处理ajax调用。

[HttpPost]
public ActionResult GetDefault(int? val)
{
    if (val != null)
    {
        //Values are hard coded for demo. you may replae with values 
       // coming from your db/service based on the passed in value ( val.Value)
        return Json(new { Success="true",Data = new { Width = 234, Height = 345}});
    }
    return Json(new { Success = "false" });
}
  1. 制作一个返回"Json"数据的控制器"操作"
  2. 让Ajax调用下拉列表中的"onchange"到"Action"
  3. 在ajax"响应"(json)上,u将获取值,然后将这些值设置为json响应中的字段

这是更新字段值的方法。

Shyju在2015年发表了一篇精彩的帖子,但我不得不更新它,使其适用于MVC 5。我和我的一个程序员(我是一名IT经理)一起创建了这个。您需要创建一个类来表示下拉列表以及高度和宽度。

public class AjaxText
{
    public int Width { set; get; }
    public int Height { set; get; }
    public List<SelectListItem> Widgets { set; get; }
    public int? SelectedWidget { set; get; }
}

在我的HomeController.cs中,GET操作将创建一个这样的对象,初始化Widgets属性并发送到视图。

public IActionResult AjaxText()
{
    //Hard coded for demo. You may replace with data form db.
    AjaxText vm = new AjaxText();
    vm.Widgets = new List<SelectListItem>
    {
        new SelectListItem {Value = "1", Text = "Weather"},
        new SelectListItem {Value = "2", Text = "Messages"}
    };
    return View(vm);
}

创建视图将为SELECT元素呈现html标记,并为Width和Height呈现2个输入文本字段。(在页面上做"查看源代码",然后查看)

@model AjaxText
@{
    ViewData["Title"] = "AjaxText";
}
<h1>@ViewData["Title"]</h1>
@using(Html.BeginForm())
{
    @Html.DropDownListFor(s => s.SelectedWidget, Model.Widgets, "Select");
    <div id = "editablePane" >
         @Html.TextBoxFor(s =>s. Width,new { @class ="myEditable", disabled="disabled"})
         @Html.TextBoxFor(s =>s. Height,new { @class ="myEditable", disabled="disabled"})
    </div>

现在,我们将有一些代码来侦听SELECT元素的更改事件并读取所选项的值,对服务器进行ajax调用以获取所选小部件的Height和Width。我添加了一些警报来帮助您调试。

<script type="text/javascript">
 $(function(){
      $("#SelectedWidget").change(function() {
            var t = $(this).val();
            if (t !== "") 
            {               
                $.ajax({
                    type: 'POST',
                    datatype: 'json',
                    url: '/Home/GetDefault?val=' + t,
                    success: function (bbb) {
                        alert(t);
                        alert(bbb.success);
                        alert(bbb.info.height);
                        $("#Width").prop('disabled', false).val(res.Data.Width);
                        $("#Height").prop('disabled', false).val(res.Data.Height);
                    },
                    error: function (msg) {
                        alert("error");
                    }
                });
            } else {
                //Let's clear the values and disable :)
                $("input.editableItems").val('').prop('disabled', true);
            }
        });
 });
</script>

在我的家庭控制器中,《华盛顿邮报》的做法几乎和Shyju的做法一样,但成功并没有真真假假。你不必使用数据这个词。。。信息或其他什么也可以。但要保持小写以保持理智。

[HttpPost]
public JsonResult GetDefault(int? val)
{
    if (val != null)
    {
        //Values are hard coded for demo. you may replae with values 
        // coming from your db/service based on the passed in value ( val.Value)
        return Json(new { success = true, info = new { width = 234, height = 345 } });
    }
    return Json(new { Success = false });
}

我相信有更好的方法可以做到这一点。这就是我们的工作。干杯,享受您的编码体验!:)