Assign selectlist to dynamically created dropdown in MVC

2k views Asked by At

I have static select list as below

var listItems = new SelectListItem[] {
                new SelectListItem(){Text="-- Please Select --",Value=""},
                new SelectListItem(){Text="Death",Value="Death"},
                new SelectListItem(){Text="Resignation",Value="Resignation"},
                new SelectListItem(){Text="Retirement",Value="Retirement"},
                new SelectListItem(){Text="Termination",Value="Termination"},
                new SelectListItem(){Text="Transfer",Value="Transfer"},
            };

            ViewBag.DeletionReason = listItems;

and assigning the same to ViewBag.

Now in my page i have to search for a staff ID.

eg: 1234

then in next view all the staffs whose staff id starts with 1234 will be listed. While listing the same against each staff details i need to list the above select list for choose there deletion reason.

I done it as below

Controller

    public ActionResult DeleteRequest(string[] memberIDs,string[] 
deletion_reason, string[] effective_date)
     {
    foreach (string item in memberIDs)
{

  np_user_requests_dtls userRequest = new np_user_requests_dtls();
  staffid = memberIDs[i];
  effectiveDateValue = effective_date[i];
  userRequest.staffid_id = staffid;
  userRequest.deletion_reason = deletion_reason[i];
userRequest.effective_date = Convert.ToDateTime(effectiveDateValue);

try
 {
   db.SaveChanges();

 }
  catch (exception ex)
                        {

                        }
                    }

                    i++;
                }

            }

View

<table >
<thead>
<tr>
<th>
Staff ID
<th>
New Effective End Date
</th>
<th>
Deletion Reason
</th>
<th>
<input type="checkbox" name="checkAll" id="checkAll" value="1" style="width: 25px" />
<a href="javascript:void(0);" id="selectAllInResult"> Or  Select all in result</a>
<span id="span_effective_for_all" style="display:none">
<input type="text" name="effective_date_all" id="effective_date_all" value="" placeholder="Effective End Date All" class="datepicker" style="width: 150px" >&nbsp;<input type="button" name="cancelAll" id="cancelAll" value="Cancel" style="width: 60px" />
</span>
<span id="span_deletion_reason_all" style="display:none">
<select name="deletion_reason_all" id="deletion_reason_all" style="width: 150px">&nbsp;</select><input type="button" name="cancelAll" id="cancelAll" value="Cancel" style="width: 60px" />
</span>
</th>
</tr>
</thead>
<tbody>
 @if (Model != null && Model.Count() > 0)
{
foreach (var item in Model)
{
<tr>
<td>
@Html.DisplayFor(modelItem => item.staff_id)
</td>
<td>
<input type="text" name="effective_date[]" id="@("efddate_"[email protected]_id)"  value="" placeholder="Effective End Date" class="datepicker"></td>
<td>
@Html.DropDownList("deletion_reason[]",(SelectList)@ViewBag.DeletionReason)
</td>
<td>
<input type="checkbox" name="memberIds[]" id="@item.staff_id" value="@item.staff_id_id" />
</td>
</tr>
}
</tbody>
</table>

Model

public string staff_id { get; set; }
public date effective_date { get; set; }
public string deletion_reason { get; set; }

In the view if the deletion_reason is also same as text type like effective_date I am able to post the data. But I need it to be dropdown. I am stucked there

This is giving me a run time error

 There is no ViewData item of type 'IEnumerable<SelectListItem>' 
that has the key 'deletion_reason[]'.

Also please give an idea how can i get the value corresponding to each staff while posting.

2

There are 2 answers

0
AudioBubble On BEST ANSWER

Firstly you can simplify your SelectList creation to

ViewBag.DeletionReason = new SelectList(new List<string>() { "Death", "Resignation", "Retirement", "Termination", "Transfer" });

Note: Do not include the "--Please select--" option. Use the overload of DropDownListFor() that accepts optionLabel (refer below).

Assuming the model is named Staff then the view needs to be

@model List<yourAssembly.Staff>
.....
for(int i = 0; i < Model.Count; i++)
{
  @Html.HiddenFor(m => m[i].staff_id)
  @Html.DisplayForFor(m => m[i].staff_id)
  @Html.TextBoxFor(m => m[i].effective_date, new { @class="datepicker" })
  @Html.DropDownListFor(m => m[i].deletion_reason, (SelectList)ViewBag.DeletionReason, "-- Please Select --")
}

and you POST method needs to be

[HttpPost]
public ActionResult YourActionName(List<Staff> model)
{
}

The use of the for loop in the view, in conjunction with the strongly typed helpers will ensure you form controls are correctly named with indexers and can be bound to a collection in the POST method.

Side note: The error you have posted in your edit is caused by the value of ViewBag.DeletionReason being null. Perhaps because you return the view in the POST method but have not reassigned the value of ViewBag.DeletionReason?

2
Pabregez On

Whilst it's rather hacky, I think what you're trying to do is cast your selectlistitem array as an enumerable and then use it?

@Html.DropDownList("deletion_reason", ((SelectListItem[])@ViewBag.DeletionReason).ToList())