I'm using default schema of Create View and in my model i've got a field that's a DateTime.
Now i'm doing that, cause if i use the #Html.DisplayFor(modelItem => item.BirthDate) i see a string formatted in this way 13/02/1989 00:00:00 instead of this 16/02/1989
First of All: How to make all with DisplayFor statement? And... How it Works with datatype, it's a good practice?
Next: I wonder i have some homework to do, some suggestion?
#foreach (var item in Model)
{
<tr class="odd gradeX">
<td>
<input name="UserIDs" type="checkbox" class="checkboxes" value=#item.Id />
</td>
<td>
#Html.DisplayFor(modelItem => item.FirstName) #Html.DisplayFor(modelItem => item.LastName)
</td>
<td>
#Html.DisplayFor(modelItem => item.Email)
</td>
<td>
#Html.DisplayFor(modelItem => item.Phone)
</td>
<td>
#Html.DisplayFor(modelItem => item.Fax)
</td>
<td>
#item.BirthDate.ToShortDateString()
</td>
<td>
#Html.ActionLink("Details", "Details", new { Id = item.Id })
</td>
</tr>
}
Add this using statement to your model:
using System.ComponentModel.DataAnnotations;
Then add this attribute to your BirthDate field:
[DisplayFormat(ApplyFormatInEditMode = true, DataFormatString = "{0:yyyy'-'MM'-'dd}")]
Edit as necessary.
Related
I wrote this code:
#foreach (var item in vm)
{
<tr>
<td>
<img src="#Html.DisplayFor(modelItem => item.Image)" style="width:150px" />
</td>
<td>
#Html.DisplayFor(modelItem => item.BrandName)
</td>
<td>
#Html.DisplayFor(modelItem => item.Name)
</td>
<td>
#Html.DisplayFor(modelItem => item.Description)
</td>
<td>
<select asp-for="Size">
#foreach (var i in ViewBag.columnNames){
<option value="#i.ToString()">#i</option>
}
</select>
</td>
<td>
#Html.DisplayFor(modelItem => item.Price)
</td>
<td>
#Html.DisplayFor(modelItem => item.ProductType.Description)
</td>
<td>
<a asp-action="AddToCart" asp-route-id="#item.Id">Buy</a>
</td>
</tr>
}
This is only part for sure, but I have an question about sending my selected value from "select" to AddToCart method of HomeController. How can I do it with asp-route-size or asp-for tags? Or is there any other way to do it?
You can build your select items in your controller, here's a bit of code I use to create a warehouse selection pulldown:
public List<SelectListItem> WarehouseFilterSelectItems { get; set; }
[BindProperty(SupportsGet = true)]
public string WarehouseFilter { get; set; }
WarehouseFilterSelectItems = _context.Warehouse
.Select(a => new SelectListItem
{
Value = a.ID.ToString(),
Text = a.WarehouseName
}).ToList();
Then in the .cshtml:
Warehouse Selection: <select asp-for="WarehouseFilter"
asp-items="#Model.WarehouseFilterSelectItems"
onchange="ProcessForm('filter_results', 'Inventory/jqindex/'); this.blur();">
<option value="0">ALL</option>
</select>
You won't need the 'onchange' event handler if you don't use javascript to post/return the data.
I have one table which is for contracts , And I have link beside each contract , when I click to the link they transfer to other page which is contract month but i want to display the data only for that contract which I click not all data.
Contact View :
#using (Html.BeginForm())
{
#Html.ActionLink("Create", "Create")
<table class="table table-bordered f" cellspacing="0">
<thead>
<tr>
</tr>
</thead>
#foreach (var item in Model)
{
<tbody>
<tr>
<td>
#Html.DisplayFor(modelItem => item.Contract_Num)
</td>
<td>
#Html.DisplayFor(modelItem => item.Contract_Start)
</td>
<td>
#Html.DisplayFor(modelItem => item.Contract_End)
</td>
<td>
#Html.DisplayFor(modelItem => item.Status)
</td>
<td>
#Html.DisplayFor(modelItem => item.typeOfRent.TypeOfRent_Name)
</td>
<td>
#Html.DisplayFor(modelItem => item.AmountOfRent)
</td>
<td>
#Html.DisplayFor(modelItem => item.Total)
</td>
<td>
#Html.DisplayFor(modelItem => item.customers.Customer_Name)
</td>
<td>
#Html.DisplayFor(modelItem => item.sections.Section_Name)
</td>
<td>
#Html.ActionLink("Contract Month", "Index", "ContractMonth")
</td>
</tbody>
}
</table>
contract month view :
foreach (var item in Model)
{
<tr>
<td>
#Html.DisplayFor(modelItem => item.contracts.Contract_Num)
</td>
<td>
#Html.DisplayFor(modelItem => item.Monthe)
</td>
<td>
#Html.DisplayFor(modelItem => item.contracts.AmountOfRent)
</td>
<td>
#Html.DisplayFor(modelItem => item.Receipt)
</td>
<td>
#{
var Balance = item.contracts.AmountOfRent - item.Receipt;
}
#Balance
</td>
Contract month controller:
public ActionResult Index()
{
var ContractMonth =_context.ContractMonth.Include(s => s.contracts).ToList();
return View(ContractMonth);
}
First of all change your Index action method inside ContractMonthController to get specific records with respect to ContractId
public ActionResult Index(int id)
{
var contractMonth = _context.ContractMonth.Where(c => c.ContractsId == id).Include(s => s.contracts).ToList();
return View(contractMonth);
}
And then change your action to accept id as query string parameter,
<td>
#Html.ActionLink("Contract Month", "Index", "ContractMonth", new { id = item.Contracts_Id }, null)
</td>
You can add the primary key (e.g. Id) of each contract to the url of each link as a query string. Then when getting the contract month data you can use the pk parameter to filter the data, for example (in the contract month controller):
public ActionResult Index(int contractId)
{
var ContractMonth =_context.ContractMonth.Where(c => c.ContractId == contractId).Include(s => s.contracts).ToList();
return View(ContractMonth);
}
Currently my DateTime gets displayed as this in my view example: 03/08/2017 00:00:00. I want it to be displayed as follow: 03/08/2017 without the time being displayed. This is my current view code
#foreach (var item in Model)
{
<tr>
<td>
#Html.DisplayFor(modelItem => item.DayOfMonth)
</td>
<td>
#Html.DisplayFor(modelItem => item.TimeSpent) hr
</td>
<td>
#Html.DisplayFor(modelItem => item.Project.Name)
</td>
<td>
#Html.DisplayFor(modelItem => item.Task.Name)
</td>
<td>
#Html.ActionLink("Edit", "Edit", new { id = item.IdTimeSheet_Details }) |
#Html.ActionLink("Details", "Details", new { id = item.IdTimeSheet_Details }) |
#Html.ActionLink("Delete", "Delete", new { id = item.IdTimeSheet_Details })
</td>
</tr>
}
What i have tried so far:
#Html.DisplayFor(modelItem => item.DayOfMonth, "{0:MM/dd/yyyy}")
#Html.DisplayFor(modelItem => item.DayOfMonth.Date.ToString("dd MMM yyyy"))
#Html.DisplayFor(modelItem => item.DayOfMonth.Value.ToString("dd. MM. yyyy"))
#Html.DisplayFor(modelItem => item.DayOfMonth.ToShortDateString() : string.Empty))
#Html.DisplayFor(modelItem => item.DayOfMonth.ToString("dd MMM yyyy"))
#Html.DisplayFor(modelItem => item.DayOfMonth.Value.ToString("dd - M - yy"))
None of the above has worked. Can someone tell me what im doing wrong?
The exeption im getting is
Templates can be used only with field access, property access,
single-dimension array index, or single-parameter custom indexer
expressions
But i dont really see what im doing differently from the people in the posts below:
Where i got most of the things i have tried from
Other post i have checked
You need to either use just
<td>item.DayOfMonth.ToString("dd MMM yyyy")</td>
or if you want to use DisplayFor(), then apply a
[DisplayFormat(DataFormatString = "{0:dd MMM yyyy}")]
public DateTime DayOfMonth { get; set; }
to your property and in the view
<td>#Html.DisplayFor(modelItem => item.DayOfMonth)</td>
I have a PersonViewModel that consists of several List<SubViewModel> (Name, Address, etc.)
I have an Html Form with tables for each SubViewModel, where the user can update,add,delete and set items to the primary entry for the person.
a simplified table for names:
#foreach (PersonNameViewModel name in Model.Names)
{
<tr>
<td>
#Html.DisplayFor(modelItem => name.FullName)
</td>
<td>
#Html.DisplayFor(modelItem => name.FirstName)
</td>
<td>
#Html.DisplayFor(modelItem => name.MiddleName)
</td>
<td>
#Html.DisplayFor(modelItem => name.LastName)
</td>
<td class="center">
#Html.RadioButtonFor(modelItem => name.IsPrimary, "")
</td>
<td class="center">
#Html.CheckBoxFor(modelItem => name.ToDelete)
</td>
</tr>
}
From here, I don't know how to get all the data back into the PersonViewModel when the user submits the form, to update the person record. If I simply accept a PersonViewModel in my POST controller, it's completely empty. I looked at FormCollection, but I'm not sure if that's right for this. Can someone with experience point me in the right direction for building my model back up for updating? Thankyou very much.
Everyone's answer is correct, But if you want to update people's information, you need to use Html Helper Editor NOT Display. Also, you still can use foreach in your view, just change it like below:
#foreach (var name in Model.Names.Select((value, i) => new { i, value }))
{
<tr>
<td>
#Html.EditorFor(m => m.Names[#name.i].FullName)
</td>
<td>
#Html.EditorFor(m => m.Names[#name.i].FirstName)
</td>
<td>
#Html.EditorFor(m => m.Names[#name.i].MiddleName)
</td>
<td>
#Html.EditorFor(m => m.Names[#name.i].LastName)
</td>
<td class="center">
#Html.RadioButtonFor(m => m.Names[#name.i].IsPrimary,"")
</td>
<td class="center">
#Html.CheckBoxFor(m => m.Names[#name.i].ToDelete)
</td>
</tr>
}
You should use sth like this (good article about model binding of collections and complex data here):
#for(var i = 0;i < Model.Names.Count;i++)
{
<tr>
<td>
#Html.DisplayFor(m => Model.Names[i].FullName)
</td>
<td>
#Html.DisplayFor(m => Model.Names[i].FirstName)
</td>
<td>
#Html.DisplayFor(m => Model.Names[i].MiddleName)
</td>
<td>
#Html.DisplayFor(m => Model.Names[i].LastName)
</td>
<td class="center">
#Html.RadioButtonFor(m => Model.Names[i].IsPrimary, "")
</td>
<td class="center">
#Html.CheckBoxFor(m => Model.Names[i].ToDelete)
</td>
</tr>
}
Try replacing the foreach with a for loop:
#for (int i = 0; i < Model.Names.Count; i++)
{
<tr>
<td>
#Html.DisplayFor(m => m.Names[i].FullName)
</td>
<td>
#Html.DisplayFor(m => m.Names[i].FirstName)
</td>
<td>
#Html.DisplayFor(m => m.Names[i].MiddleName)
</td>
<td>
#Html.DisplayFor(m => m.Names[i].LastName)
</td>
<td class="center">
#Html.RadioButtonFor(m => m.Names[i].IsPrimary, "")
</td>
<td class="center">
#Html.CheckBoxFor(m => m.Names[i].ToDelete)
</td>
</tr>
}
The expression parsing/model binding does a better job with indexes than with foreach temp variables.
I have a list of Topic's. Each Topic have a list of Message. When i click on "Details" I want to open a new View that display a list of the Message's from the Topic.
I expect that I need to modify this line: (this is what I have so far)
#Html.ActionLink("Details", "Details", new { id=item.Id }, null)
The Message's are accessed by item.Message.
And the first line in the Detail View
#model IEnumerable<Models.TopicMessage>
This is my Topic View:
#model IEnumerable<Models.Topic>
<table>
<tr>
<th>
#Html.DisplayNameFor(model => model.Name)
</th>
<th></th>
</tr>
#foreach (var item in Model) {
<tr>
<td>
#Html.DisplayFor(modelItem => item.Name)
</td>
<td>
#Html.ActionLink("Details", "Details", new { id=item.Id }, null)
</td>
</tr>
}
</table>
There are a number of ways to do that. You can use the Action method to execute the controller action directly:
<tr>
<td>
#Html.DisplayFor(modelItem => item.Name)
</td>
<td>
#Html.Action("Details", "Details", new { id=item.Id })
</td>
</tr>
Or you can bypass the controller and render the view directly using this overload of DisplayFor:
<tr>
<td>
#Html.DisplayFor(modelItem => item.Name)
</td>
<td>
#Html.DisplayFor(modelItem => item.Messages, "MessagesDetail")
</td>
</tr>
Or if you define the template as the default DisplayTemplate, you can just do this:
<tr>
<td>
#Html.DisplayFor(modelItem => item.Name)
</td>
<td>
#Html.DisplayFor(modelItem => item.Messages)
</td>
</tr>
I fixed this by making a somethingViewModel that contained both the liste and the Id. That way i could contain the two information from two difference places in one new object I had access to in the View.