8

我们有一个包含很多字段的普通 ASP.NET MVC 表单。第一个字段是最重要的,它是一个下拉列表。假设它是公司字段,它包含两个值“可口可乐”和“百事可乐”。

公司字段如下所示:

    <div class="editor-label">
       @Html.LabelFor(Function(model) model.Company)
    </div>
    <div class="editor-field">
        @Html.DropDownListFor(Function(model) model.Company, TryCast(ViewData("Companies"), SelectList), New With {Key .style = "blah blah;"})
        @Html.ValidationMessageFor(Function(model) model.Company)
    </div>

因为重要的是这个选择是主动做出的,而不是仅仅因为它是按字母顺序排列的第一个而简单地留在“可口可乐”上,所以我们首先需要该字段为空(验证数据注释负责强制用户输入内容)。

这很容易用 Javascript 完成,如下所示:

        function InitialiseForm() {
            $('#Company').prop('selectedIndex', -1);
        }

        window.onload = InitialiseForm;

但是,在某些情况下,表单并未完全加载为空白,而是在控制器中初始化了公司字段,如下所示:

    modelObject.Company = "Coca Cola" 

在这种情况下,我们当然不希望 Javascript 执行和删除它。

在这种情况下,正常的解决方案是什么?

4

5 回答 5

3

我的假设是正确的:如果初始值为 null ,DropDownListFor则不会生成属性。selected

对于空公司,它会生成以下 html:

<select id="Company" name="Company">
   <option value="1">Coca-Cola</option>
   <option value="2">Pepsi</option>
</select>

与选定的公司 html 代码不同:

<select id="Company" name="Company">
   <option selected="selected" value="1">Coca-Cola</option>
   <option value="2">Pepsi</option>
</select>

所以你可以使用这个javascript代码,它会工作:

$(function () {
    if ($("#Company").find("option[selected]").length == 0) {
        $("#Company").prop('selectedIndex', -1);
    }
});

此外,如果您的 jquery 版本早于 1.9.0,则option[selected]表达式可能无法正常工作。该错误在 1.9.0 中已修复,但在早期版本中,'filter'、'children' 和 'is' 等函数工作不正确,而 'find' 和 'has' 返回了正确的结果。

于 2013-10-26T20:11:22.960 回答
1

几天前我遇到了类似的问题,想将我的下拉菜单默认为第一个索引,除非它在某个时候被选中。我使用会话变量作为补救措施......这样的事情可能会奏效:

var CurrentCompanyID = 1;
var gCompanyID = '@(Convert.ToInt32(Session["CompanyID"]))';

if (gCompanyID == null || gCompanyID == '' || gCompanyID == 0) {
    CurrentCompanyID = 1;
}
else {
    CurrentCompanyID = gCompanyID;
    $("#CompanyDropDown").val(CurrentCompanyID);
}

$("#CompanyDropDown").change(function () {
    CurrentCompanyID = $(this).val();

    $.ajax({
        url: "Controller/ChangeCompany",
        cache: false,
        data: { _compID: CurrentCompanyID },
        success: function (result) {
            console.log(result);
            $("#CompanyForm").submit();
        }
    });
});

// Where:

public JsonResult ChangeCompany(int _compID)
{
    Session["CompanyID"] = _compID;
    return Json(Session["CompanyID"], JsonRequestBehavior.AllowGet);
}

...对于当前控制器的 Index() 操作:

var _compID = Convert.ToInt32(Session["CompanyID"]);
var dataContext = new SERVERDataContext();

if (Session["CompanyID"] == null)
{
    //Get Companies

    return View(vm);
}
else
{
    //Get Companies where Company.ID == _compID

    return View(vm);
}

所以基本上我将下拉列表的当前值设置为会话变量的值。如果我想更改下拉值,我只需为会话变量分配一个新值!当 session var 为 null 或毫无价值时,将下拉列表设置为我想要的索引。

希望这可以帮助。

于 2013-10-16T13:22:53.030 回答
1

这是一种干净的方法:

在列表中添加一个可选标签,如果模型公司值为空,它将被选中,否则将显示当前值预选(不需要 javaScript 选择代码),如果用户不选择他不能选择的值通过验证:

@Html.DropDownListFor(Function(model) model.Company, TryCast(ViewData("Companies"), SelectList), "Select a company", New With {Key .style = "blah blah;"})
于 2013-10-22T13:23:38.310 回答
1

选项1:

您可以将逻辑放在控制器中的操作方法中。

例如:控制器

public ActionResult LoadForm()
{
    var companies = new List<Company>();
    var isSpecialCase = false;

    if (default)
    {
        companies.Add(new Company {
            CompanyId = 1,
            CompanyName = "Coca Cola"
        });

        companies.Add(new Company
        {
            CompanyId = 2,
            CompanyName = "Pepsi"
        });
    }
    else if (yourSpecialCase)
    {
        isSpecialCase = true;

        companies.Add(new Company {
            CompanyId = 1,
            CompanyName = "Coca Cola"
        });
    }
    else
    {
         //define any other implementations...
    }

    ViewBag.IsSpecialCase = isSpecialCase;
    ViewBag.Companies = companies;

    return View();
}

公司

public class Company {
    public int CompanyId { get; set; }
    public string CompanyName { get; set; }
}

在你的表单 中(注意如果是特殊情况,不会显示可选标签)

@if (ViewBag.IsSpecialCase)
{
    @Html.DropDownListFor(model => model.Data, new SelectList(ViewBag.Companies as List<Company>, "CompanyName", "CompanyId"))
}
else
{
    @Html.DropDownListFor(model => model.Data, new SelectList(ViewBag.Companies as List<Company>, "CompanyName", "CompanyId"), "Select a company...")
}

选项 2:

创建自定义下拉列表(自定义 html 助手)

请参考以下链接。 链接 1 链接 2

于 2013-10-29T06:29:34.030 回答
1
@{
    var listItems = new SelectList(new List<SelectListItem>
                {
                    new SelectListItem { Value = "1", Text = "drink 1" },
                    new SelectListItem { Value = "2", Text = "drink 2" },
                    new SelectListItem { Value = "3", Text = "drink 3" }
                }, "Value", "Text");

    var selectedDrink = "";
}

@Html.DropDownListFor(x => selectedDrink, listItems, "--select drink--")

“--select drink--” 除非设置了所选项目,否则将显示。

(为简洁起见,代码仅在 View 中编写)

于 2013-10-26T22:10:13.290 回答