I have a loop that creates a button for each entry. However, I need to set a dynamic id for the button in order to use it and know the selected entry upon button click.
My controller retrieves a list of entries from the database and using "ViewBag.List", I added the buttons. The list derrived from the database includes ID, Title and Description.
This is the view/ Index.cshtml
@model Exams.Models.subjects
@{
ViewBag.Title = "Subjects"
}
<h2> Current Subjects </h2>
<form method="post" action="@Url.Action("Submit")" >
<table>
@foreach(var subject in ViewBag.List){
<tr>
<td>
@subject.Title </br>
@subject.Desc
</td>
<td>
<button name="Submit"> Submit </button>
<td>
<tr>
}
</table>
Upon clicking the button, the next view must include
"You just registered " + SubjectTitle
How should the subject Title be included? Knowing that simple ViewBag saves the SubjectTitle by reference
3 Things,
1)You need to attach click event to button.
2) use, $(this).parent().prev()
in clicked handler to target previous td element.
3) get the td html, split on occurrence of br and get the first element for getting title only.
$('table button').click(function(){
var titleanddesc = $(this).parent().prev().html();
alert(titleanddesc.split('<br>')[0]);
});
Working Demo
Use a View Model to persist your data. View models are great. Here are a few reasons why.
public class SubjectsViewModel {
public IEnumerable<Subject> Subjects { get; set; }
}
Use whatever controller code you're using to fill ViewBag.List
to fill Subjects
instead and return the view with the SubjectsViewModel
, something like:
public ActionResult Subjects() {
var model = new SubjectsViewModel();
model.Subjects = db.Subjects;
return View(model);
}
Your new view:
@model Exams.ViewModels.SubjectsViewModel
@{
ViewBag.Title = "Subjects"
}
<h2> Current Subjects </h2>
@using (Html.BeginForm())
{
<table>
@foreach(var subject in Model.Subjects){
<tr>
<td>
@subject.Title</br>
@subject.Desc
</td>
<td>
<input name="submit" value='@subject.id'> Submit </button>
</td>
<tr>
}
</table>
}
From the HTML I changed, I will assume you're not massively used to Razor. You can read up on Razor here.
You can then do this with your controller:
[HttpPost]
public ActionResult Subjects(string submit) {
return RedirectToAction("SubjectInfo", new { subjectid = submit });
}
This tells the controller to pass the value of the button you named as 'submit'. If you wanted to rename it, just change the name of the input and the parameter in the POST
controller action.
You can set dynamic id to button in this way
@foreach (var objBook in ((List<Student>)ViewBag.List).Select((x, i) => new { Data = x, Index = i }))
{
<tr>
<td>
@objBook.Data.Title
</td>
<td>
<button name="Submit" id="btnSubmit_" + @objBook.Index> // append Index to Id
Submit
</button>
</td>
</tr>
}
Please try with this.
<form method="post" action="@Url.Action("Submit")" >
<table>
@foreach(var subject in ViewBag.List){
<tr>
<td>
@subject.Title </br>
@subject.Desc
</td>
<td>
<button name="Submit" " id="btnsubmit-@subject.id" > Submit
</button>
</td>
<tr>
}
</table>