ASP.NET Core MVC returning checked items from a form in a razor view to controller - razor

I am working with a view that shows a list of delisted books (with isActive = false). In this view I have added a column of checkbox against each book . When the form is submitted I want to set all the checked books to become active (isActive = true).
This is the view I am working with :
#model IEnumerable<MvcBooksList.Models.Book>
#{
ViewData["Title"] = "Delisted Books";
}
#if (Model != null)
{
#using (Html.BeginForm("DelistedForm", "Book", FormMethod.Post))
{
<table class="table">
<thead>
<tr>
<th>
#Html.DisplayNameFor(model => model.BookName)
</th>
<th>
#Html.DisplayNameFor(model => model.Author)
</th>
<th>
#Html.DisplayNameFor(model => model.Publisher)
</th>
<th>
Enlist
</th>
</tr>
</thead>
<tbody>
#foreach (var item in Model)
{
<tr>
<td>
#Html.DisplayFor(modelItem => item.BookName)
</td>
<td>
#Html.DisplayFor(modelItem => item.Author)
</td>
<td>
#Html.DisplayFor(modelItem => item.Publisher)
</td>
<td>
#Html.CheckBoxFor(modelItem => item.IsActive)
</td>
</tr>
}
</tbody>
</table>
<input type="submit" value="Save" /> <input type = "button" value = "Cancel" onclick = "location.href='#Url.Action("Index","Home")'" />
}
}
else
{
<h3>No Books currently delisted</h3>
}
So my question is: how do I process this data in my controller action. As in when I click submit, will the form return IEnumerable of Books with IsActive set to true to the action??
I am trying something like this:
[HttpPost]
public ActionResult DelistedForm(IEnumerable<Book> fromDelist)
{
foreach (var item in fromDelist)
{
if (item.IsActive == true) ;
// enlist code here
}
return View("~/Views/Home/Index.cshtml");
}

If you only want to pass a list of books which IsActive is true.YOu can add hidden inputs to bind the data of BookName,Author,Publisher.And then change the name attribute of the inputs to correct format when checkbox is checked before form submitting.Here is a demo:
Action:
[HttpGet]
public IActionResult DelistedForm()
{
return View(new List<Book> { new Book { Author="a1", BookName="b1", IsActive=false, Publisher="p1"},
new Book { Author = "a2", BookName = "b2", IsActive = false, Publisher = "p2" },
new Book { Author = "a3", BookName = "b3", IsActive = false, Publisher = "p3" } });
}
[HttpPost]
[Route("/Book/DelistedForm")]
public ActionResult DelistedForm(IEnumerable<Book> fromDelist)
{
foreach (var item in fromDelist)
{
if (item.IsActive == true) ;
// enlist code here
}
return View("~/Views/Home/Index.cshtml");
}
View:
#if (Model != null)
{
#using (Html.BeginForm("DelistedForm", "Book", FormMethod.Post,new { #id="myForm"}))
{
<table class="table">
<thead>
<tr>
<th>
#Html.DisplayNameFor(model => model.BookName)
</th>
<th>
#Html.DisplayNameFor(model => model.Author)
</th>
<th>
#Html.DisplayNameFor(model => model.Publisher)
</th>
<th>
Enlist
</th>
</tr>
</thead>
<tbody>
#foreach (var item in Model)
{
<tr>
<td>
#Html.DisplayFor(modelItem => item.BookName)
#Html.HiddenFor(modelItem => item.BookName)
</td>
<td>
#Html.DisplayFor(modelItem => item.Author)
#Html.HiddenFor(modelItem => item.Author)
</td>
<td>
#Html.DisplayFor(modelItem => item.Publisher)
#Html.HiddenFor(modelItem => item.Publisher)
</td>
<td>
#Html.CheckBoxFor(modelItem => item.IsActive)
</td>
</tr>
}
</tbody>
</table>
<input type="submit" value="Save" />
<input type="button" value="Cancel" onclick="location.href='#Url.Action("Index","Home")'" />
}
}
else
{
<h3>No Books currently delisted</h3>
}
js:
<script>
$("#myForm").submit(function () {
var count = 0;
$("tbody tr").each(function () {
if ($(this).find("#item_IsActive").prop("checked")) {
$(this).find("#item_BookName").attr("name", "fromDelist[" + count + "].BookName");
$(this).find("#item_Author").attr("name", "fromDelist[" + count + "].Author");
$(this).find("#item_Publisher").attr("name", "fromDelist[" + count + "].Publisher");
$(this).find("#item_IsActive").attr("name", "fromDelist[" + count + "].IsActive");
count++;
}
})
})
</script>
result:

Related

data is not deleted after click on Delete Button in ASP.NET MVC

I created view where i listed my all records and i wanted to delete particular record after click on delete Button . But my record is deleted.
Following is the code-
Controller code-
public ActionResult Faqdelete()
{
var res = dbobj.tbl_FAQ.ToList();
return View(res);
}
[HttpPost]
public ActionResult Faqdelete(int id)
{
var res = dbobj.tbl_FAQ.Where(x => x.FAQ_ID == id).FirstOrDefault();
dbobj.tbl_FAQ.Remove(res);
dbobj.SaveChanges();
var Faqdata = dbobj.tbl_FAQ.ToList();
return View("Faqdelete",Faqdata);
}
- View page Code-
#model IEnumerable<ClassOne_SampleProject.Models.tbl_FAQ>
#{
ViewBag.Title = "Faqdelete";
}
<h2>Faqdelete</h2>
<table class="table">
<tr>
<th>
#Html.DisplayNameFor(model => model.FAQ_Question_Answer)
</th>
<th>Action</th>
</tr>
#foreach (var item in Model) {
<tr>
<td>
#Html.Raw(item.FAQ_Question_Answer)
</td>
<td>
Delete
</td>
</tr>
}
</table>
Please tell me where exactly the problem.
Modify your anchor tag as
<td>
<a href="Url.Action("Faqdelete", "somecontroller", new { id = item.FAQ_ID })"
class="btn btn-danger">Delete</a>
</td>

HTML how to display elements in a list on a new line

I have an object with a couple lists (OrganizationIDs and Organization Names) and I would like to display the contents of the lists on separate lines. Currently, if an object has more than one item in its list it appears to just append the values like so:
#{
ViewBag.Title = "Index";
}
<h2>Index</h2>
<p>
#Html.ActionLink("Create New", "Create")
</p>
<table class="table">
<tr>
<th>
#Html.DisplayNameFor(model => model.OrganizationIDs)
</th>
<th>
#Html.DisplayNameFor(model => model.OrganizationNames)
</th>
<th>
#Html.DisplayNameFor(model => model.Email)
</th>
</tr>
#foreach (var item in Model) {
<tr>
<td>
#Html.DisplayFor(modelItem => item.OrganizationIDs)
</td>
<td>
#Html.DisplayFor(modelItem => item.OrganizationNames)
</td>
<td>
#Html.DisplayFor(modelItem => item.Email)
</td>
<td>
#Html.ActionLink("Edit", "Edit", new { id = item.Id }) |
#Html.ActionLink("Details", "Details", new { id = item.Id }) |
#Html.ActionLink("Delete", "Delete", new { id = item.Id })
</td>
</tr>
}
</table>
How would I break these elements out in to their own rows?
Here is a working demo:
Model:
public class Model1
{
public List<int> OrganizationIDs { get; set; }
public List<string> OrganizationNames { get; set; }
public List<string> Email { get; set; }
}
Controller(Use fake data):
public IActionResult TestListModel1()
{
Model1 m = new Model1 { OrganizationIDs=new List<int> {16,18 }, OrganizationNames=new List<string> { "Bulldogs","Test Org"} };
Model1 m1=new Model1 { OrganizationIDs = new List<int> { 30 }, OrganizationNames = new List<string> { "Chevy"} };
Model1 m2 = new Model1 { OrganizationIDs = new List<int> { 19,29 }, OrganizationNames = new List<string> { "Testing","OrganzationTest" } };
Model1 m3 = new Model1 { OrganizationIDs = new List<int> { 16 }, OrganizationNames = new List<string> { "Bulldogs" } };
List<Model1> l = new List<Model1> { m, m1, m2, m3 };
return View(l);
}
TestListModel1.cshtml:
#model IEnumerable<Model1>
<table class="table">
<tr>
<th>
#Html.DisplayNameFor(model => model.OrganizationIDs)
</th>
<th>
#Html.DisplayNameFor(model => model.OrganizationNames)
</th>
<th>
#Html.DisplayNameFor(model => model.Email)
</th>
</tr>
#foreach (var item in Model)
{
#for (var i = 0; i < item.OrganizationIDs.Count(); i++)
{
<tr>
<td>
#Html.DisplayFor(modelItem => item.OrganizationIDs[i])
</td>
<td>
#Html.DisplayFor(modelItem => item.OrganizationNames[i])
</td>
<td>
#Html.DisplayFor(modelItem => item.Email[i])
</td>
<td>
</td>
</tr>
}
}
</table>
result:

Passing an ID from Razor view to Controller

In a view of type List I'm trying to pass the id (which is an eMail in this case) of the item from the view to an actionResult in the controller: I used the following code():
#Html.ActionLink("Contact", "CreateMessage", "Member", new { id = item.eMail })
I get a null reference because the id passed is null.
Here's the view which works just fine and the id in it isn't null:
#model IEnumerable<Mutuelle.Domain.Entities.Adherent>
#{
ViewBag.Title = "lister";
}
<h2>Liste des adhérents</h2>
<table class="table">
<tr>
<body style="overflow:scroll;">
<th>
#Html.DisplayNameFor(model => model.dateOfBirth)
</th>
<th>
#Html.DisplayNameFor(model => model.address)
</th>
<th>
#Html.DisplayNameFor(model => model.phoneNumber)
</th>
<th></th>
</tr>
#foreach (var item in Model)
{
<tr>
<td>
#Html.DisplayFor(modelItem => item.dateOfBirth)
</td>
<td>
#Html.DisplayFor(modelItem => item.address)
</td>
<td>
#Html.DisplayFor(modelItem => item.phoneNumber)
</td>
<td>
#Html.ActionLink("Contacter", "CreateMessage", "MembreComite", new { id = item.eMail })
</td>
</tr>
}
</table>
Here's the controller:
public ActionResult CreateMessage(string id)
{
Message message = new Message();
return View(message);
}
[HttpPost]
public ActionResult CreateMessage(Message message, string id)
{
if (ModelState.IsValid)
{
AMDMService service = new AMDMService();
Member member = service.GetMemberByeMail(id);
message.member = member;
message.adherentId = id;
member.listMessages.Add(message);
return RedirectToAction("listeMessages");
}
return View(message);
}
When you use routeValues like new { id = item.eMail } in your ActionLink, then you always should provide value for html attributes, which mostly used for styling your link, so if you don't want to style your link then you pass null otherwise you pass something like that new { #class = "btn btn-rounded btn-blue" }). So your code for ActionLink should look like this if you don't want to style your link:
#Html.ActionLink("Contact", "CreateMessage", "Member", new { id = item.eMail }, null);
Also you can replace #Html.ActionLink helper with #Url.Action helper like below:
Contact

How can I use #Html.DisplayFor without using foreach loop

I am trying to make a project where I want to display the details of user and then in a table I want to show the courses done by that user. When I try to display user details, the details of that user is shown as many number of courses they are taking since I am using a foreach loop. How can I do it without using foreach? I can do it if all the data is stored and retrieved from a single table but in this project I am using three tables- User, Course and UserCourse. UserCourse has foreign key reference to both UserId and CourseId. Now I want to retrieve details from user table.
HomeController:
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Login(User u)
{
if (ModelState.IsValid)
{
using (DetailsEntities dc = new DetailsEntities())
{
var v = dc.Users.Where(a => a.UserName.Equals(u.UserName) && a.Password.Equals(u.Password)).FirstOrDefault();
if (v != null)
{
Session["User"] = v;
return RedirectToAction("Index", "Course");
}
}
}
return View(u);
}
CourseController:
public class CourseController : Controller
{
private DetailsEntities db = new DetailsEntities();
//
// GET: /Course/
public ActionResult Index()
{
User user = (User)Session["User"];
//var usr = db.Users.Find(user.UserId);
//int userId = (int)Session["UserId"];
var user1 = db.Users.FirstOrDefault(u => u.UserId==user.UserId);
if (Session["User"] != null)
{
var course = db.UserCourses.Where(u => u.UserId == user1.UserId);
if (user1 != null)
return View(course);
}
return View(user1);
}
}
Index:
<table border="1" align="center" height ="200px" width ="100%" #*style ="background-color: darkgray"*#>
<tr>
<th>
#Html.DisplayNameFor(model => model.User.FirstName)
</th>
<th>
#Html.DisplayNameFor(model => model.User.LastName)
</th>
<th>
#Html.DisplayNameFor(model => model.User.Address)
</th>
<th>
#Html.DisplayNameFor(model => model.User.City)
</th>
<th>
#Html.DisplayNameFor(model => model.User.Email)
</th>
<th>
#Html.DisplayNameFor(model => model.User.PhoneNo)
</th>
<th></th>
</tr>
#foreach (var item in Model)
{
<tr>
<td>
#Html.DisplayFor(modelItem => item.User.FirstName)
</td>
<td>
#Html.DisplayFor(modelItem => item.User.LastName)
</td>
<td>
#Html.DisplayFor(modelItem => item.User.Address)
</td>
<td>
#Html.DisplayFor(modelItem => item.User.City)
</td>
<td>
#Html.DisplayFor(modelItem => item.User.Email)
</td>
<td>
#Html.DisplayFor(modelItem => item.User.PhoneNo)
</td>
</tr>
}
</table>
<p>
#Html.ActionLink("Create New", "Create")
</p>
<table border="1" align="left" height ="200px" width ="300px" #*style ="background-color: darkgray"*#>
<tr>
<th>
#Html.DisplayNameFor(model => model.Course.CourseName)
</th>
</tr>
#foreach (var item in Model) {
<tr>
<td>
#Html.DisplayFor(modelItem => item.Course.CourseName)
</td>
<td>
#Html.ActionLink("Edit", "Edit", new { id=item.Id }) |
#Html.ActionLink("Details", "Details", new { id=item.Id }) |
#Html.ActionLink("Delete", "Delete", new { id=item.Id })
</td>
</tr>
}
</table>
I know the question is silly but I am new at this so please help me.

use a model as IEnumerable and static in same view

Am trying to put together a view where it will generate a detail list from a table through code first and a strongly typed view but also allow the user to input data into through the model into the table.
So the first part is:
<table class="table">
<tr>
<th>
#Html.DisplayNameFor(model => model.Gender)
</th>
<th></th>
</tr>
#foreach (var item in Model)
{
<tr>
<td>
#Html.DisplayFor(modelItem => item.Gender)
</td>
<td>
#Html.ActionLink("Edit", "Edit", new { id = item.GenderID }) |
#Html.ActionLink("Details", "Details", new { id = item.GenderID }) |
#Html.ActionLink("Delete", "Delete", new { id = item.GenderID })
</td>
</tr>
}
</table>
The next part to enter a new gender would be:
<div>#Html.LabelFor(model => model.Gender)</div>
<div>#Html.EditorFor(model => model.Gender, new { htmlAttributes = new { #class = "div-form-control", id = "LkUpGender" } })</div>
<div>#Html.ValidationMessageFor(model => model.Gender, "", new { #class = "text-danger" })</div>
The problem is the first part requires:
IEnumerable<OrwellFrontEnd.LkUpModels.vwLkUpGender>
But the second part seems to not work with that and require:
OrwellFrontEnd.LkUpModels.vwLkUpGender
How can I make this work?