Issue
I am using the following example model:
public class MyModel
{
public int Id { get; set; }
public string Text { get; set; }
public string Description { get; set; }
public bool? Accepted { get; set; }
}
Using this to show buttons if value for Accepted is null, otherwise show their choice:
@foreach (var item in Model) {
<tr>
<td>
@Html.DisplayFor(modelItem => item.Text)
</td>
<td>
@Html.DisplayFor(modelItem => item.Description)
</td>
<td class="accepted">
@{
if (item.Accepted == null)
{
@Html.ActionLink("Accept", "Edit", "MyModels", new { id = item.Id, Accepted = true, Text = item.Text, Description = item.Description },
new { @class = "btn btn-success btn-xs" })
@Html.ActionLink("Decline", "Edit", "MyModels", new { id = item.Id, Accepted = false, Text = item.Text, Description = item.Description },
new { @class = "btn btn-danger btn-xs" })
}
else if (item.Accepted == true)
{
<span>Accepted</span>
}
else if (item.Accepted == false)
{
<span>Declined</span>
}
}
</td>
Its working - But how could I handle this if there were 50 or 100 properties - I couldn't put them on the Actionlink?
My model in view is IEnumerable<MyModel>
and I need to access the releveant item.Id
in the foreach loop and serialise but I am not sure how? for example as below but model is a json Array of all Objects, cannot access item.id
out of scope (in the <script>
tag at botton of View), how do i just get the single item:
$('#MyTable td.accepted a').click(function() {
var model = @Html.Raw(Json.Encode(Model)); // this is an array of Objects (Model is IEnumerable<MyModel>)
$.ajax({
url: this.href,
type: 'POST',
contentType: 'json',
data: model[item.id], //here I just want to get 1 object
success: function(result) {
window.location.reload(true);
}
});
return false;
});
So I am sure there is a better way to accomplish this, e.g. sent the single item in the Model as one in the POST - I searched but could find no relevant question - please enlighten me.
P.S. sorry for my English, hope you can follow.
Edit: MVC Controller POST action:
[HttpPost]
public ActionResult Edit([Bind(Include = "Id,Text,Accepted,Description")] MyModel myModel)
{
if (ModelState.IsValid)
{
_db.Entry(myModel).State = EntityState.Modified;
_db.SaveChanges();
return RedirectToAction("Index");
}
return View(myModel);
}
Solution
Simple - use some forms and hidden inputs:
<td class="accepted">
@{
if (item.Accepted == null)
{
<form action="@Url.Action("Edit", "MyModels")" method="post" class="action-form">
<input type="hidden" name="Id" value="@item.Id" />
<input type="hidden" name="Accepted" value="true" />
<button type="submit" class = "btn btn-success btn-xs">Edit</button>
</form>
<form action="@Url.Action("Edit", "MyModels")" method="post" class="action-form">
<input type="hidden" name="Id" value="@item.Id" />
<input type="hidden" name="Accepted" value="false" />
<button type="submit" class = "btn btn-danger btn-xs">Decline</button>
</form>
}
else if (item.Accepted == true)
{
<span>Accepted</span>
}
else if (item.Accepted == false)
{
<span>Declined</span>
}
}
</td>
Adjust your jQuery code a bit:
$('#MyTable form.action-form').on('submit', function(e) {
e.preventDefault();
var model = $(this).serialize();
var url = $(this).attr('action');
$.post(url, model)
.done(function(result, status, jqxhr){
window.location.reload(true);
});
});
It looks as though you're using your data models as view models. I wouldn't recommend that, but you can make it work as-is by doing this:
[HttpPost]
public ActionResult Edit(MyModel model)
{
if (ModelState.IsValid)
{
var entry = _db.MyModels.SingleOrDefault(m => m.ID == model.ID);
if(entry != null)
{
entry.Accepted = model.Accepted;
_db.SaveChanges();
return RedirectToAction("Index");
}
}
return View(myModel);
}
This way, you're only updating the properties that actually need to be changed.
Answered By - Tieson T. Answer Checked By - David Goodson (PHPFixing Volunteer)
0 Comments:
Post a Comment
Note: Only a member of this blog may post a comment.