I have the following code:
#model IEnumerable<SampleMvcApp.Models.Exercise>
#foreach (var item in Model.GroupBy(m => m.DayName).Distinct())
{
<table class="table">
<h2>#Html.Display(item.Select(x => x.DayName).ToString())</h2>
<thead>
<tr>
<th>
ExerciseName
</th>
<th>
ExerciseTime
</th>
<th>
ExerciseRepetition
</th>
<th>
MomentOfTheDay
</th>
<th>
Routine
</th>
<th>
Week
</th>
</tr>
</thead>
#foreach (var test2 in item)
{
<tbody>
<tr>
<td>
#Html.DisplayFor(modelItem => test2.ExerciseName)
</td>
<td>
#Html.DisplayFor(modelItem => test2.ExerciseTime)
</td>
<td>
#Html.DisplayFor(modelItem => test2.ExerciseRepetition)
</td>
<td>
#Html.DisplayFor(modelItem => test2.MomentOfTheDay)
</td>
<td>
#Html.DisplayFor(modelItem => test2.Routine.RoutineID)
</td>
<td>
#Html.DisplayFor(modelItem => test2.ExerciseWeek)
</td>
<td>
<a asp-action="Edit" asp-route-id="#test2.ExerciseID">Edit</a> |
<a asp-action="Details" asp-route-id="#test2.ExerciseID">Details</a> |
<a asp-action="Delete" asp-route-id="#test2.ExerciseID">Delete</a>
</td>
</tr>
</tbody>
}
</table>
}
Everything works fine but
<h2>#Html.Display(item.Select(x => x.DayName).ToString())</h2>
I'm just trying to show the Day Name above the table as it is grouped by days, however the Display code won't show anything. I've tried using DisplayFor but apparently it doesn't accept expressions. Or maybe I am doing it wrong.
Html.Display is not intended for this purpose, which is why it doesn't work. What you need is Html.DisplayFor. However, the error you're getting with that is because the parameter must be an expression that evaluates to an member on the model. Using something like Select is not possible because the expression cannot be parsed to a particular member.
Now, given your use of Select here, it's not entirely clear what kind of display you're expecting to see. It's going to be an enumerable, so you'd need to make some decision about how each item in that enumerable should be handled. Simply, you could do something like:
<h2>
#foreach (var item in items)
{
#Html.DisplayFor(x => x.DayName)
}
</h2>
However, since this is a heading, it's likely you're only expecting a single day name, so you might rather just do something like:
#{ var item = item.First(); }
<h2>#Html.DisplayFor(x => item.DayName)</h2>
Yet, it's not entirely clear if DisplayFor is even necessary here. If DayName is just a string like Monday, then DisplayFor is entirely superfluous; it will merely just output the string. Therefore, you could just do:
<h2>#items.Select(x => x.DayName).First()</h2>
Related
I am trying to format my date using .ToString() but I keep getting this error, I understand where it's coming from but I have no idea how to fix it.
The error message I keep getting is: InvalidOperationException: Templates can be used only with field access, property access, single-dimension array index, or single-parameter custom indexer expressions.
Currently my code inside my view looks like this:
#foreach (var item in Model) {
<tr>
<td>
#Html.DisplayFor(modelItem => item.DatePrescribed.ToString("yyyy-MMM-dd hh:mm:ss"))
</td>
<td>
#Html.DisplayFor(modelItem => item.Comments)
</td>
<td>
#Html.DisplayFor(modelItem => item.PatientDiagnosis.PatientDiagnosisId)
</td>
<td>
#Html.DisplayFor(modelItem => item.Treatment.Name)
</td>
<td>
<a asp-action="Edit" asp-route-id="#item.PatientTreatmentId">Edit</a> |
<a asp-action="Details" asp-route-id="#item.PatientTreatmentId">Details</a> |
<a asp-action="Delete" asp-route-id="#item.PatientTreatmentId">Delete</a>
</td>
</tr>
}
The line in question is:
#Html.DisplayFor(modelItem => item.DatePrescribed.ToString("yyyy-MMM-dd hh:mm:ss"))
I've been stuck on this for a while so any solution would be much appreciated.
Decorate your property with DisplayFormat like below:
[DisplayFormat(DataFormatString = "{0:yyyy-MMM-dd hh:mm:ss}")]
public DateTime DatePrescribed { get; set; }
And then simply in your view just call property:
#Html.DisplayFor(modelItem => item.DatePrescribed)
I have several costs/fees to display for a tenant and now I want to sum up all the values. Here is my code.
#foreach (var item in Model.Contracts)
{
<tr>
<td>
#Html.DisplayFor(modelItem => item.Apartment.MonthParkfee)
</td>
<td>
#Html.DisplayFor(modelItem => item.Apartment.MonthUtilityFee)
</td>
<td>
#Html.DisplayFor(modelItem => item.MonthlyRent)
</td>
<td>
#Html.DisplayFor(sumOfAllFees => MonthParkFee + MonthUtilityFee + MonthlyRent)
</td>
</tr>
}
The MonthParkFee and MonthUtilityFee are both in the Apartment table while the MonthlyRent is in the contract table but the contract table contains the foreign key for the Apartment table. How would I be able to add those values together in razor and render them?
Define a variable to hold the sum as below:
#foreach (var item in Model.Contracts)
{
var sum = item.Apartment.MonthParkfee + item.Apartment.MonthUtilityFee +item.MonthlyRent;
<tr>
<td>
#Html.DisplayFor(modelItem => item.Apartment.MonthParkfee)
</td>
<td>
#Html.DisplayFor(modelItem => item.Apartment.MonthUtilityFee)
</td>
<td>
#Html.DisplayFor(modelItem => item.MonthlyRent)
</td>
<td>
#Html.Display("sumOfAllFees" => sum)
</td>
</tr>
}
Or add a Sum property to view model you are sending and send Sum from controller itself to show in the view.
I'm trying to develop a Razor view page like following , that consist with inline editing, but saving using single submit button.
So I did up to this level in my Viewpage
#model IEnumerable<sample.Models.Sample>
<table class="table">
<tr>
<th>
#Html.DisplayNameFor(model => model.Name)
</th>
<th>
#Html.DisplayNameFor(model => model.Value)
</th>
<th></th>
</tr>
#foreach (var item in Model) {
<tr>
<td>
#Html.DisplayFor(modelItem => item.Name)
</td>
<td>
#Html.DisplayFor(modelItem => item.Value)
</td>
<td>
#Html.ActionLink("Edit", "Edit", new { id=item.Id })
</td>
</tr>
}
</table>
How can I continue from here, I'm not planning to use any 3rd party library such as jQuery Datatable,
You don't have to use jQuery datatable but why cannot you use basic jQuery. On edit set a dirty attribute for the inline text control and on submit you can make an ajax call using jQuery and pass the data in JSON format to your post method in your controller.
I am using jquery datatables in my MVC ASP.Net application and get an alert warning while the application is running. The alert is "Warning: Scroller requires DataTables 1.10.0 or greater". I have verified that my version of DataTables is 1.10.10 and the DataTables work fairly well except for a few issues.
My issues with DataTables is when pages using it initially load, the number of rows that are supposed to be displayed do not match how many are shown. All rows are shown on a page load. Once I interact with the table, everything is fixed.
I am loading the javascript and css in my BundleConfig.cs file.
One of my views is as follows:
#model IEnumerable<Q5.ViewModels.ProjectVM>
#{
ViewBag.Title = "Projects";
}
<h2>Projects/Deals</h2>
<p>
#Html.ActionLink("Create New", "Create")
</p>
<table class="table table-striped table-hover display" id="projects" cellspacing="0">
<thead>
<tr>
<th>
#Html.DisplayNameFor(model => model.Name)
</th>
<th>
#Html.DisplayName("Last Updated")
</th>
<th>
#Html.DisplayName("Sales Person")
</th>
</tr>
</thead>
<tbody>
#foreach (var item in Model)
{
<tr>
<td>
#Html.ActionLink(item.Name, "ProjectProfile", new { id = item.Id })
</td>
<td>
#Html.DisplayFor(modelItem => item.LastUpdated)
</td>
<td>
#Html.DisplayFor(modelItem => item.AssignedToUserName)
</td>
</tr>
}
</tbody>
</table>
<script>
$(document).ready(function () {
$('#projects').DataTable();
})
</script>
You could have the table refreshed after load:
$('#example').dataTable( {
"initComplete": function(settings, json) {
alert( 'DataTables has loaded.' );
$('#example').dataTable().ajax.reload( null, false );
}
} );
This may not be 100% syntax, just typed off the cuff. I seem to remember having to do this for a project, but the details escape me. I never could figure out why it happened so I slapped this band aid on it.
My question is how to get table data back to the controller from view?
I have class in my model:
public class Company
{
public string Name { get; set; }
public int ID { get; set; }
public string Address { get; set; }
public string Town { get; set; }
}
and I pass list of Companies to my view as:
#model IEnumerable<MyTestApp.Web.Models.Company>
....
#using (Html.BeginForm("Edit", "Shop"))
{
<table id="example">
<thead>
<tr>
<th>
#Html.DisplayNameFor(model => model.Name)
</th>
<th>
#Html.DisplayNameFor(model => model.Address)
</th>
<th>
#Html.DisplayNameFor(model => model.Town)
</th>
</tr>
</thead>
<tbody>
#foreach (var item in Model) {
<tr>
<td>
#Html.EditorFor(modelItem => item.Name)
</td>
<td>
#Html.EditorFor(modelItem => item.Address)
</td>
<td>
#Html.EditorFor(modelItem => item.Town)
</td>
</tr>
}
</tbody>
</table>
<input type="submit" value="Submit" />
}
And everything looks ok, but I can't understand how to get modified data in the controller? I used these approaches:
public ActionResult Edit(IEnumerable<Company> companies)
{
// but companies is null
// and ViewData.Model also is null
return RedirectToAction("SampleList");
}
I need access to modified objects, what am I doing wrong?
UPDATE: Thanks to webdeveloper, I just needed use 'for' loop instead of 'foreach' loop. Right version is
<tbody>
#for (int i = 0; i < Model.Count(); i++ ) {
<tr>
<td>
#Html.EditorFor(modelItem => modelItem[i].Name)
</td>
<td>
#Html.EditorFor(modelItem => modelItem[i].Address)
</td>
<td>
#Html.EditorFor(modelItem => modelItem[i].Town)
</td>
</tr>
}
</tbody>
Please, look at my answer here: Updating multiple items within same view OR for Darin Dimitrov answer.
You need items with index in name attribute in rendered html markup. Also you could look at: Model Binding To A List
I think that you are missing the Company's ID in your form so that the model can be correctly bound.
You should add it like this:
#using (Html.BeginForm("Edit", "Shop"))
{
<table id="example">
<thead>
<tr>
<th>
#Html.HiddenFor(model => model.ID)
#Html.DisplayNameFor(model => model.Name)
</th>
...
Otherwise the rest of your code seems to be OK.
You need to bind your table rows by providing an id for each one being edited so mvc can bind to it back to the controller. One row of table data example:
#for (var a = 0; a < #Model.Pets.Count; a++)
{
<tr>
<td>
#Html.CheckBoxFor(model => #Model.Pets[a].ChildSelected, new { #id= a + "childSelected" })
</td>
</tr>