pass table values from view to controller mvc - c#

I am working on a project in dot Net + share-point,
In there controller get sharepoint list record & create a list of list object.
In view catch the object as one model and dilplay in a table.
Table view
enter image description here
Index.cshtml
#using( Html.BeginForm() )
{
<table id = "timeTrackingView" border="1" >
<tr>
<th>Projects</th>
#for (var date = #Model.Dates.AddDays(-(#Model.DateRange-1)); date <= #Model.Dates; date = date.AddDays(1))
{
<th >#date.Day/#date.Month/#date.Year</th>
}
</tr>
#{ double[] totalForToday = new double[#Model.DateRange];}
#for (int i = 0; i < #Model.TimeTrakings.Count; i++)
{
//var projectName = #Model.TimeTrakings[i][0].ProjectName;
int index = 0;
<tr>
<td>
#Model.TimeTrakings[i][0].ProjectName
</td>
#for (int j = 0; j < Model.TimeTrakings[i].Count(); j++)
{
totalForToday[index] = totalForToday[index] + #Model.TimeTrakings[i][j].Hours;
var time = #Html.EditorFor(model => #Model.TimeTrakings[i][j]);
<td>#time</td>
#*#Html.EditorFor(model => #Model.TimeTrakings[i][j].Hours)*#
index++;
}
</tr>
}
<tr>
<td>Total for day</td>
#foreach(var tot in totalForToday)
{
<td>#tot</td>
}
</tr>
</table>
<input type="submit" name="SubmitBtn"/>
}
I am trying to get table data into controller.. help me im my code only gettinh hours, need get project name date & hours together.
My controller.
[HttpPost]
public ActionResult Index(TimeTracking timeTracking)
{
////do the logic here
return View(this.ReceiveTimeTrackingData());
}
I Used two mode-:
Model1
public class TimeTrackingDetails
{
public string ProjectName { get; set; }
public DateTime Date { get; set; }
public double Hours { get; set; }
}
Model 2-:
public class TimeTracking
{
public List<List<TimeTrackingDetails>> TimeTrakings { get; set; }
}

If you need project name you should create an input. Now in your code you have just plain text with this line:
#Model.TimeTrakings[i][0].ProjectName
Just add another line onder it:
#Model.TimeTrakings[i][0].ProjectName
// this line will create additional hidden input and on form post it will be sended to server.
#Html.HiddenFor(x => x.TimeTrakings[i][0].ProjectName)

Related

how to show viewbag data in html table by converting viewbag object to list in asp.net mvc

im passing list data in the viewbag from the controller . while accessing the viewbag as list getting error.
error - 'Object reference not set to an instance of an object.'
getting error at this line. ViewBag.Total_PowerList as IEnumerable<TransformerEnergyMonitoring.Models.KWHConsumption>
view
#model IEnumerable<TransformerEnergyMonitoring.Models.KWHConsumption>
<div class="row">
<div class="table-responsive">
<table id="myTable" class="table table-bordered table-hover table-striped">
<thead class="table-header">
<tr>
<th>Date</th>
<th>KWH Reading</th>
<th>KWH Consumption</th>
</tr>
</thead>
<tbody>
#foreach (var item in (ViewBag.Total_PowerList as IEnumerable<TransformerEnergyMonitoring.Models.KWHConsumption>))
{
<tr>
<td>#item.timeStamp</td>
</tr>
}
</tbody>
</table>
</div>
</div>
dataset
{ timeStamp = 12/5/2020 12:00:00 AM, finalState = 47326.95, consuption = 1455.71 }
Controller
public ActionResult KWHDateWise(RangeSelection RS)
{
DateTime ToDate = Convert.ToDateTime(RS.ToDate).AddDays(1);
RS.ToDate = ToDate;
List<KWHConsumption> kwhcon = new List<KWHConsumption>();
var Total_PowerList = db.Total_Power.Where(u => u.DeviceImei == RS.DeviceImei && (u.DeviceTimeStamp >= RS.FromDate && u.DeviceTimeStamp <= RS.ToDate)).OrderByDescending(u => u.DeviceTimeStamp).ToList();
ViewBag.Total_PowerList= Total_PowerList
.GroupBy(
i => i.DeviceTimeStamp.Date,
(timeStamp, dayilyData) => new { timeStamp, dayilyData })
.Select(i => new
{
i.timeStamp,
finalState = i.dayilyData.Max(x => x.KWH),
consuption = (i.dayilyData.Max(x => x.KWH) - i.dayilyData.Min(x => x.KWH))
})
.ToList();
return PartialView("~/Views/TransEnergyHistory/_KWH.cshtml", kwhcon);
}
Model
public class KWHConsumption
{
public DateTime timeStamp { get; set; }
public double finalState { get; set; }
public double consuption { get; set; }
}
Whenever you are using a viewbag is a dynamic structure that doesnt care about the datatype is having inside, what you sohuld be doing is casting your datatype to your desired type here an example:
Provided this TestModel
public class TestModel
{
public string Id { get; set; }
public int Number { get; set; }
public string Name { get; set; }
}
and this Action in the controller
public IActionResult Index()
{
var vm = new List<TestModel>() {
new TestModel(){
Id = "randomId1",
Name = "randomName1",
Number = 2
},
new TestModel(){
Id = "randomId2",
Name = "randomName2",
Number = 1
},
new TestModel(){
Id = "randomId3",
Name = "randomName3",
Number = 3
},
};
ViewBag.TestModels = vm;
return View();
}
In your view it should look like this
#foreach (var item in (ViewBag.TestModels as IEnumerable<TestModel>))
{
<tr>
<td>#item.Id</td>
<td>#item.Number</td>
<td>#item.Name</td>
</tr>
}
Im assuming in your case the way you want to cast it is
(ViewBag.Total_PowerList as IEnumerable<TransformerEnergyMonitoring.Models.Total_Power>)

Radio button values binding not working

I have a view:
#using(Html.BeginForm())
{
<div>
<table id="dimensionFeedbackTable">
<tbody>
#for(int i = 0; i < 6; i++)
{
<tr>
<td>
<div>
<p>
<text>
Rate #i
</text>
</p>
</div>
</td>
#foreach(var item in Model.DeptList)
{
<td>
<div style="text-align: center;">
#Html.RadioButtonFor(m => item.DepartmentValue, i,
new
{
id = i,
style = "min-height:45px;"
})
</div>
</td>
}
</tr>
}
</tbody>
</table>
<button id="submitComment" value="submit">
#{
<text>Submit</text>
}
</button>
</div>
}
Model in that view is EmployeeModelClass. Here it is:
public class EmployeeModelClass
{
public int Id
{
get; set;
}
public IEnumerable<DepartmentModelClass> DeptList
{
get; set;
}
}
public class DepartmentModelClass
{
public string DepartmentCode
{
get; set;
}
[Range(1, 6)]
public int? DepartmentValue
{
get; set;
}
}
My controller:
[HttpPost]
public ActionResult Index(EmployeeModelClass emp, IEnumerable<DepartmentModelClass> qec)
{
emp.DeptList = qec;
return View(emp);
}
I am trying to accomplish next:
Each row should be group for it self. For example Rate 1 row can have only one radio button selected. Now, these buttons should be bound. If second radio button is selected in any row then its value (DepartmentValue) should be set to 2. So when I submit, I get a collection of which radio buttons are selected.
I've tried a lot of combinations with setting proper model and binding it. Also tried html helper method RadioButton, but still no luck to return the values. Closest that I managed to get is returning a collection but although radio buttons are selected in Controller, collection is not null but values (DepartmentValues) are null.
Also, there are similar answers here but for some reason none of them is working for me. Any help and pointing direction are appreciated. Losing my mind over a simple thing.
One more thing, I tried with creating partials view but still now luck. I read online that is a bad practice to place for/foreach loop in a view and tried to simplify it but this approach is also not working.
Thanks
I notice few issues -
for loop and foreach loop are opposite.
Should use for for array of controls instead of foreach
Do not explicitly assign id to radio buttons new { id = i, ...})
View
#model DemoMvc.Models.EmployeeViewModel
#using (Html.BeginForm())
{
<div>
<table id="dimensionFeedbackTable">
<tbody>
#for (int i = 0; i < Model.DepartmentViewModels.Count; i++){
<tr>
<td>
<div>
<p>
<text>
Rate #Model.DepartmentViewModels[i].DepartmentCode
</text>
</p>
</div>
</td>
#for (int j = 1; j <= 6; j++)
{
<td>
<div style="text-align: center;">
#Html.RadioButtonFor(m =>
Model.DepartmentViewModels[i].DepartmentValue,
j, new { style = "min-height:45px;" })
#j
</div>
</td>
}
</tr>
}
</tbody>
</table>
<button id="submitComment" value="submit">Submit</button>
</div>
}
Model
public class EmployeeViewModel
{
public int Id { get; set; }
public IList<DepartmentViewModel> DepartmentViewModels { get; set; }
}
public class DepartmentViewModel
{
public string DepartmentCode { get; set; }
public int? DepartmentValue { get; set; }
}
Controller
public ActionResult Index()
{
// This could come from database.
var model = new EmployeeViewModel
{
DepartmentViewModels = new List<DepartmentViewModel>
{
new DepartmentViewModel{ DepartmentCode = "ABC", DepartmentValue = 1},
new DepartmentViewModel{ DepartmentCode = "DEF", DepartmentValue = 2},
new DepartmentViewModel{ DepartmentCode = "GHI", DepartmentValue = 3},
}
};
return View(model);
}
[HttpPost]
public ActionResult Index(EmployeeViewModel model)
{
return View(model);
}
Result
Posted Value

Passing Dictionary To ASP.NET MVC Action [duplicate]

I could not bind the model to Controller. Please give me any advice.
Model,controller and view classes are below. When model is submmited, dictionary property equals to null.
public class GroupRights //model
{
public List<DtoGrup> groups { get; set; }
public Dictionary<short, Dictionary<EnFunction, bool>> groupRights { get; set; } // group function HasPermission
}
public enum EnFunction
{
LPDU_login,
LPDU_changePassword,
LPDU_transitList,
LPDU_PosEventList,
....
}
Controller
public ActionResult GroupRights()
{
TocCommonService.CommonServiceClient client = new TocCommonService.CommonServiceClient();
GroupRights gr = new GroupRights();
gr.groups = client.GetAllOperatorGroups().ToList();
gr.groupRights = new Dictionary<short, Dictionary<EnFunction, bool>>();
foreach (var g in gr.groups)
{
Dictionary<EnFunction, bool> permission = new Dictionary<EnFunction, bool>();
foreach (var func in Enum.GetValues(typeof(EnFunction)).Cast<EnFunction>())
{
permission.Add(func, client.hasPermission(new DtoGrup() { GROUPID = g.GROUPID }, func));
}
gr.groupRights.Add(g.GROUPID, permission);
}
return View(gr);
}
View
#model TocWebApplication.Models.GroupRights
#{
int id = 0;
}
#using (Html.BeginForm("ChangePermissionOfGroup", "Home", FormMethod.Post))
{
<table>
<thead>
<tr>
<th></th>
#foreach (var gr in Model.groups)
{
<th>#gr.GROUPNAME (#gr.GROUPID)</th>
}
</tr>
</thead>
<tbody>
#foreach (var func in Enum.GetValues(typeof(EnFunction)).Cast<EnFunction>())
{
<tr>
<td>#(func.ToString())</td>
#for (int j = 0; j < Model.groups.Count(); j++)
{
<td>#Html.CheckBoxFor(model => model.groupRights[Model.groups[j].GROUPID][func])</td>
}
</tr>
}
</tbody>
</table>
<button type="submit" class="btn btn-primary">Save changes</button>
<button class="btn">Cancel</button>
}
For all but Dictionaries where both the Key and Value are simple value types (for example Dictionary<string, bool>), the DefaultModelBinder requires the name/value attributes to be in the format (in your case)
<input name="groupRights[0].Key" value="1" ... />
<input name="groupRights[0].Value[0].Key" value="LPDU_login" ... />
<input name="groupRights[0].Value[0].Value" value="True" ... />
<input name="groupRights[1].Key" value="2" ... />
<input name="groupRights[1].Value[0].Key" value="LPDU_changePassword" ... />
<input name="groupRights[1].Value[0].Value" value="False" ... />
There are no HtmlHelper methods that can generate the correct attributes and to bind to your groupRights you would need to generate the html manually.
Instead, create a view model(s) that represents the data you want to display in the view.If I have interpreted this correctly, you want to display a table displaying each EnFunction value down, and each DtoGrup across, and to display a checkbox in each cell to determine which EnFunction is selected for each DtoGrup.
public class GroupRightsVM // represents a table cell
{
public short GroupID { get; set; }
public bool IsSelected { get; set; }
}
public class RightsVM // represents a table row
{
public RightsVM()
{
Groups = new List<GroupRightsVM>()
}
public EnFunction Right { get; set; }
public List<GroupRightsVM> Groups { get; set; } // represents the cells in a row
}
public class PermissionsVM // Represents the table
{
public PermissionsVM()
{
Permissions = new List<RightsVM>()
}
public IEnumerable<string> Headings { get; set; } // represents the table headings
public List<RightsVM> Permissions { get; set; } // represents all rows
}
And in the view
<thead>
<tr>
<th></th>
#foreach(var heading in Model.Headings)
{
<th>#heading</th>
}
</tr>
</thead>
<tbody>
#for(int i = 0; i < Model.Rows.Count; i++)
{
<tr>
<td>
#Html.HiddenFor(m => m.Permissions[i].Right)
#Html.DisplayFor(m => m.Permissions[i].Right)
</td>
#for(int j = 0; j < Model.Permissions[i].Groups.Count; j++)
{
<td>
#Html.HiddenFor(m => m.Permissions[i].Groups[j].GroupID)
#Html.CheckboxFor(m => m.Permissions[i].Groups[j].IsSelected)
</td>
}
</tr>
}
</tbody>
In the GET method, initialize an instance of PermissionsVM and populate it based on your data models and pass it to the view, for example
var groups = client.GetAllOperatorGroups()
var model = new PermissionsVM();
model.Headings = groups.Select(x => String.Format("{0} {{1})", x.GROUPNAME, x.GROUPID));
foreach (var func in Enum.GetValues(typeof(EnFunction)).Cast<EnFunction>())
{
RightsVM r = new RightsVM();
r.Right = func;
foreach (var g in groups)
{
GroupRightsVM gr = new GroupRightsVM();
gr.GroupID = g.GROUPID;
gr.IsSelected = ...
r.Groups.Add(gr);
}
model.Persmissions.Add(r);
}
return View(model);
and in the POST method
public ActionResult GroupRights(PermissionsVM model)

How to represent a month of checkboxes in an MVC model

I can't manage to get my head around how to use MVC to create the following table, and successfully bind it to a model:
I basically need to keep track of which days of the month an event needs to happen. Here is my attempt at a model:
EDIT: This isn't for a month, but for a arbitrary 4 week cycle
public class ScheduleViewModel
{
public int PatientId { get; set; }
public List<Schedule> Schedules { get; set;}
}
public class Schedule {
public int Week { get;set;}
public Day Day { get;set;}
public bool IsSelected { get;set;}
}
public enum Day
{
Monday,
Tuesday,
Wednesday,
Thursday,
Friday,
Saturday,
Sunday
}
And I can render a view successfully (that isn't bound to the model). I realise that I would need to use #html.CheckBoxFor in place on my inputs.
Here is a rough copy of my html for the view:
#model WebApplication10.Models.ScheduleViewModel
#using (Html.BeginForm())
{
<table class="table table-striped">
<thead>
<tr>
<th></th>
#{
foreach (Day t in Enum.GetValues(typeof(Day)))
{
<th>#t</th>
}
}
</tr>
</thead>
<tbody>
#{
for (int i = 1; i <= 4; i++)
{
<tr>
<td>Week #i</td>
#foreach (Day t in Enum.GetValues(typeof(Day)))
{
<td><input type="checkbox" /></td>
}
</tr>
}
}
</tbody>
</table>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Create" class="btn btn-default" />
</div>
</div>
}
How would I successfully post which check-boxes have been selected? Does my ViewModel make sense?
I suggest you change you view model(s) to
public class DayVM
{
public Day Day { get; set; }
public bool IsSelected { get; set; }
}
public class WeekVM
{
public WeekVM()
{
Days = new List<DayVM>();
Days.Add(new DayVM() { Day = Day.Sunday });
Days.Add(new DayVM() { Day = Day.Monday });
.. etc
}
public List<DayVM> Days { get; set; }
}
public class ScheduleViewModel
{
public ScheduleViewModel()
{
Weeks = new List<WeekVM>();
Weeks.Add(new WeekVM());
.... etc
}
public int PatientId { get; set; }
public List<WeekVM> Weeks { get; set;}
}
Then in the view
for(int i = 0; i < Model.Weeks.Count; i++)
{
<tr>
<td>Week #i</td>
for(int j = 0; j < Model.Weeks[i].Days.Count; j++)
{
<td>
#Html.CheckBoxFor(m => m.Weeks[i].Days[j].IsSelected)
</td>
}
</tr>
}
Side note: I don't think you really need you own enum here - your could just use the DayOfWeek enumeration, for example Days.Add(new DayVM() { Day = DayOfWeek.Sunday });. Note also I have not included an input for the Day property since you could easily determine that from its index in the collection. In fact the Day property may not be required at all if you manually render the table header row.

MVC Razor form : data not sent

I'm trying to so a simple form to send some data. My form have a list of checkboxes and next to each box, a name and a role of person. What I want to do : recover the list of person that box have been checked.
I've created a model that way to do that :
public class CoupleModel
{
public Boolean isSelected { get; set; }
public String name {get; set;}
public String login { get; set; }
public String role { get; set; }
public CoupleModel(String name, String login, String role)
{
this.name = name;
this.login = login;
this.role = role;
this.isSelected = false;
}
public CoupleModel()
{
this.isSelected = false;
}
}
My form looks like this :
#using (Html.BeginForm("CreateInventory", "Home"))
{
#Html.Action("PersonListInventory")
<button type="submit" class="btn btn-primary">Validate creation</button>
}
And the PartialView linked to it is this one :
#model List<MyApp.Models.CoupleModel>
<table class="table table-striped table-bordered"">
<tbody>
#for (int i = 0; i < Model.Count(); i++) {
<tr>
<td>
#Html.EditorFor(m => m[i].isSelected)
</td>
<td>
#Html.EditorFor(m => m[i].name)
</td>
<td>
#Html.EditorFor(m => m[i].role)
</td>
</tr>
}
</tbody>
</table>
And then, in my controller view, I just want to list the name of the people where the box have been checked :
[HttpPost]
public ActionResult CreateInventory(List<CoupleModel> model)
{
String res = "";
foreach (var item in model) {
if (item.isSelected)
{
res += "selected : " + item.login + "<br>";
}
else
{
res += item.login + "<br>";
}
}
ViewBag.Res = res;
return View();
}
But only the "isSelected" part is set, that's to say that login is always blank when displaying. Why isn't it set ? Do I need to do some particular binding ?
that's to say that login is always blank when displaying.
That's perfectly normal. You don't have a corresponding field in your form. You need to add it as a hidden field:
#Html.HiddenFor(m => m[i].login)
You need to add #Html.HiddenFor(..)s for the fields you want to pass along.
The result:
#for (int i = 0; i < Model.Count(); i++) {
#Html.HiddenFor(m => m[i].login)
<tr>
<td>
#Html.EditorFor(m => m[i].isSelected)
</td>
<td>
#Html.EditorFor(m => m[i].name)
</td>
<td>
#Html.EditorFor(m => m[i].role)
</td>
</tr>
}
On the side, please use the .NET naming convention.

Categories