I have a asp.net core 2.0 app. I have an employee entity that I need to display checkboxes for in the view. The problem is that I need to do this dynamically, meaning because number of employees vary, I need to create a checkbox for each employee when rendering the view.
It sounds easy, but isn't really.
This is how I tried to do it and it works. But surely there must be an easier way to do this. I find making lists and checkboxes a nightmare to do in asp.net. Why is that? This is a fundamental part of so many websites. There should be ready made components for this!
I have a form that creates a discussion post. I need to provide a way to notify the employees that a new discussion has been made. So In the form I have one checkbox that when checked, all employees gets a notification over email. I also have checkboxes for each employee, if checked only the chosen employees gets emailed.
anyway, this is how I did it (This is inspired from a tutorial in the docs i can't seem to find):
1) Get all employees from the database and put it in a list
2) I set the list to the ViewData variable because I only need it for this particular view:
public async Task<IActionResult> NewDiscussion() { var user = await GetCurrentUserAsync(); var users = await _unitOfWork.DiskusjonRepository.GetAllUsers(user.OrganisasjonID); ViewData["Items"] = users; return View(); }
Because you can't send modified lists to the controller, this creates one checkbox with the name selectedPersons for each employee and sets it's value to the employee's id. In the view:
<div class="form-group"> @{ List<Styreforum2.Data.ApplicationUser> persons = ViewBag.Items; }<table class="table"><thead><tr><th>Name</th><th>Send email</th></tr></thead><tbody> @foreach (var person in persons) {<tr><td>@person.FirstName @person.LastName</td><td><input type="checkbox" name="selectedPersons" value="@person.Id" /></td></tr> }</tbody></table></div>
Now comes the part I have trouble with understanding. So creating many checkboxes with a string value, - what is sent to the controller is an array of strings? Not only that, this is in addition to the viewmodel for the rest of the form(that contains properties for the discussion post and also one checkbox for the send to all option).
I didn't even know this was possible. I don't understad how all the checkboxes gets put into a string array. Only because they are the same name? This is the rest;
[HttpPost] [ValidateAntiForgeryToken] public async Task<IActionResult> NewDiscussion([FromServices] IEmailSender _emailSender, string[] selectedPersons, NewDiscussionViewModel model) { if (!ModelState.IsValid) { return NotFound("Form not correct"); } ApplicationUser currentUser = await GetCurrentUserAsync(); if (currentUser == null) { return NotFound("Failed to get current user"); } if (selectedPersons.Any()) { var users = await _unitOfWork.DiskusjonRepository.GetAllUsers(currentUser.OrgID); var recievers = new List<ApplicationUser>(); foreach (var item in users) { if (selectedPersons.Contains(item.Id)) { recievers.Add(item); } } try { await _emailSender.SendManyEmailsAsync(recievers, $"{currentUser.FirstName} {currentUser.LastName} just created a new discussion. {model.Title} : {model.Message}."); return RedirectToAction(nameof(Index), new { message = "Created a new discussion" }); } catch (Exception ex) { throw new ApplicationException($"A new discussion created but failed to send email notification '{ex.Message}'."); }
// code for the discussion form removed....
return View(nameof(Index)): }