由AJAX填充的下拉列表未获得初始值设置

时间:2012-12-13 19:31:08

标签: jquery asp.net-mvc asp.net-mvc-3

我有一个页面,其中包含一个表格,其中包含一个动态添加行的按钮以及一种删除行的方法。每行有2个级联下拉列表。创建一行时,我使用AJAX调用来填充第一个下拉列表中的值。在此下拉列表的更改事件中,我执行另一个AJAX调用以填充第二个下拉列表。这一切都运行正常,但我的问题是,当我加载屏幕时应该显示最初显示的数据我可以使用AJAX调用填充下拉列表但是没有选择值我猜测因为它被绑定到我的填充后模型。有没有办法正常处理这种情况?下面是我的文档就绪函数

中的代码
$(document).ready(function () {
    $.getJSON('@Url.Action("GetAll", "Customers")', function (customers) {
        var customerSelect = $('.Customers');
        customerSelect.empty();
        customerSelect.append('<option value="0">Choose Customer...</option>');
        $.each(customers, function (index, customer) {
            customerSelect.append($('<option/>', {
                value: customer.ID,
                text: customer.CustomerName
            }));
        });
    });
});

如果此信息有帮助,这里是加载表的HTML代码

<table id="Attendees" class="table-gridview">
        <thead>
            <tr>
                <th style="width:320px">
                    Customer
                </th>
                <th style="width:250px">
                    Attendee
                </th>
                <th>
                    Attended
                </th>
                <th>
                    Paid
                </th>
                <th style="width:120px">
                    Check Number
                </th>
                <th>

                </th>
            </tr>
        </thead>
        <tbody>
            @Html.EditorFor(x => x.Attendees)
        </tbody>
    </table>

以下代码是参加者

的编辑器模板中的内容
<tr class="ClassAttendee">

    <td>
        @Html.HiddenFor(model => model.ID)
        @Html.HiddenFor(model => model.ClassID)

        @Html.DropDownList("Customers", Enumerable.Empty<SelectListItem>(), new { @Class = "Customers", style="width:300px" })
    </td>
    <td>    
        @Html.DropDownListFor(
            x => x.CustomerEmailID,
            Enumerable.Empty<SelectListItem>(),
            "Choose Attendee...",
                              new { @Class = "Contact", style = "width:220px" }
        )
        @Html.ValidationMessageFor(model => model.CustomerEmailID)
    </td>
    <td>    
        @Html.CheckBoxFor(model => model.Attended)
        @Html.ValidationMessageFor(model => model.Attended)
    </td>
    <td>    
        @Html.CheckBoxFor(model => model.FeePaid, new { @Class = "FeePaid"})
        @Html.ValidationMessageFor(model => model.FeePaid)
    </td>
    <td>    
        @if (Model.FeePaid != true)
        {
            @Html.TextBoxFor(model => model.CheckNumber, new { @Class = "CheckNumber", disabled ="true", style = "width:100px" })
        }
        else
        {
            @Html.TextBoxFor(model => model.CheckNumber, new { @Class = "CheckNumber", style = "width:100px" })
        }

        @Html.ValidationMessageFor(model => model.CheckNumber)
    </td>
    <td>
        @Html.HiddenFor(x => x.Delete, new { @class = "mark-for-delete" })
        @Html.LinkToRemoveNestedFormUpdateCounter("Remove", "tr.ClassAttendee", "input.mark-for-delete")
    </td>
</tr>

我将展示的最后一部分是AJAX调用的服务器端代码

public JsonResult GetAll()
    {
        var customers = customerRepository
            .All
            .Select(p => new
            {
                p.ID ,
                p.CustomerName
            })
            .OrderBy(o => o.CustomerName);
        return Json(customers, JsonRequestBehavior.AllowGet);
    }

2 个答案:

答案 0 :(得分:0)

因此,当我加载页面时,我设法通过不使用编辑器来实现此功能。相反,我现在用下面的代码填充表格

<table id="Attendees" class="table-gridview">
        <thead>
            <tr>
                <th style="width:320px">
                    Customer
                </th>
                <th style="width:250px">
                    Attendee
                </th>
                <th>
                    Attended
                </th>
                <th>
                    Paid
                </th>
                <th style="width:120px">
                    Check Number
                </th>
                <th>

                </th>
            </tr>
        </thead>
        <tbody>
            @foreach (var item in Model.Attendees)
            {
              <tr class="ClassAttendee">
                <td>
                    @Html.HiddenFor(model => item.ID)
                    @Html.HiddenFor(model => item.ClassID)

                    @Html.DropDownList("Customers", ((IEnumerable<TRIOSoftware.Domain.Entities.Customer>)ViewBag.PossibleCustomers).Select(option => new SelectListItem
                   {
                       Text = (option == null ? "None" : option.CustomerName),
                       Value = option.ID.ToString(),
                       Selected = (Model != null) && (option.ID == item.CustomerEmail.CustomerID)
                   }),"Choose Customer...", new { @Class = "Customers", style = "width:300px" })
                </td>
                <td> 
                     @Html.DropDownListFor(model => item.CustomerEmailID, ((IEnumerable<TRIOSoftware.Domain.Entities.CustomerEmail>)ViewBag.PossibleContacts).Where(o => o.CustomerID == item.CustomerEmail.CustomerID).Select(option => new SelectListItem
                    {
                        Text = (option == null ? "None" : option.Name),
                        Value = option.ID.ToString(),
                        Selected = (Model != null) && (option.ID == item.CustomerEmailID)
                    }), "Choose Attendee...")   
                    @*@Html.DropDownListFor(model => item.CustomerEmailID, Enumerable.Empty<SelectListItem>(), "Choose Attendee...", new { @Class = "Contact", style = "width:220px" })*@
                    @Html.ValidationMessageFor(model => item.CustomerEmailID)
                </td>
                <td>    
                    @Html.CheckBoxFor(model => item.Attended)
                    @Html.ValidationMessageFor(model => item.Attended)
                </td>
                <td>    
                    @Html.CheckBoxFor(model => item.FeePaid, new { @Class = "FeePaid" })
                    @Html.ValidationMessageFor(model => item.FeePaid)
                </td>
                <td>    
                    @if (item.FeePaid != true)
                    {
                        @Html.TextBoxFor(model => item.CheckNumber, new { @Class = "CheckNumber", disabled = "true", style = "width:100px" })
                    }
                    else
                    {
                        @Html.TextBoxFor(model => item.CheckNumber, new { @Class = "CheckNumber", style = "width:100px" })
                    }

                    @Html.ValidationMessageFor(model => item.CheckNumber)
                </td>
                <td>
                    @Html.HiddenFor(x => item.Delete, new { @class = "mark-for-delete" })
                    @Html.LinkToRemoveNestedFormUpdateCounter("Remove", "tr.ClassAttendee", "input.mark-for-delete")
                </td>
            </tr>
            }
        </tbody>
    </table>

基本上我将模板代码移动到视图中,而不是使用AJAX填充下拉列表,而是使用我发送到视图中的数据填充初始代码。

我会暂时提出这个问题,看看是否有人想出更好的答案,因为在我看来这是一个强力解决方案。

EDIT ---------------------------------------------- ---------------------------------

我遇到此解决方案的问题,将值传递回控制器进行保存。由于我没有找到其他方法来实现这一点,我将其添加到视图的文档就绪功能

 $("#Attendees tr").each(function (index) {
        $(this).find("input, select, span").each(function (indx, element) {
            if ($(element).attr('name') !== undefined) {
                var name = $(element).attr('name').replace("item", "Attendees[" + (index - 1) + "]");
                $(element).attr('name', name);
            } else {
                // attribute does not exist
            }

            if ($(element).attr('id') !== undefined) {
                var id = $(element).attr('id').replace("item", "Attendees_" + (index - 1) + "_");
                $(element).attr('id', id);
            } else {
                // attribute does not exist
            }

            if ($(element).attr('data-valmasg-for') !== undefined) {
                var dataval = $(element).attr('data-valmasg-for').replace("item", "Attendees[" + (index - 1) + "]");
                $(element).attr('data-valmasg-for', dataval);
            } else {
                // attribute does not exist
            }
        });


    });

基本上我会用正确的名称替换项目ID和名称,以将我的数据恢复到控制器。这有点像黑客,但确实有效,所以我想发布它。

答案 1 :(得分:0)

我没有对此进行过测试,但你可以做点什么:

$(document).ready(function () {
    $.getJSON('@Url.Action("GetAll", "Customers")', function (customers) {
        var customerSelect = $('.Customers');
        customerSelect.empty();
        customerSelect.append('<option value="0">Choose Customer...</option>');
        $.each(customers, function (index, customer) {

            var option=$('<option/>', {
                value: customer.ID,
                text: customer.CustomerName
            });
            if(customer.ID=='@(Model.CustomerEmailID)')
                 $(option).attr("selected","selected");

            customerSelect.append(option);

        });
    });
});

<强>更新

如果您可以将选定的ID添加为父<td>的属性,请执行以下操作:

<td data-id="@(Model.CustomerEmailID)">    
    @Html.DropDownListFor(
        x => x.CustomerEmailID,
        Enumerable.Empty<SelectListItem>(),
        "Choose Attendee...",
                          new { @Class = "Contact", style = "width:220px" }
    )
    @Html.ValidationMessageFor(model => model.CustomerEmailID)
</td>

你可以这样做:

$(document).ready(function () {
    $.getJSON('@Url.Action("GetAll", "Customers")', function (customers) {
        var customerSelect = $('.Customers');
        customerSelect.empty();
        customerSelect.append('<option value="0">Choose Customer...</option>');
        $.each(customers, function (index, customer) {

            var option=$('<option/>', {
                value: customer.ID,
                text: customer.CustomerName
            });
            if(customer.ID==$(this).parent().attr("data-id"))
                 $(option).attr("selected","selected");

            customerSelect.append(option);

        });
    });
});
相关问题