ASP.NET MVC CheckBox List sending always null - asp.net-mvc

I want to create a table with items and checkboxes to select these items. I am including these checkboxes in a list but this list is always returning null. Thank you very much for your help.
Controller:
public ActionResult Index()
{
var expenseTypesView = new ViewExpenseTypesAndSelection
{
ExpensesTypes = _context.ExpenseType.ToList(),
};
return View(expenseTypesView);
}
[HttpPost]
public ActionResult SelectExpensesTypes( ViewExpenseTypesAndSelection SelectedExpenses)
{
var entry = new userSpecificExpenses();
var i = 0;
foreach (var item in SelectedExpenses.SelectedExpenses)
{
if(item)
{
entry.expenseTypeId = i;
entry.UtilisateurId= User.Identity.GetUserId();
_context.UserspecificExpenses.Add(entry);
_context.SaveChanges();
}
i++;
}
return View();
}
View:
#model MBT.ViewModels.ViewExpenseTypesAndSelection
....
#using (Html.BeginForm("SelectExpensesTypes", "ExpenseTypes"))
{
<table class="table table-bordered table-hover">
<thead>
<tr>
<th class="text-center">Expense</th>
<th class="text-center">Include</th>
</tr>
</thead>
<tbody>
#{
for (int i = 0; i < Model.ExpensesTypes.Count; i++)
{
<tr>
<td>
<div class="checkbox">
#Model.ExpensesTypes[i].Type
</div>
</td>
<td>
<div class="checkbox">
#Html.CheckBoxFor(m => m.SelectedExpenses[i])
</div>
</td>
</tr>
}
}
</tbody>
</table>
<button type="submit" class="btn btn-primary">Submit</button>
}

You sending ViewExpenseTypesAndSelection almost null just with ExpensesTypes and then post it back to your post method. It means you send null and receive null.
So what is wrong with that?

Related

How to save the settings of an authentication id in ASP.NET MVC

I have made an tv-guide where you can see the programs for 5 channels. If you login you can also make an "personal" tvguide. where you can decide which of the 5 channels you are interested in seeing the tableau of, by clicking on their checkboxes. How can I make the application remember the user input. So let's say I log in and open the menu for Channel one (SVT1), and two (SVT2). Then I want these two channels also to be open next time I log in with that user id, how do I do that?
Screenshot of my personal tv-guide page
My controller
public class FavoritChannelsController : Controller
{
TvProgramDBEntities db = new TvProgramDBEntities();
[Authorize(Roles = "User")]
public ActionResult channel_index()
{
List<Full> model = new List<Full>();
var list = db.Full.Where(d => d.Date == "2018-11-12").ToList();
foreach (var item in list)
{
if (item.Id <1000)
{
var initedF = new Full
{
Channel = Regex.Replace(item.Channel, #"\s", ""),
Program = item.Program,
Time = item.Time,
Date = Regex.Replace(item.Date, #"\s", "")
};
model.Add(initedF);
}
}
return View(model);
}
}
My view
#model IEnumerable<Uppgift4.Models.Full>
#{
ViewBag.Title = "channel_Index";
var list = Model.ToList();
var list1 = list.Where(_ => _.Channel == "SVT1").Select(_ => _.Time +
_.Program).ToList();
var list2 = list.Where(_ => _.Channel == "SVT2").Select(_ => _.Time +
_.Program).ToList();
var list3 = list.Where(_ => _.Channel == "TV3").Select(_ => _.Time +
_.Program).ToList();
var list4 = list.Where(_ => _.Channel == "TV4").Select(_ => _.Time +
_.Program).ToList();
var list5 = list.Where(_ => _.Channel == "Kanal5").Select(_ => _.Time +
_.Program).ToList();
}
(_ => _.Date + " " +_.Time + _.Program).ToList();
<style>
.hiddenRow {
padding: 0 !important;
}
.in-line {
display: inline;
}
</style>
<br />
<table class="table table-condensed" style="border-collapse:collapse;">
<thead>
<tr>
<th>
<h3>TV-Tablå 2018-11-12</h3>
<b>Välj de kanaler du vill se tablån för</b>
</th>
<th>
</th>
</tr>
</thead>
<tbody>
<tr>
<td>
<input type="checkbox" data-toggle="collapse" data-target="div
[id*='demo1']" /><b> SVT1</b>
</td>
</tr>
#for (var i = 0; i < #list1.Count; i++)
{
<tr>
<td colspan="2" class="hiddenRow">
<div id="demo1+'#i'+" class="accordian-body collapse">
#list1[i]
</div>
</td>
</tr>
}
<tr data-toggle="collapse" data-target="#demo2">
<td>
<input type="checkbox" data-toggle="collapse" data-target="div
[id*='demo2']" /><b> SVT2</b>
</td>
</tr>
#for (var i = 0; i < #list2.Count; i++)
{
<tr>
<td colspan="2" class="hiddenRow">
<div id="demo2+'#i'+" class="accordian-body collapse">
#list2[i]
</div>
</td>
</tr>
}
<tr data-toggle="collapse" data-target="#demo3">
<td>
<input type="checkbox" data-toggle="collapse" data-target="div
[id*='demo3']" /><b> TV3</b>
</td>
</tr>
#for (var i = 0; i < #list3.Count; i++)
{
<tr>
<td colspan="2" class="hiddenRow">
<div id="demo3+'#i'+" class="accordian-body collapse">
#list3[i]
</div>
</td>
</tr>
}
<tr data-toggle="collapse" data-target="#demo4">
<td>
<input type="checkbox" data-toggle="collapse" data-target="div
[id*='demo4']" /><b> TV4</b>
</td>
</tr>
#for (var i = 0; i < #list4.Count; i++)
{
<tr>
<td colspan="2" class="hiddenRow">
<div id="demo4+'#i'+" class="accordian-body collapse">
#list4[i]
</div>
</td>
</tr>
}
<tr data-toggle="collapse" data-target="#demo5">
<td>
<input type="checkbox" data-toggle="collapse" data-target="div
[id*='demo5']" /><b> Kanal5</b>
</td>
</tr>
#for (var i = 0; i < #list5.Count; i++)
{
<tr>
<td colspan="2" class="hiddenRow">
<div id="demo5+'#i'+" class="accordian-body collapse">
#list5[i]
</div>
</td>
</tr>
}
</tbody>
</table>
My model (from my database table Full with entity framework)
namespace Uppgift4.Models
{
using System;
using System.Collections.Generic;
public partial class Full
{
public int Id { get; set; }
public string Channel { get; set; }
public string Program { get; set; }
public string Category { get; set; }
public string Date { get; set; }
public string Time { get; set; }
public string Length { get; set; }
}
}
By using following Command you can Get the UserId of the current user in controllers.
using Microsoft.AspNet.Identity;
.
.
.
User.Identity.GetUserId()
Use this Id to save/retrieve user choices. For example you can add following entity.
public class User_Channel
{
public int User_ChannelId { get; set; }
[MaxLength(128)]
public string UserId { get; set; }
public int ChannelId { get; set; }
}

.NET MVC JQuery function is not getting fired in table row click event

I have table data in UI. I want to display data in a div in the same page when I click the Details link in the row. The JQuery function is not getting fired in when I click on details link in any row.
Below is my code:
Model view class:
public class ItemViewModel
{
public Item item { get; set; }
public IEnumerable<Item> items { get; set; }
}
UI Code:
#model Medhub.Models.ItemViewModel
#{
ViewBag.Title = "View";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<h2>View</h2>
<p>
#Html.ActionLink("Create New", "CreateEdit", new { controller = "Item" }, new { #class = "btn btn-primary" })
</p>
<table align="center" height="10%" width="90%">
<tr>
<td>
<div id="Items">
<table style="vertical-align:top; height:200px" width="100%">
<tr style="height:20px">
<th>
#Html.DisplayName("Name")
</th>
<th>
#Html.DisplayName("Description")
</th>
<th>
#Html.DisplayName("Item Type")
</th>
</tr>
#if (Model != null)
{
foreach (var item in Model.items)
{
<tr style="height:15px">
<td>
#Html.HiddenFor(model => item.ItemId)
#Html.DisplayFor(model => item.Name)
</td>
<td>
#Html.DisplayFor(model => item.Description)
</td>
<td>
#Html.DisplayFor(model => item.Type)
</td>
<td>
#Html.ActionLink("Edit", "CreateEdit", new { id = item.ItemId }) |
#Html.ActionLink("Details", "Item", new { id = item.ItemId }) |
#Html.ActionLink("Delete", "Delete", new { id = item.ItemId })
</td>
</tr>
}
}
</table>
</div>
</td>
</tr>
</table>
<table>
<tr>
<td>
<div id="ItemDetails">
#if (Model.item != null)
{
Html.RenderPartial("Details", Model.item);
}
</div>
</td>
</tr>
</table>
<script type="text/javascript">
$(function () {
$("div.Items a").click(function (e) {
//e.preventDefault();
var url = this.ref;
$("#ItemDetails").load(url);
});
});
</script>
Controller code:
List<Item> items = new List<Item>();
// GET: Item
public ActionResult Item(int id = 0)
{
ItemViewModel itemVM = new ItemViewModel();
itemVM.items = GetItems();
if (id > 0)
itemVM.item = itemVM.items.FirstOrDefault(u => u.ItemId == id);
return View(itemVM);
}
Any clues?
First of all, you are waiting for clicks on a class called Items. This is the reason the jquery code is not being fired. You should have
$("div#Items a").click(function (e) {
Secondly, you need to check the attribut href, not ref. Also, prevent default needs to be there, otherwise you just reload your page
e.preventDefault();
var url = this.href;
You don't need the renderpartial in the page, just leave it empty:
<div id="ItemDetails">
</div>
While your logic kind of works, the way the url is loaded causes the entire page to be loaded into the ItemDetails section. I'd suggest that in your controller, you'd create a separate method for the details:
public ActionResult Details(int id) {
Item item = GetItem(id);
return View(item);
}
private Item GetItem(int id) {
return new Item() { Details = "details here" };
}

Posted model is null

I'm not sure what's wrong since I'm very new with MVC. This is a shopping cart. The customer is able to review their cart and edit quantity.
On the HttpPost ViewCart method, the cart is always empty, and number of lines is zero.
Controller:
public ActionResult ViewCart() {
var cart = (CartViewModel)Session["Cart"];
return View(cart);
}
[HttpPost]
public ActionResult ViewCart(CartViewModel cart) {
Session["Cart"] = cart;
return RedirectToAction("Order", "Checkout");
}
View:
#model CartViewModel
using (Html.BeginForm()) {
<h2>Your cart</h2>
<table>
<thead> ... </thead>
<tbody>
#foreach (var item in Model.Lines) {
<tr>
<td>#Html.DisplayFor(modelItem => item.Article.Description)</td>
<td>#Html.EditorFor(modelItem => item.Quantity)</td>
</tr>
}
</tbody>
</table>
<input type="submit" value="Checkout">
}
ViewModel:
public class CartViewModel {
public List<Line> Lines { get; set; }
public CartViewModel() {
Lines = new List<Line>();
}
}
Try changing the view to use indexes:
#model CartViewModel
using (Html.BeginForm()) {
<h2>Your cart</h2>
<table>
<thead> ... </thead>
<tbody>
#for (int i = 0; i < Model.Lines.Count; i++) {
<tr>
<td>#Html.DisplayFor(m => Model.Lines[i].Article.Description) #Html.HiddenFor(m => Model.Lines[i].Article.Id)</td>
<td>#Html.EditorFor(m => Model.Lines[i].Quantity)</td>
</tr>
}
</tbody>
</table>
<input type="submit" value="Checkout">
}

Post collection of selected values to server action

I have a form with a product-warranty list.
Each list item has checkbox.
How can I post a list of SelectecSources (warranties) to the server?
What do I have to change in that code?
The WarrantyPlusViewModel object is posted to the server. It contains a list SelectedSources which should contain the selected warranty articles.
Is it possible at all to use a complex object for the selected list?
Consider I have to post the WarrantyPlusViewModel to the server which includes
the SelectedSources property with the selected warranty objects.
#model WarrantyPlusViewModel
<div class="row">
<div class="col-md-10 col-md-offset-1">
#using (...)
{
<table class="table table-striped">
<tr>
<th></th>
<th>#Html.DisplayFor(m => m.ProductSelected.Name)</th>
<th>#Html.DisplayFor(m => m.ProductSelected.Description,l)</th>
<th>#Html.DisplayFor(m => m.ProductSelected.Price)</th>
</tr>
#foreach (var product in Model.ProductList)
{
<tr>
<td><input type="checkbox" name="SelectedSources" value="#product" /></td>
<td>#product.Name</td>
<td>#product.Description</td>
<td>#product.Price</td>
</tr>
}
</table>
<input type="submit" value="Save" />
#Html.HiddenFor(p => p.SerialNumber)
}
</div>
[HttpPost]
public virtual async Task<ActionResult> Save(WarrantyPlusViewModel viewModel)
{
return View(MVC.WarrantyPlus.WarrantyPlus.Views.OverviewWarrentyPlus, viewModel);
}
public class WarrantyPlusViewModel
{
// other properties
public List<WarrantyPlusProductViewModel> ProductList { get; set; }
public IEnumerable<WarrantyPlusProductViewModel> SelectedSources { get; set; }
}
It's really hard to bind this way. If you want to do it you should override Model Binder.
If i were on your place i will just use ProductId with some knowlege of list binding and come up with this solution:
#for (var i = 0; i < Model.ProductList.Count(); i++)
{
<tr>
<td><input type="checkbox" name="ProductList[" #i "].Id" value="#Model.ProductList[i].Id" /></td>
<td>#Model.ProductList[i].Name</td>
<td>#Model.ProductList[i].Description</td>
<td>#Model.ProductList[i].Price</td>
</tr>
}

bind a table on click event of button

I am working with ASP.NET MVC 3 Razor. I have a list method in controller, so want to bind this list to table on click event of a button. How will I achieve this functionality.
Here is my controller method:
public ActionResult getItnList(string scanCode)
{
List<List<String>> getitnDetails_List = getitnDetails(date, name);
ViewBag.getitnDetails = getitnDetails_List;
return Json(new { getitnDetails_List = getitnDetails_List }, JsonRequestBehavior. AllowGet);
}
Here is my view code:
#{
List<List<String>> str = (List<List<String>>)ViewBag.getitnDetails;
}
<table id="list" width="100%">
<td><b>Harvest Date</b></td>
<td><b>Product</b></td>
#for (int i = 0; i <= str.Count - 1; i++)
<td>#str[i][0].ToString()</td>
<td>#str[i][1].ToString()</td>
</table>
How will I bind this table to list on click event of button?
I'm not exactly sure what you are asking. But if you want to get the list on the click of a button you can use jQuery .getJSON (http://api.jquery.com/jQuery.getJSON/) to retrieve the list data and then insert it with javascript. Or you could render the list in the action and simply use json .get and insert the result.
Try this
View
<table>
<tr>
<th>
Name
</th>
<th>
PhoneNo
</th>
<th>
Address
</th>
<th>
Action
</th>
</tr>
#{var list = ViewBag.RegisterItems; }
#if (list != null)
{
foreach (var m in list)
{
<tr>
<td>
<input id="txtName-#m.ID.ToString()" type="text" class="hide" value="#m.Name.ToString()"/>
</td>
<td>
<input id="txtPhoneNo-#m.ID.ToString()" type="text" class="hide" value="#m.PhoneNo.ToString()"/>
</td>
<td>
<input id="txtAddress-#m.ID.ToString()" type="text" class="hide" value="#m.Address.ToString()"/>
</td>
</tr>
}
}
</table>
Controller
public ActionResult CustomerInfo()
{
ViewBag.RegisterItems = GetAllRegisterData();
return View();
}

Resources