Reputation: 1017
I have a table where I keep a list of Roles
, which has three columns: Name
and two buttons Edit
and Delete
. When users click on Edit
, it takes them to another form where they can edit the name of the role. If they click on Delete
, they get a modal dialog asking them for verification before they delete the role.
My issue is the following: if I click on the Edit
button, it detects the right Role
and the correct role name shows up in the new form that appears. However, if I click on Delete
, it always grabs the first Role
of the Model list (that is, the first role of the table), no matter which one I clicked on. Why?
Here's my view:
<table class="table table-striped table-hover ">
<thead>
<tr>
<th>@Resources.Role</th>
<th></th>
<th></th>
</tr>
</thead>
<tbody>
@foreach (var role in Model)
{
<tr>
<td>
@role.Name
</td>
<td>
@using (Html.BeginForm("RoleEdit", "Admin", new { ReturnUrl = ViewBag.ReturnUrl }, FormMethod.Get, new { @class = "form-horizontal", role = "form" }))
{
@Html.AntiForgeryToken()
@Html.HiddenFor(m => m.Where(r => r.Id.Equals(role.Id)).FirstOrDefault().Name)
<input type="submit" value="@Resources.Edit" class="btn btn-default btn-sm" />
}
</td>
<td>
<input type="submit" value="@Resources.Delete" class="btn btn-default btn-sm" data-toggle="modal" data-target="#confirm-delete" />
<div class="modal fade" id="confirm-delete" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
@Resources.DeleteRole
</div>
<div class="modal-body">
@Resources.AreYouSureYouWantToDelete
<hr />
@role.Name
</div>
<div class="modal-footer">
@using (Html.BeginForm("RoleDelete", "Admin", new { ReturnUrl = ViewBag.ReturnUrl }, FormMethod.Post, new { @class = "form-horizontal", role = "form" }))
{
@Html.AntiForgeryToken()
@Html.HiddenFor(m => m.Where(r => r.Id.Equals(role.Id)).FirstOrDefault().Name)
<button type="button" class="btn btn-default" data-dismiss="modal">@Resources.Cancel</button>
<input type="submit" value="@Resources.Delete" class="btn btn-danger btn-ok" />
}
</div>
</div>
</div>
</div>
</td>
</tr>
}
</tbody>
</table>
Upvotes: 0
Views: 573
Reputation:
Your issue is that you are creating duplicate id
attributes in your foreach
loop (which is invalid html) in the following line of code
The submit button above it is target the element with that id
<input type="submit" ... data-target="#confirm-delete" />
which will only ever return the first element with id="confirm-delete"
One way to solve this if to ensure your elements have unique id
attributes, for example
@{ int counter = 0; }
@foreach (var role in Model)
{
var id = string.Format("confirm-delete-{0}", ++counter);
var target = string.Format("#{0}", id);
....
<input type="submit" ... data-target="@target" />
<div class="modal fade" id="@id" ...>
However this design is generating a separate dialog in each iteration and generating a lot of extra unnecessary html. It would be be better to have one dialog and handle the .submit()
event to display the dialog and cancel the submit if it returns false. You have not indicated which jquery plugin your using for the dialog, so that will need to be the subject of a separate question.
Side notes:
You can simplify your view by using a link for the redirecting to the Edit()
method rather than using a form element
@Html.ActionLink("Edit", "RoleEdit", "Admin", new { ID = role.Id }, new { @class = "btn btn-default btn-sm" })
and int the 'Delete' form, you can add the Id
as a route value and omit the hidden input. Note also that your deleting data so it should be a POST, not a GET
@using (Html.BeginForm("RoleEdit", "Admin", new { ReturnUrl = ViewBag.ReturnUrl, id = item.Id }, FormMethod.Post, new { @class = "form-horizontal", role = "form" }))
{
@Html.AntiForgeryToken()
<input type="submit" value="@Resources.Edit" class="btn btn-default btn-sm" />
}
however a better way to handle the 'Delete' would be to post the value using ajax and return a result indicating success or otherwise, and if successful, remove the corresponding item form the DOM. This allows the users to stay on the same page and continue to delete other items.
Upvotes: 1