On a page in a Razor MVC app a bunch of lines are written from a model, like this:
@foreach (var item in Model)
{
// write lots of data
@Html.CheckBoxFor(item.Id) // incorrect syntax, I know
}
<input type="button" value="Update" onclick="Update();" />
The javascript that is run from the button is supposed to get the item.Id (which is a unique integer) from each checkbox that has been checked, put the ids in an array and pass the array to another function. This is what I'm working with so far:
function Update() {
var ids = document.getElementsByName("myCheckbox");
var idList = new Array(ids.length);
for (var i = 0; i < ids.length; i++) {
if (ids[i].checked {
idList.push(ids[i]);
}
}
$.ajax({
type: "POST",
url: "@Url.Action("Update", "Home")",
data: idList,
success: function (data) {
},
error: function (data) {
console.log(data);
}
});
}
How do I add the same name to all the checkboxes and have their ID be that of item.Id?
Edit
I tried C Murphy's suggestion by making a class for the checkboxes:
public class ToBeUpdated
{
public int ID { get; set; }
public bool IsSelected { get; set; }
}
And then adding a List to the class that's in the model:
public List<ToBeUpdated> ToBeUpdatedList { get; set; }
However, I can't figure out how to write the CheckBoxFor. His/her suggestion was:
@Html.CheckboxFor(modelItem => modelItem.SomeNameList[i].IsSelected)
But I'm not doing a for loop but a foreach:
foreach (var item in Model)
So I had to do this instead:
@Html.CheckBoxFor(modelItem => item.ToBeUpdatedList.Find(m => m.ID == item.Id).IsSelected)
Then I have my button that sends me to the function in my controller:
<input type="button" value="Update" onclick="location.href='@Url.Action("UpdateStatuses", "Home")'" />
public IActionResult UpdateStatuses(IEnumerable<FileData> model)
{
// iterate through the items in the model
}
The problem is that when I get to UpdateStatuses the model is empty even though I had a ton of checkboxes that I checked before clicking the button. The model in the View is
@model IEnumerable<MyData>
And MyData is a simple class:
public class MyData
{
public int Id { get; set; }
public List<ToBeUpdated> ToBeUpdatedList { get; set; }
}
Edit 2: Finally found a solution
I made my checkboxes like this:
<input type="checkbox" name="chkUpdateThis" id="@item.Id" />
And then I could, with the help of T.J's code, edit my javascript to do this:
function UpdateStatuses() {
const ids = [...document.querySelectorAll("[name=chkUpdateThis]")].filter(({checked}) => checked).map(({id}) => id)
var idList = new Array();
for (var i = 0; i < ids.length; i++) {
idList.push(parseInt(ids[i]));
}
$.ajax({
type: "POST",
url: "@Url.Action("UpdateStatuses", "Home")",
data: ({ ids: idList }),
success: function (data) {
},
error: function (data) {
console.log(data);
}
});
}
Then I can call the UpdateStatuses function in my Home controller:
public IActionResult UpdateStatuses(List<int> ids)
Since T.J didn't post a suggestion that I can give a checkbox to, I'll give it to C Murphy who was also helpful. I didn't use his suggestion, but I don't want to give myself a checkbox even though the solution I went for is right here.