简体   繁体   中英

C# MVC DropDownListFor in a table of editable records

I am not sure if this is possible, and have not found any similar questions on this.

We have an Edit View that is NOT for a single record, but for the multiple members of a "parent" record. These "child" record need to be edited together (at the same time). ... if possible.

One field in each of these "child" records is a reference to another table, so a select list is required. We use DropDownListFor in all of our standard Edit Views, and the single record edits fine.

Our model for this issue is :

    [Display(Name = "Team Member")]
    public int Contact_ID { get; set; }
    [Display(Name = "Team Member")]
    public String Contact_Name { get; set; }

    [Display(Name = "Type/Role")]
    public int MemberTypeLookUp_ID { get; set; }
    [Display(Name = "Type/Role")]
    public String MemberTypeValue { get; set; }
    [Display(Name = "Type/Role")]
    public LookUpList MemberTypeLookUp { get; set; }

We retrieve the first 4 fields via a select from a database table. Straightforward and OK..

Our code to set up the DropDownListFor is :

(edit : new code added within the foreach() loop to manually set the .Selected property of the relevant option within each list to true. This still does not translate over to the actual displayed View...)

    foreach (TeamEditViewItem tevi in this.members)
    {
        tevi.MemberTypeLookUp = new LookUpList("TeamMemberType");

        foreach (SelectListItem item in tevi.MemberTypeLookUp.list)
        {
            if (item.Value == tevi.MemberTypeLookUp_ID.ToString())
            {
                item.Selected = true;
                break;
            }
        }
    }

For completion of this question, the LookUpList code is :

public class LookUpList 
{
    public SelectList list;

    // Return all Active LookUp entries for the passed-in Category.
    public LookUpList(String Category)
    {
        WorkpointContext _db = new WorkpointContext();

        int Customer_ID = _db.GetCustomer_ID();

        IList<LookUp> items = (from lookup in _db.LookUp
                                where (lookup.Category == Category)
                                && (lookup.IsActive == true)
                                orderby lookup.DisplayOrder ascending
                                select lookup).ToList();

        this.list = new SelectList(items, "ID", "Value");
    }

}

As mentioned, the LookUpList code is fine for a single record on a standard Edit View.

After rendering the page, we get the multiple "child" records listed, however the DropDown List does not hold the existing value for each record. (This is an EDIT not a Create, so values have already been assigned via defaults and other logics - not via DropDown lists on the Create View.

When viewing the source of the page, I can see that each of the DropDown Lists have their own ID.

I have a feeling that our issue is due to the multiple DropDownListFor objects on the page, but cannot figure out WHAT the issue is and WHY we have the issue.

Our View has simple code for the DropDownList :

    @Html.DropDownListFor(model => model.members[i].MemberTypeLookUp_ID, Model.members[i].MemberTypeLookUp.list, "--Select--")
    @Html.ValidationMessageFor(model => model.members[i].MemberTypeLookUp_ID)

The third parameter has been added because we were always getting the first option in the DropDown Lists and needed to determine if there was a value or not. We are constantly getting the "--Select--" option displayed in the DropDown Lists, which is a placeholder and not a valid option - therefore the Validation Message is displayed.

(Edit) I have added the complete Edit View cshtml code :

@model WebWorkPoint.Models.TeamEditView
<h3>Edit Team</h3>
@using (Html.BeginForm()) {
    <fieldset>
        @if (Model.members.Count>0)
        {
            <table>
            <!-- table headings -->
            <thead>
            <tr>
                <td style="text-align:center; border-bottom: 1px solid black; " >
                    <div class='editor-label'>
                        @Html.LabelFor(m => m.members.First().Contact_Name)
                    </div>
                </td>
                <td class="spacer-border"> </td>
                <td style="text-align:center; border-bottom: 1px solid black; " >
                    <div class='editor-label'>
                        @Html.LabelFor(m => m.members.First().MemberTypeValue)
                    </div>
                </td>
            </tr>
            </thead>

            <!-- table rows -->
            <tbody>
                @for (int i = 0; i < Model.members.Count; i++)
                {
                    <tr>
                        <td style="text-align:center; " >
                            @Html.HiddenFor(m => m.members[i].Contact_ID)
                            <div class="editor-field">
                                @Html.EditorFor(m => m.members[i].Contact_Name)
                                @Html.ValidationMessageFor(model => model.members[i].Contact_Name)
                            </div>
                        </td>
                        <td class="spacer"></td>
                        <td style="text-align:center; " >
                            <div class="editor-field">
                                @Html.DropDownListFor(model => model.members[i].MemberTypeLookUp_ID, Model.members[i].MemberTypeLookUp.list, "--Select--")
                                @Html.ValidationMessageFor(model => model.members[i].MemberTypeLookUp_ID)
                            </div>
                        </td>
                    </tr>
                }
            </table>
        }
        else
        {
            <p>There are currently no team members defined.</p>
        }
        <p>
            <input type="submit" value="Update Team" />
            @{
                sAction = "/" + Model.TableNameValue + "/" + Model.TableNameValue + "Show/" + Model.TableRecord_ID.ToString();
                sLinkText = "Cancel";
            }
            <button type="button" onclick="location.href='@sAction'" >@sLinkText</button>
        </p>
    </fieldset>
}

(end Edit)

Can anyone shed some light into our issue ? Thank you in advance for any help.

After reading this answer on Stack Overflow , we decided to try the same kind of resolution.

As it turns out, the FULL resolution went as follows :

  1. We still needed to set up the LookUpList in the setup code (but did not need to attempt any select code) :

     // other code above ... foreach (TeamEditViewItem tevi in this.members) { tevi.MemberTypeLookUp = new LookUpList("TeamMemberType"); } 
  2. The LookUpList() code creates the SelectList as per the original issue/question - no changes required there.

  3. We also needed to replace the DropDownListFor() call on the Edit View :

     @Html.DropDownListFor(model => model.members[i].MemberTypeLookUp_ID, new SelectList(Model.members[i].MemberTypeLookUp.list, "Value", "Text", Model.members[i].MemberTypeLookUp_ID), "--Select--") 

It seemed repetitive or redundant, but this is what was required. There may be something we could do to clean it further, but it "ain't broke" now, so why try to fix it ?

I must say thank you to @Stephen Muecke and @Mario Lopez for their input, to get us investigating and thinking further afield from what we were doing. Also, thank you to @ataravati for resolving the other issue linked above, to get us to try something else.

Hopefully our issue and resolution might help other coders out there ...

I think what is happening is that all the dropwdowns are being generated with the same Id = MemberTypeLookUp_ID. What I would do is creating a partial view for the child and call it from the main view inside a foreach and pass to this partial view only the child model that has to be populated for and not the whole parent model.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM