I'm making an attendance panel for the students that are enrolled in the particular batch. For that I'm displaying the records of the students along with the number of checkboxes according to the number of classes assigned for that batch. Everything is displayed correctly, However checkboxes of only one row carry values to the post, and rest of the checkboxes in other rows are not posted. The student details for each row is posting correcting in a list.
Below is my code
StudentAttendance.cs
public class StudentAttendance
{
public List<Models.User> userlist { get; set; }
public List<Models.Days> days { get; set; }
}
InstructorController.cs
public ActionResult AssignedStudents(string id)
{
Models.StudentAttendance viewmodel = new Models.StudentAttendance();
//viewmodel.studentbatch = new Models.StudentBatch();
//viewmodel.user = new Models.User();
Context.Instructor instructor = new Context.Instructor();
viewmodel.userlist = new List<Models.User>();
viewmodel.days = new List<Models.Days>();
viewmodel.userlist = instructor.lstAssignedStudents(id);
Context.Batches contBatch = new Context.Batches();
var days = contBatch.SelectDays(id);
int totaldays = contBatch.CalculateDays(days);
var duration = contBatch.GetallBatchList().Where(p => p.Id == id);
var batchduration = (from c in duration where c.Id == id select c.Duration).ToList();
string d = batchduration[0].ToString();
int totalduration = contBatch.GetBatchDuration(d);
int TotalCheckBoxes = totalduration * totaldays;
List<string> getdays = contBatch.getdaysinList(days, totalduration);
List<Models.Days> day = new List<Models.Days>();
for (int i = 0; i < TotalCheckBoxes; i++)
{
day.Add(new Models.Days { dayid = i, dayname = getdays[i], ischecked = false });
}
viewmodel.days = day;
return View(viewmodel);
}
[HttpPost]
public ActionResult MarkAttendance(Models.StudentAttendance viewmodel)
{
Models.StudentAttendance viewmodel1 = new Models.StudentAttendance();
//viewmodel.studentbatch = new Models.StudentBatch();
//viewmodel.user = new Models.User();
return View();
}
AssignedStudents.cshtml
#model WebApplication1.Models.StudentAttendance
#{
ViewBag.Title = "AssignedStudents";
}
<h2>AssignedStudents</h2>
<p>
#Html.ActionLink("Create New", "Create")
</p>
#using (Html.BeginForm("MarkAttendance","Instructor", FormMethod.Post))
{
<table class="table">
<tr>
<th>#Html.DisplayName("First Name")</th>
<th>#Html.DisplayName("Last Name")</th>
</tr>
#for (int j = 0; j < Model.userlist.Count; j++)
{
<tr>
<td>#Html.HiddenFor(m=>Model.userlist[j].Id)</td>
<td>#Html.EditorFor(m => Model.userlist[j].FirstName)</td>
<td>#Html.EditorFor(m => Model.userlist[j].LastName)</td>
#for (int i = 0; i < Model.days.Count; i++)
{
<td>
#Html.CheckBoxFor(m => Model.days[i].ischecked)
#Model.days[i].dayname
#Html.HiddenFor(m => Model.days[i].dayid)
#Html.HiddenFor(m => m.days[i].dayname)
</td>
}
</tr>
}
</table>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" id="Attendance" value="Create" class="btn btn-default" />
</div>
</div>
}
Solved the issue using viewmodel as a List in the controller class.
StudentAttendance.cs
List<DayVM> days = new List<DayVM>
{
new DayVM(),
new DayVM()
};
List<StudentVM> model = new List<StudentVM>
{
new StudentVM{ Id = 1, FirstName = "Bob", Days = days },
new StudentVM{ Id = 2, FirstName = "john", Days = days },
}
return View(model);
and inside view
#for(int i = 0; i < Model.Count; i++)
{
... elements for properties of Student
#for(int j = 0; j < Model[i].Days.Count; j++)
{
#Html.CheckBoxFor(m => m[i].Days[j].IsSelected)
....
}
}
and taking List for collecting values in the post action
public ActionResult MarkAttendance(List<Models.StudentVM> lst)
{
.....
}
All thanks to Stephen Muecke who made it easy.
Related
Description
I'm am creating a dynamic table where the user can select regions in a dropdown lists. On "add" the user can also add new table rows with region dropdown lists included. On POST, a list of Regions should be posted to the controller where it´s being saved to the SavingPlan model.
Problem
Ajax is returning null to my controller even though I have saved selected option-data to string arrays which is being posted to the controller.
Addition
I am fairly new to ASP.NET MVC so please have that in mind when commenting. I am open minded towards doing things differently but I´d very much appreciate I someone would be able to guid me and my code in the right direction.
Region Model
public class Region
{
public int Id { get; set; }
public string Name { get; set; }
}
Saving Plan Model
public SavingPlan()
{
}
public SavingPlan(List<Region> regionList)
{
RegionList = regionList;
}
public int Id { get; set; }
public ApplicationUser AssessmentUser { get; set; }
public IEnumerable<Region> RegionLookUp { get; set; }
public bool IsActive { get; set; }
public byte RegionId { get; set; }
public Region Region { get; set; }
public List<Region> RegionList { get; set; }
}
SavingPlan - ViewModel
public class SavingPlan
{
public SavingPlan()
{
}
public SavingPlan(List<Region> regionList)
{
RegionList = regionList;
}
public int Id { get; set; }
public ApplicationUser AssessmentUser { get; set; }
public IEnumerable<Region> RegionLookUp { get; set; }
public bool IsActive { get; set; }
public byte RegionId { get; set; }
public Region Region { get; set; }
public List<Region> RegionList { get; set; }
}
Controller Action GET - NewSavingPlan
public ActionResult NewSavingPlan()
{
SavingPlanAssessmentView viewModel = new SavingPlanAssessmentView();
viewModel.SavingPlan = new SavingPlan();
var regions = _context.Regions
.ToList();
viewModel.RegionLookUp = regions;
return View(viewModel);
}
Controller Action POST - Save SavingPlan
[HttpPost]
public JsonResult SaveList(string RegionList)
{
var urlBuilder = new UrlHelper(Request.RequestContext);
var url = urlBuilder.Action("Index", "Assessments");
string[] arr = RegionList.Split(',');
foreach (var item in arr)
{
var region = item;
}
return Json(new { status = "success", redirectUrl = Url.Action("Index","Home") });
}
SavingPlan Partial View
#model BBRG.ViewModels.SavingPlanAssessmentView
<h2>#Model.Heading</h2>
#*#using (Html.BeginForm("Save", "Assessments", FormMethod.Post))
{*#
#*#Html.AntiForgeryToken()
#Html.HiddenFor(m => m.Id)*#
<legend>Saving Plan</legend>
<table id="regionTable" class="table table-striped">
<thead>
<tr>
<td>Region</td>
<td> <button id="add" type="button" class="btn btn-link">Add</button></td>
<td></td>
</tr>
</thead>
<tbody>
<tr id="regionRow_1">
<td>
#Html.DropDownListFor(m => m.RegionId, new SelectList(Model.RegionLookUp, "Id", "Name"), "Select Region", new { #class = "form-control Region", id = "Region_1", type="string", name = "Region", selected="false" })
</td>
<td>
<button data-region-id="#Model.RegionId" id="deleteRegion" type="button" class="btn btnDeleteRegion btn-link btn-xs btn" btn-xs>remove</button>
</td>
</tr>
</tbody>
</table>
<hr />
<p>
#Html.HiddenFor(m => m.Id)
<button data-saving-id="#User.Identity" onclick="saveRegion()" type="submit" calss="btn btn-default js-toggle-save">Save</button>
</p>
Jquery - Add new table row with dropdownlist
$(document).ready(function () {
var counter = 2;
$(function () {
$('#add').click(function () {
$('<tr id="regionRow_' + counter + '">'
+ '<td>'
+ '<select type="text" value="RegionId" name="Region" id="Region_'+ counter+'" class="form-control Region" " >'
+ $(".Region").html()
+ '</select>'
+ '</td>'
+ '<td>'
+ '<button data-region-id= id="deleteRegion" type="button" class="btn btnDeleteRegion btn-link btn-xs btn" btn-xs>remove</button>'
+ '</td>'
+ '</tr>').appendTo('#regionTable');
counter++;
return false;
});
});
});
Jquery and .ajax for POST
{
<script src="~/Scripts/SavingPlanScripts.js"></script>
<script>
var saveRegion = (function () {
var array = [];
var commaSeperated = "";
var count = 1;
$("#regionTable tbody .Region").each(function (index, val) {
var regionId = $(val).attr("Id");
var arr = regionId.split('_');
var currentRegionId = arr[1];
var isSelected = $(".Region option").is(':selected', true);
if (isSelected) {
array.push(currentRegionId);
}
count++;
});
if (array.length != 0) {
commaSeperated = array.toString();
$.ajax({
type: "POST",
dataType: "json",
contentType: "/application/json",
url: "/SavingPlans/SaveList",
data: { "RegionList": commaSeperated },
success: function (json) {
if (json.status == "success") {
window.location.href = json.redirectUrl;
};
}
});
};
});
</script>
}```
I found the solution to my problem, I forgot to stringify my .ajax data. If anyone still want to provide me with some constructive input, please don´t hesitate.
$.ajax({
url: "../SavingPlans/SaveList",
data: JSON.stringify({ RegionId: commaSeperated }),
type: "POST",
dataType: "json",
contentType: 'application/json; charset=utf-8',
success: function (json) {
if (json.status == "success") {
window.location.href = json.redirectUrl;
};
}
});
I am trying to show the employee details in a table. I created a model class EmployeeDetail, an EmployeeController and a view in EmployeeDetails.cshtml, plus a class for accessing the database.
EmployeeDetails is my model class:
[Serializable]
public class EmployeeDetails
{
private int _eid;
private string _ename;
private string _eaddress;
private string _gender;
private string _emobileno;
private bool _status;
private DateTime _ejoiningdate;
private DateTime _eleavedate;
#region ================= Code start for public variable =========================
[DataObjectField(true,true,false)]
public int eid {
get { return _eid; }
set { _eid = value; }
}
[DataObjectField(true, true, false)]
public string ename
{
get { return _ename; }
set { _ename = value; }
}
[DataObjectField(true, true, false)]
public string eaddress
{
get { return _eaddress; }
set { _eaddress = value; }
}
[DataObjectField(true, true, false)]
public string gender
{
get { return _gender; }
set { _gender = value; }
}
[DataObjectField(true, true, false)]
public string emobileno
{
get { return _emobileno; }
set { _emobileno = value; }
}
[DataObjectField(true, true, false)]
public bool status
{
get { return _status; }
set { _status = value; }
}
[DataObjectField(true, true, false)]
public DateTime ejoiningdate
{
get { return _ejoiningdate; }
set { _ejoiningdate = value; }
}
[DataObjectField(true, true, false)]
public DateTime eleavedate
{
get { return _eleavedate; }
set { _eleavedate = value; }
}
#endregion ==================== code end for public variable =================
}
Here is my EmployeeController:
public class EmployeeController : Controller
{
// GET: /Employee/
private Employeecon db = new Employeecon();
public ActionResult EmployeeDetails()
{
var studentList = new List<EmployeeDetails>{
new EmployeeDetails() { eid = 1, ename = "John", eaddress = "teszxs" } ,
new EmployeeDetails() { eid = 2, ename = "Steve", eaddress = "jfdsk" } ,
new EmployeeDetails() { eid = 3, ename = "Bill", eaddress = "jfdsk" } ,
new EmployeeDetails() { eid = 4, ename = "Ram" , eaddress = "jfdsk" } ,
new EmployeeDetails() { eid = 5, ename = "Ron" , eaddress = "jfdsk" } ,
new EmployeeDetails() { eid = 4, ename = "Chris" , eaddress = "jfdsk" } ,
new EmployeeDetails() { eid = 4, ename = "Rob" , eaddress = "jfdsk" }
};
return View();
}
}
I created EmployeeDetails.cshtml as a Razor view:
#model IEnumerable<Employee.Models.EmployeeDetails>
<html>
<head>
<title>Employee Details</title>
</head>
<body>
<div align="center">
<b> Employee Details</b>
</div>
<div align="right">
<p>
#Html.ActionLink("New Employee", "NewEmployee")
</p>
</div>
<table align="center" cellpadding="5" cellspacing="5" style="border:1px thin
black;" frame="box">
<tr>
<th>
Name
</th>
<th>
Address
</th>
<th>
Mobile no
</th>
<th>
Joining Date
</th>
</tr>
#foreach(var r in Model)
{
<tr>
<td>
#* #r.ename;*#
#Html.DisplayNameFor(m => r.ename); //but when I am declaring like that its showing error the call is ambiguous between the following methods or properties
</td>
</tr>
<tr>
<td>
#*#r.eaddress;*#
#Html.DisplayNameFor(m => r.eaddress);
</td>
</tr>
<tr>
<td>
#* #r.emobileno;*#
#Html.DisplayNameFor(m => r.emobileno);
</td>
</tr>
<tr>
<td>
#* #r.ejoiningdate;*#
#Html.DisplayNameFor(m => r.ejoiningdate);
</td>
</tr>
}
</table>
</body>
</html>
I am creating a separate folder for data access. I created a data context file Employeecon.cs:
public class Employeecon : DbContext
{
public Employeecon() : base("EmployeeContext")
{
}
public DbSet<EmployeeDetails> emp { get; set; }
}
And I added a connection string to the web.config file:
<add name="EmployeeContext"
connectionString="Data Source=LEVIOZA;Initial Catalog=Manali;Persist Security Info=True;User ID=sa;Password=pedcall"
providerName="System.Data.SqlClient" />
I want to connect to a SQL Server database, instead of local db, or I don't want to create database in the App_Data folder. Like we are did in the asp.net using SQL Server we pass the connection string using SqlConnection like that.
I am trying to connect but I don't know if it's working or not .
I don't know whats wrong with this program. I am trying to learn ASP.NET MVC and this is my first try. Please help me.
So you actually did a good job so far, let me point you to the rest.
Firstly, with database connection a side, you did created a simulation of data, which i assume you wonder why they did not shown in the view.
This is because you did not asked the controlled to use your data as model for the view. Yes, you did specify which type the model is, but you didn't supply it with data.
To fix it, pass the View() method the model instance you want, so it can bind it together.
return View(studentList);
Secondly, you want to extract those information from database, you only lacking querying the information you want from database and return it as model.
For example, lets create another url called /EmployeeDetailsFromDb
public ActionResult EmployeeDetailsFromDb()
{
var studentList = db.EmployeeDetails; // .EmployeeDetails should be changed to the table\dataset you want.
return View(studentList);
}
This will work, assuming the EmployeeDetails(if exists) is actually a collection of EmployeeDetails entities, which is what the view .cshtml expects.
why my controller gets the null value for Address, Phone, UserName, Email?
When i debug, Payment2 POST has received id from view and has a value.
My controller:
[HttpGet]
public ActionResult Payment2(int id)
{
model md = new model();
var pm = new paymentmodel();
var cart = Session[CartSession];
if (cart != null)
{
md.v1 = (List<CartItemModel>)cart;
}
md.v2 = pm.userdetails(id);
return View(md);
}
[HttpPost]
public ActionResult Payment2(int id, User c)
{
var cart = (List<CartItemModel>)Session[CartSession];
foreach (var item in cart)
{
if (item.quantity > item.Product.suspended)
{
return Redirect("/loi-so-luong");
}
}
var oder = new HoaDon();
oder.Date = DateTime.Now;
oder.Address = c.Address;
oder.Phone = c.Phone;
oder.TenNguoiNhan = c.UserName;
oder.E_mail = c.Email;
}
return Redirect("/hoan-thanh");
}
NULL with Address, Phone, UserName, Email
My model.cs:
public class model
{
public List<CartItemModel> v1 { set; get; }
public List<get_customer_Result> v2 { set; get; }
}
My paymentmodel:
public class paymentmodel
{
KINHDOANHVLXDEntities ke = new KINHDOANHVLXDEntities();
public List<get_customer_Result> userdetails(int id)
{
var ln = ke.get_customer(id);
return ln.ToList();
}
}
My index view:
#model List<thuctaplan2.Models.CartItemModel>
#using thuctaplan2.Common
#{
ViewBag.Title = "Index";
Layout = "~/Views/Shared/_Layout.cshtml";
var session = (UserLogin)Session[CommonConstants.USER_SESSION];
}
Thanh Toán
My Payment2 View:
#model thuctaplan2.Models.model
#{
ViewBag.Title = "Thanh Toán";
Layout = "~/Views/Shared/_Layout.cshtml";
}
#using (Html.BeginForm("Payment2", "Cart", FormMethod.Post))
{
foreach (var item in Model.v2)
{
<div class="form-group">
<label>Name</label>
<label>#item.UserName</label>
</div>
<div class="form-group">
<label>Phone</label>
<label>#item.Phone</label>
</div>
<div class="form-group">
<label>Address</label>
<label>#item.Address</label>
</div>
<div class="form-group">
<label>E-mail</label>
<label>#item.Email</label>
</div>
}
<button type="submit" class="btn">Send</button>
}
What is happening here based on your code is that when you render your view, all your controls inside your Form is empty or with no value, in short, null. Why? Because you only render label html elements inside your Form.
In order to have a value, add a textbox like this:
#Html.TextBoxFor(modelItem => item.UserName, new { #class = "form-control" })
So that when you submit your Form, your User model properties like UserName will have a value. If this are all labels only, no value will be passed to your controller.
I am new to TypeScript , please help for the problem below about invalid date in Chrome.
I have a ListViewModel and has code as :
module ListView {
export class ListViewModel{
public createdDate: Date;
public name: string;
constructor(listId:number) {
for(var i = 0; i < dataContext.List.length; i++) {
if(listId == dataContext.List.id){
// PROBLEM IS HERE:
this.createdDate = dataContext.Lists[i].createdDate;
this.name = dataContext.Lists[i].name;
}
}
}
}
}
and I have a controller which to get all list for my view, like
module ListController {
public aList : Array<ListViewModel>;
export class ListController(){
aList = [];
for(var i = 0; i < 2; i++) {
var newList = new ListViewModel(i);
aList.push(newList);
}
}
}
and dataContext is created manually in run.ts file , like :
Lists : [
new List(1, new Date(2014,1,2), "test1"),
new List(1, new Date(2014,06,07),"test2")
]
and I want to show the list in HTML and i have alread correctly set controller = ListController for this page , like :
<ul>
<li ng-repeat="n in aList">
<label>Name: {{n.name}}</label>
<label>Date: {{n.createdDate}}</label>
</li>
</ul>
The problem is : the list does not display , but in Chrome Console there is no any error.
When debug into ListModelView, this.createdDate = dataContext.Lists[i].createdDate; is an invalid date, but name is correctly set.
Thanks a lot for having a look.
I suspect the issue is as follows:
var date = new Date(2014,06,07);
Your literals 06 and 07 are octals, not decimal numbers.
To create a date, use decimals, like this:
var date = new Date(2014, 6, 7);
Browsers typically sort this out for you, but the TypeScript compiler will complain about this if you are targeting ECMAScript 5 or above.
If it isn't the compiler warning you are having trouble with, you can revisit your code to solve the simple syntactical issues that TypeScript should also be warning you about (it certainly warned me when I took your examples).
Here is a rudimentary running version, with some bits reverse engineered out of your question. I have given it a quick spin in Chrome and the date is logged correctly.
class List {
constructor(public id: number, public createdDate: Date, public name: string) {
}
}
var dataContext = {
Lists : [
new List(1, new Date(2014,1,2), "test1"),
new List(1, new Date(2014,6,7),"test2")
]
};
module ListView {
export class ListViewModel {
public createdDate: Date;
public name: string;
constructor(listId:number) {
for(var i = 0; i < dataContext.Lists.length; i++) {
console.log(dataContext.Lists[i].createdDate);
if(listId == dataContext.Lists[i].id) {
// PROBLEM IS HERE:
this.createdDate = dataContext.Lists[i].createdDate;
this.name = dataContext.Lists[i].name;
}
}
}
}
}
module ListController {
export var aList : Array<ListView.ListViewModel>;
export class ListController{
public aList = [];
constructor() {
for(var i = 0; i < 2; i++) {
var newList = new ListView.ListViewModel(i);
aList.push(newList);
}
}
}
}
var lv = new ListView.ListViewModel(1);
The snippet with the compiled JavaScript output is below (albeit I changed it to log to the visible page, rather than the console):
var List = (function () {
function List(id, createdDate, name) {
this.id = id;
this.createdDate = createdDate;
this.name = name;
}
return List;
})();
var dataContext = {
Lists: [
new List(1, new Date(2014, 1, 2), "test1"),
new List(1, new Date(2014, 06, 07), "test2")]
};
var ListView;
(function (ListView) {
var ListViewModel = (function () {
function ListViewModel(listId) {
for (var i = 0; i < dataContext.Lists.length; i++) {
document.getElementById('output').innerHTML += dataContext.Lists[i].createdDate + '<br />';
if (listId == dataContext.Lists[i].id) {
// PROBLEM IS HERE:
this.createdDate = dataContext.Lists[i].createdDate;
this.name = dataContext.Lists[i].name;
}
}
}
return ListViewModel;
})();
ListView.ListViewModel = ListViewModel;
})(ListView || (ListView = {}));
var ListController;
(function (_ListController) {
_ListController.aList;
var ListController = (function () {
function ListController() {
this.aList = [];
for (var i = 0; i < 2; i++) {
var newList = new ListView.ListViewModel(i);
_ListController.aList.push(newList);
}
}
return ListController;
})();
_ListController.ListController = ListController;
})(ListController || (ListController = {}));
var lv = new ListView.ListViewModel(1);
<div id="output"></div>
MyModels
public class ExpenseEntryItems
{
public List<ExpenseEntryModel> NewItemList { get; set; }
public List<SelectListItem> PaymentMethodList { get; set; }
public List<SelectListItem> ActionList { get; set; }
}
public class ExpenseEntryModel
{
[Display(Name = "Payment Method")]
public string PaymentMethod { get; set; }
[Display(Name = "Action")]
public string Action { get; set; }
}
MyView
#model REMClient.Models.ExpenseEntryItems
#using (Html.BeginForm("SubmitForm", "Expenses", FormMethod.Post, new { enctype = "multipart/form-data", id = "frmFileUpload" }))
{
#foreach (var i=0; i<Model.NewItemList.Count; i++)
{
#Html.DropDownListFor(modelItem => modelItem.NewItemList[i].PaymentMethod, new SelectList(Model.PaymentMethodList, "Value", "Text", Model.NewItemList[i].PaymentMethod), new { #class = "obj grid", id = "ddlPayMethod_" + Model.NewItemList[i].ExpDetailId })
#Html.DropDownListFor(modelItem => modelItem.NewItemList[i].Action, new SelectList(Model.ActionList, "Value", "Text", Model.NewItemList[i].Action), new { #class = "obj grid", id = "ddlAction_" + Model.NewItemList[i].ExpDetailId })
}
}
In controller I am populating the inner model list with values.
in the view, it load the first value of the list and set as a selected value for the remaining
dropdownlistfor in the grid
but it is displaying the values in view but not get the list value in controller after post if I implementing the dropdownlistfor as follows as
#using (Html.BeginForm("SubmitForm", "Expenses", FormMethod.Post, new { enctype = "multipart/form-data", id = "frmFileUpload" }))
{
#foreach (var i=0; i<Model.NewItemList.Count; i++)
{
string payment = Model.NewItemList[i].PaymentMethod;
string action = Model.NewItemList[i].Action;
#Html.DropDownListFor(modelItem => payment , new SelectList(Model.PaymentMethodList, "Value", "Text", payment ), new { #class = "obj grid", id = "ddlPayMethod_" + Model.NewItemList[i].ExpDetailId })
#Html.DropDownListFor(modelItem => action , new SelectList(Model.ActionList, "Value", "Text", action ), new { #class = "obj grid", id = "ddlAction_" + Model.NewItemList[i].ExpDetailId })
}
}
Please suggest me a correct way of implementation