MVC checkbox list bounding to model - asp.net-mvc-4

I am trying to collect all the options that the user have selected for a checkbox list. The checkbox list is built using a foreach loop and I have a int[] that I am trying to put the id into. Any help would be great.
View
#{
int idxFormats = 0;
foreach (var item in Model.ListOfFormats)
{
<div class='col-md-6'>
<input type="checkbox" value=#item.Value name="chkFormat" />
<label asp-for=#item.Selected>#Html.Raw(#item.Name)</label>
#Html.HiddenFor(m => Model.selectedFormats[idxFormats]);
</div>
idxFormats++;
}
#Html.ValidationMessageFor(model => model.selectedFormats[idxFormats])
}
Model
public List<GenericValues> ListOfFormats { get; set; }
[Display(Name = "At least one 'Format' must be selected")]
public int[] selectedFormats { get; set; }

Change the Checkbox name to selectedFormats
<input type="checkbox" value=#item.Value name="selectedFormats" />
Test example:
Model:
public class Test
{
public List<GenericValues> ListOfFormats { get; set; }
public int[] selectedFormats { get; set; }
}
public class GenericValues
{
public int Value { get; set; }
public string Name { get; set; }
public bool Selected { get; set; }
}
View:
#model Test
#{
ViewData["Title"] = "Index";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<h1>Index</h1>
<form method="post">
#{
foreach (var item in Model.ListOfFormats)
{
<div class='col-md-6'>
<input type="checkbox" value=#item.Value name="selectedFormats" />
<label asp-for=#item.Selected>#Html.Raw(#item.Name)</label>
</div>
}
}
<input type="submit" value="submit" />
</form>
Controller:
public IActionResult Index()
{
Test test = new Test
{
ListOfFormats = new List<GenericValues>
{
new GenericValues
{
Name = "A",
Value = 1,
},
new GenericValues
{
Name = "B",
Value = 2,
},
new GenericValues
{
Name = "C",
Value = 3,
}
}
};
return View(test);
}
[HttpPost]
public IActionResult Index(Test test)
{
return Ok();
}
Result:

if you are looking to put id as value of your idxFormats then use this code in your checkbox:
<input type="checkbox" value=#item.Value name="chkFormat" id="#idxFormats" />
Edit:
I am not so familiar with c#, I tested with minimum code :
// Replace the model correct path by yours
#model IEnumerable<WebApplication1.Models.MyModels.ListOfFormats>
#{
int idxFormats = 0;
foreach (var item in Model)
{
<div class='col-md-6'>
<input type="checkbox" value=#item.Value name="chkFormat" id="#idxFormats"/>
<label>#Html.Raw(#item.Name)</label>
</div>
idxFormats++;
}
}

Related

How Can I Update a row SelectList with Multiple Selected Value

I have a table named BookAuthors.
BookAuthor
Id | BookId | AuthorId
1 1 1
2 1 2
3 2 1
I want to update a book ( By the bookId). I have a problem. I take the value from the database but I can't set selectlist's selectedvalue with multiple authors.
In the BookController class
public IActionResult Update(int Id)
{
var model = new BookViewModel
{
Book = _bookService.GetById(Id),
Categories = _categoryService.GetListNotFirst(), // Get categories from the database
Author = _authorService.GetListNotFirst(), // Get Authors from the database
BookCategoriesList = _bookCategoryService.GetListByBookId(Id), //I get categories related to bookId.
BookAuthorsList = _bookAuthorService.GetListByBookId(Id) // I get authors related to bookId.
};
return View(model);
}
In the BookViewModel
public class BookViewModel
{
public Book Book { get; set; }
public List<Category> Categories { get; set; }
public List<Author> Author { get; set; }
public List<BookCategory> BookCategoriesList { get; set; }
public List<BookAuthor> BookAuthorsList { get; set; }
public string[] BookCategories { get; set; }
public string[] BookAuthors { get; set; }
}
Related part from the update view
<div class="form-group">
<label asp-for="BookAuthors">Author Name</label>
<select asp-for="BookAuthors" class="form-control" asp-items="#(new SelectList(Model.Author, "Id", "Name",<selectedvalue>))" multiple> // Model.Author is a List<Author> property
</select>
</div>
I tried to this
select asp-for="BookAuthors" class="form-control" asp-items="#(new SelectList(Model.Author, "Id", "Name",new[1,2] or new string["1,2"]))" multiple>
</select>
It didn't work. How can I solve this problem?
If you want to select multiple items,you need to hold down the control (ctrl) button.You can refer to the Usage Notes of the link.
Here is a demo:
View(TestMulitipleList.cshtml):
<form method="post">
<div class="form-group">
<label asp-for="BookAuthors">Author Name</label>
<select asp-for="BookAuthors" class="form-control" asp-items=#(new SelectList(Model.Author, "Id", "Name")) multiple >
</select>
</div>
<input type="submit" value="submit" />
</form>
Controller:
[HttpGet]
public IActionResult TestMulitipleList() {
BookViewModel b = new BookViewModel
{
Author = new List<Author> {
new Author{ Id=1, Name="author1"},
new Author{ Id=2, Name="author2"},
new Author{ Id=3, Name="author3"},
new Author{ Id=4, Name="author4"},
new Author{ Id=5, Name="author5"},
}
};
return View(b);
}
[HttpPost]
public IActionResult TestMulitipleList(BookViewModel b)
{
return Ok();
}
result:
Update:
If you want to bind the selected value,you can do like this:
<select asp-for="BookAuthors" class="form-control" multiple>
#foreach (var item in Model.Author)
{
if (item.Id == 1 || item.Id == 2)
{
<option selected value=#item.Id>#item.Name</option>
}
else
{
<option value=#item.Id>#item.Name</option>
}
}
</select>
result:

Partial view is return NULL on POSTBACK

My partial view is returning Null on submitting the form
The main view is not null, it contains values on the form submission, I'm using render partial to include the partial view. Passing the model to partial view as well, tried passing the model in partial view action result as well but the result was the same. Any help would be highly appreciated
Thanks
View
``` <div class="container">
#using (Html.BeginForm("Menu", "Booking", FormMethod.Post))
{
#Html.AntiForgeryToken()
<fieldset class="scheduler-border">
#*<div id="">
<input type="text" id="checkduplication" style="background: white; outline: none; border: none; border-color: transparent; color: red; font-weight: bold;" disabled />
</div>*#
<div class="form-group row">
#Html.HiddenFor(model => model.MenuID)
<label class="control-label col-sm-2"> Menu Name </label>
<div class="col-sm-4">
#Html.TextBoxFor(model => model.MenuName, new { #class = " form-control", #id = "FunctionName" })
#Html.ValidationMessageFor(model => model.MenuName)
</div>
<label class="control-label col-sm-2"> Menu Price </label>
<div class="col-sm-4">
#Html.TextBoxFor(model => model.MenuPrice, new { #class = " form-control", #id = "FunctionName" })
#Html.ValidationMessageFor(model => model.MenuPrice)
</div>
</div>
<div id="MyPartialContainer">
#if (Model.MenuItems != null)
{
foreach (var x in Model.MenuItems)
{
{ Html.RenderPartial("menuitems", x); }
}
}
</div>
<div class="row" style="float: right">
<input type="submit" id="submit" title="Save" value="Save" class="btn-success btn-lg" />
<input type="button" onclick="window.location.reload();" id="cancel" title="Cancel" value="Cancel" class="btn-cancel btn-lg" />
<br /> <br />
</div>
</fieldset>
}
</div> ```
Model Classes
``` public class VMMenu
{
public VMMenu()
{
MenuItems = new List<VMMenuItems> { new VMMenuItems() };
}
public int MenuID { get; set; }
public string MenuName { get; set; }
public string MenuPrice { get; set; }
//public int BookingDetailID { get; set; }
//public int PaymentDetailID { get; set; }
public IList<VMMenuItems> MenuItems { get; set; }
}
public class VMMenuItems
{
public int MenuItemID { get; set; }
public int? MenuID { get; set; }
public string ItemName { get; set; }
public string ItemPrice { get; set; }
public int? ItemCategory { get; set; }
public string ItemCategoryName { get; set; }
} ```
Action Methods
public ActionResult Menu() {
VMMenu menu = new VMMenu();
return View(menu);
}
[HttpPost]
public ActionResult Menu(VMMenu _MenuDetails)
{
if (ModelState.IsValid)
{
VMMenu VMMenu=new VMMenu();
Mapper.CreateMap<VMMenu,Menu>();
Mapper.CreateMap<VMMenuItems,MenuItem>();
Menu obj = Mapper.Map<VMMenu, Menu>(_MenuDetails);
BookingRepo _repo = new BookingRepo();
_repo.CreateMenu(obj);
return View();
}
return View();
}
public ActionResult menuitems()
{
return PartialView();
}

How to solve empty model trouble using both Ajax.BeginForm and Html.BeginForm in MVC

I am new to MVC and stuck in passing modal to controller.
I have read many similar threads in SO, to no avail.
Here, I have a view for entering order details.
User will enter order item details (using ajax.BeginForm) and when he clicks save, whole order will be saved in backend (using Html.BeginForm). Ajax.BeginForm is working properly and passing + displaying records properly. But Html.BeginForm is passing model as nothing.
Here is my code ...
My Models
public class OrderItemsModel
{
public string SrNo { get; set; }
public int? ItemCode { get; set; }
public string ItemName { get; set; }
public Decimal? Qty { get; set; }
public Decimal? Rate { get; set; }
public Decimal? Amount { get; set; }
}
public class OrderModel
{
public string OrderNumber { get; set; }
public string OrderDate { get; set; }
public int? CustomerCode { get; set; }
public string CustomerName { get; set; }
public string Note { get; set; }
//List of items selected in Order
public List<OrderItemsModel> ItemsSelected { get; set; }
}
Extract from My View
#model OrderApplication.Models.OrderModel
#{
ViewBag.Title = "Index";
Model.ItemsSelected = ViewBag.getlist;
}
#using (Ajax.BeginForm("UpdateItemList", "Order", new AjaxOptions { HttpMethod = "POST", UpdateTargetId = "selectedtable" }))
{
<h2 style="margin-left:5%;">Order Entry</h2>
//Order No & Date
<div class="row">
<div class="col-sm-6">
<div class="col-sm-3">
#Html.LabelFor(model => model.OrderNumber, "OrderNo"):
</div>
<div class="col-sm-3">
#Html.TextBoxFor(model => model.OrderNumber, new { #class = "form-control", #readonly = "readonly" })
</div>
</div>
<div class="col-sm-6">
<div class="col-sm-3">
#Html.LabelFor(model => model.OrderDate, "Date"):
</div>
<div class="col-sm-3">
#Html.TextBoxFor(model => model.OrderDate, new { #class = "form-control" })
</div>
</div>
</div>
<br />
//Table of entries
<div id="selectedtable">
#Html.Partial("_selectTable", Model);
</div>
<br />
}
#*Main Save*#
<div class="row">
<div class="col-sm-12">
<div class="col-sm-3">
#using (Html.BeginForm("SaveData", "Order", new { order = Model, id = "loginform", #class = "justify-content-center" }))
{
<input type="submit" value="Save Order" class="btn btn-success" />
}
</div>
<div class="col-sm-3">
<input type="button" class="btn btn-success" value="Clear Form" onclick="location.href='#Url.Action("Clear", "Order")'" />
</div>
</div>
</div>
My Controller
public class OrderController : Controller
{
public List<OrderItemsModel> dd = new List<OrderItemsModel>() ;
[HttpPost]
public ActionResult SaveData(OrderModel order, string id)
{
if (order == null) //order is always Nothing
{
return View(order);
}
if (order.CustomerCode == 0)
{
return View(order);
}
return View(order);
}
}
}
You shouldn't use both Ajax.BeginForm and Html.BeginForm, as it won't work. Please, check this post as might be of help to decide which one you wish to choose:
https://forums.asp.net/t/1757936.aspx?When+to+use+Html+BeginForm+vs+ajax+BeginForm
If you still want to use Html.BeginForm, just move the using sentence to replace your Ajax.BeginForm at the top of the page, so the form covers all fields, and the model won't be empty.

How to capture multiple checkboxes and radio buttons posted data by viewmodel ASP.Net MVC

i am new in MVC. so this is my html looks like
<form id='your-form' action='#Url.Action("Action","Controller")' method='post'>
<b>Gender</b><br />
<input type='radio' name='gender' value='Male' /> Male <br />
<input type='radio' name='gender' value='Female' /> Female <br />
<hr />
<b>Hobbies</b><br />
<input type='checkbox' name='hobbies' value='Reading' /> Reading <br />
<input type='checkbox' name='hobbies' value='Sports' /> Sports <br />
<input type='checkbox' name='hobbies' value='Movies' /> Movies <br />
<input type='submit' value='Update Profile' />
</form>
this way i am capturing data
public class HomeController : Controller
{
public ActionResult Index()
{
return View();
}
[HttpPost]
public ActionResult Index(string gender, string[] hobbies)
{
// Example output
var output = String.Format("The user's gender is <b>{0}</b> and they enjoy <b>{1}</b>", gender, String.Join(",", hobbies));
return Content(output);
}
}
but i like to know how could i capture it by viewmodel concept. anyone can help me with sample code. thanks
View models
public class HobbyVM
{
public int ID { get; set; }
public string Name { get; set; }
public bool IsSelected { get; set; }
}
public class PersonVM
{
....
public string Gender { get; set; } // would be better to use an enum
public List<HobbyVM> Hobbies { get; set; }
}
In the GET method, initialize an instance of the view model and pass it to the view
public ActionResult Create()
{
PersonVM model = new PersonVM()
{
Hobbies = new List<HobbyVM>()
{
new HobbyVM(){ ID = 1, Name = "Reading" },
new HobbyVM(){ ID = 2, Name = "Sports" },
....// etc these would actually be loaded from a repository
}
};
return View(model);
}
[HttpPost]
public ActionResult Create(PersonVM model)
{
// map you view model to a instance of your data model
// save and redirect
}
View
#model PersonVM
#Html.BeginForm())
{
....
<label>
#Html.RadioButtonFor(m => m.Gender, "Male", new { id = "" })
<span>Male</span>
</label>
<label>
#Html.RadioButtonFor(m => m.Gender, "Female", new { id = "" })
<span>Female</span>
</label>
for(int i = 0; i < Model.Hobbies.Count; i++)
{
#Html.HidenFor(m => m.Hobbies[i].ID)
#Html.CheckBoxFor(m => m.Hobbies[i].IsSelected)
#Html.LabelFor(m => m.Hobbies[i].IsSelected, Model.Hobbies[i].Name)
}
<input type="submit" />
}

Saving multiple records on submit click into differnt entities in MVC4. Not getting values from view in Controller

I am trying to save the class attendance for multiple students on click of submit button. I am able to create the blank records in the concern tables and then populate the data in view.
I have the following view model:
public class TeacherAttendanceModel
{
#region Required Properties
public long ScholarAttendanceId { get; set; }
public string Student { get; set; }
public bool Absent { get; set; }
public string AbsentComment { get; set; }
public bool Uniform { get; set; }
public bool Homework { get; set; }
public string HomeworkComment { get; set; }
public String UniformCommentSelected { get; set; }
public IEnumerable<String> UniformComment { get; set; }
#endregion
}
My Controller is as below.
public class TeacherAttendanceController : Controller
{
//
// GET: /TeacherAttendance/
public ActionResult Index()
{
long classId = Success.Business.Roles.Teacher.GetHomeRoomClassID(Convert.ToInt64(Session[GlobalVar.LOGGED_IN_ID]));
var classAttendanceStatus = Success.Business.Entities.ClassAttendance.GetClassAttendanceStatus(classId);
ViewBag.status = classAttendanceStatus;
var attendanceData = TeacherAttendance.CreateClassAttendance(classId);
return View(attendanceData);
}
[HttpPost]
public ActionResult Index(IEnumerable<TeacherAttendanceModel> teacherAttendanceModel)
{
try
{
if (ModelState.IsValid)
{
TeacherAttendance.SaveAttendance(teacherAttendanceModel);
}
}
catch (Exception e)
{
}
return View(teacherAttendanceModel);
}
}
Get Index is working fine. But I am not getting the TeacheAttendanceModel object in Post index. I get null object. I would be thank full to get any help in this regards. How to update the multiple records of attendance on submit click?
I am using the following View:
#foreach (var item in Model) {
<tr >
<td style="border-style:solid; border-color:darkslategray; border-width:thin;">
#Html.DisplayFor(modelItem => item.Student)
</td>
<td style="border-style:solid; border-color:darkslategray; border-width:thin;">
#Html.CheckBoxFor(modelItem => item.Absent, ViewBag.status == 2 ? new {disabled = "disabled"} : null)
#Html.TextBoxFor(modelItem => item.AbsentComment, ViewBag.status == 2 ? new {disabled = "disabled"} : null)
</td>
<td style="border-style:solid; border-color:darkslategray; border-width:thin;">
#Html.CheckBoxFor(modelItem => item.Uniform, ViewBag.status == 2 ? new {disabled = "disabled"} : null)
#Html.DropDownListFor(modelItem => item.UniformCommentSelected, new SelectList(item.UniformComment),item.UniformCommentSelected ?? "---Select---", ViewBag.status == 2? new {disabled = "disabled"} : null)
</td>
<td style="border-style:solid; border-color:darkslategray; border-width:thin;">
#Html.CheckBoxFor(modelItem => item.Homework, ViewBag.status == 2 ? new {disabled = "disabled"} : null)
#Html.TextBoxFor(modelItem => item.HomeworkComment, ViewBag.status == 2? new {disabled = "disabled"} : null)
</td>
</tr>
}
Model:
public class Test
{
public List<string> UniformComment { get; set; }
}
Controller:
public ActionResult Index()
{
var model = new Test
{
UniformComment = new List<string>{ "one", "two", "three" }
};
return View(model);
}
[HttpPost]
public ActionResult Index(Test model)
{
return View(model);
}
View:
#using (Html.BeginForm())
{
for (var i = 0; i < Model.UniformComment.Count; i++)
{
#Html.TextBoxFor(x => Model.UniformComment[i])
}
<input type="submit" value="Save" />
}
Rendered html example:
<input id="UniformComment_0_" name="UniformComment[0]" type="text" value="one" />
<input id="UniformComment_1_" name="UniformComment[1]" type="text" value="two" />
<input id="UniformComment_2_" name="UniformComment[2]" type="text" value="three" />
The idea is iterate with for loop or create EditorTemplate and then you receive indexed items.
Added (Feel the difference):
View:
#using (Html.BeginForm())
{
foreach (var comment in Model.UniformComment)
{
#Html.TextBoxFor(x => comment)
}
<input type="submit" value="Save" />
}
Rendered html:
<input id="comment" name="comment" type="text" value="one" />
<input id="comment" name="comment" type="text" value="two" />
<input id="comment" name="comment" type="text" value="three" />
Use a IList instead of IEnumerable in the view and replace the foreach loop with a for loop.
Step 1:
Use
#model IList<TeacherAttendanceModel>
instead of
#model IEnumerable<TeacherAttendanceModel>
Step 2:
Use
#for (var i = 0; i < Model.Count; i++)
instead of
#foreach (var item in Model)
Refer How to pass IEnumerable list to controller in MVC including checkbox state? for more details.