I am building a Todo list application
Model class Todo.cs is as below
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.ComponentModel.DataAnnotations;
namespace Todo_Application.Models
{
public class Todo
{
[Display(Name ="Item Id")]
[Required]
public int ItemId { get; set; }
[Display(Name ="Description")]
[Required(ErrorMessage ="Description is required")]
[StringLength(100,MinimumLength =10)]
public string Description { get; set; }
[Display(Name = "Start Date")]
[Required(ErrorMessage ="Start date is required")]
public DateTime StartDate { get; set; }
[Display(Name = "End Date")]
[Required(ErrorMessage ="End date is required")]
public DateTime EndDate { get; set; }
[Display(Name = "Status of completion")]
public Status StatusOfCompletion { get; set; }
public class SortByStartDate : IComparer<Todo>
{
public int Compare(Todo x, Todo y)
{
return x.StartDate.CompareTo(y.StartDate);
}
}
public class SortByEndDate:IComparer<Todo>
{
public int Compare(Todo x,Todo y)
{
return x.EndDate.CompareTo(y.EndDate);
}
}
}
}
I have a home controller with index, add and edit as actions as below.
public class HomeController : Controller
{
public static List<Todo> ListOfTodos = new List<Todo>()
{
new Todo()
{
ItemId=101,
Description="Plan the module",
StartDate=DateTime.Now,
EndDate=DateTime.Now.AddDays(4),
StatusOfCompletion=Status.YetToStart},
new Todo()
{
ItemId=102,
Description="Dry run the plan",
StartDate=DateTime.Now.AddDays(3),
EndDate=DateTime.Now.AddDays(5),
StatusOfCompletion=Status.YetToStart
}
};
public ActionResult Index()
{
return View(ListOfTodos);
}
static int max = 0;
void maxid()
{
foreach (var v in ListOfTodos)
max = Math.Max(max, v.ItemId);
}
public ActionResult Add()
{
maxid();
Session["id"]= max;
return View();
}
[HttpPost]
public ActionResult Add(Todo t)
{
//if(!ModelState.IsValidField("ItemId"))
//{
// ModelState.AddModelError("ItemId", "invalid id");
//}
//if(string.IsNullOrEmpty(t.Description))
//{
// ModelState.AddModelError("Description", "Description field is empty");
//}
//if (!ModelState.IsValidField("StartDate"))
// ModelState.AddModelError("StartDate", "invalid start date");
//if (!ModelState.IsValidField("EndDate"))
// ModelState.AddModelError("EndDate", "invalid end date");
//if (!ModelState.IsValidField("StatusOfCompletion"))
// ModelState.AddModelError("StatusOfCompletion", "invalid status");
if(ModelState.IsValid)
{
ListOfTodos.Add(t);
return View("Index", ListOfTodos);
}
//ModelState.AddModelError("", "Invalid data");
return View();
}
public ActionResult Delete(int id)
{
ListOfTodos.Remove(ListOfTodos.Find(m => m.ItemId == id));
return View("Index",ListOfTodos);
}
public ActionResult Edit(int id)
{
Todo t = ListOfTodos.Find(m => m.ItemId == id);
return View(t);
}
[HttpPost]
public ActionResult Edit(Todo t1)
{
if (ModelState.IsValid)
{
Todo t = ListOfTodos.Find(m => m.ItemId == t1.ItemId);
t.ItemId = t1.ItemId;
t.Description = t1.Description;
t.StartDate = t1.StartDate;
t.EndDate = t1.EndDate;
t.StatusOfCompletion = t1.StatusOfCompletion;
return View("Index", ListOfTodos);
}
return View();
}
[HttpPost]
public ActionResult SortBy(string Sortby)
{
Todo t = new Todo();
if (Sortby.Equals("Start Date"))
ListOfTodos.Sort(new Todo.SortByStartDate());
else if (Sortby.Equals("End Date"))
ListOfTodos.Sort(new Todo.SortByEndDate());
return View("Index", ListOfTodos);
}
}
And also the views as below: Index.cshtml
@model IEnumerable<Todo_Application.Models.Todo>
@{
ViewBag.Title = "Index";
int count = 0;
}
<h2>List of todo items</h2>
<a href="/home/add" >Add New Item</a>
<form method="post" action="/Home/SortBy">
Sort By @Html.DropDownList("Sortby", new SelectList(new List<string>() { "Start Date", "End Date" }),
new { htmlAttributes = new {@class = "form-control"}})
<input type="submit" value="Go" />
</form>
<table >
<thead>
<tr>
<th>Serial No</th>
<th>Item Id</th>
<th>Description</th>
<th>Start Date</th>
<th>End Date</th>
<th>Completion Status</th>
</tr>
</thead>
<tbody>
@{
foreach(var v in Model)
{
<tr>
<td>
@(count=count 1)
</td>
<td>
@v.ItemId
</td>
<td>
@v.Description
</td>
<td>
@v.StartDate.ToShortDateString()
</td>
<td>
@v.EndDate.ToShortDateString()
</td>
<td>
@v.StatusOfCompletion
</td>
<td>
@Html.ActionLink("edit", "Edit", new { id = v.ItemId })
</td>
<td>
@Html.ActionLink("delete", "Delete", new { id = v.ItemId })
</td>
</tr>
}
}
</tbody>
</table>
and Edit.cshtml as below
@model Todo_Application.Models.Todo
@{
ViewBag.Title = "Edit";
}
<h2>Edit Item</h2>
@using (Html.BeginForm("Edit", "Home", FormMethod.Post))
{
<div >
<div >
@Html.EditorFor(m => m.ItemId,
new { htmlAttributes = new {@class = "form-control",type="hidden"} })
</div>
<div >
@Html.LabelFor(m => m.Description)
@Html.EditorFor(m => m.Description,
new { htmlAttributes = new { @class = "form-control"} })
@Html.ValidationMessageFor(m=>m.Description)
</div>
<div >
@Html.LabelFor(m => m.StartDate)
@Html.EditorFor(m => m.StartDate,
new { htmlattributes = new { @class = "form-control datepicker",
type="date" } })
@Html.ValidationMessageFor(m=>m.StartDate)
</div>
<div >
@Html.LabelFor(m => m.EndDate)
@Html.EditorFor(m => m.EndDate,
new { htmlattributes = new { @class = "form-control datepicker",
type="date"} })
@Html.ValidationMessageFor(m=>m.EndDate)
</div>
<div >
@Html.LabelFor(m => m.StatusOfCompletion)
@Html.EnumDropDownListFor(m => m.StatusOfCompletion,
new { htmlattributes = new { @class = "form-control" } })
</div>
<input type="submit" value="Update" />
</div>
}
index view just displays all the items. edit view is used to update the item details. The moment I click on the edit link, it takes me to edit view but does not populate the date fields. It populates description field. How to populate the date fields?
Updated: In the home controller, I defined the a list that has values of type Todo. The startdate will be today's date and time. When I displayed on the index page, I just wanna display date which I am able to do by using ToShortDateString(). Now when i click on edit, only the date should be populated and not time. Initially i used a textbox so it used to display both date and time. Later, I added datepicker class , now nothing gets populated instead the format dd/mm/yyyy is shown.
CodePudding user response:
If you want to display the default datetime meanwhile can choose the datetime, razor doesn't support that. If you want to display
date
while loading the edit page in that case it should be type ofstring
in that case it will be like textbox. If you want that asdate picker
I think in that case we should change thetext
todate picker
. Here is the working demo for you which may you are wanted to implement.
Model:
public class Todo
{
[Display(Name ="Item Id")]
[Required]
public int ItemId { get; set; }
[Display(Name ="Description")]
[Required(ErrorMessage ="Description is required")]
[StringLength(100,MinimumLength =10)]
public string Description { get; set; }
[Display(Name = "Start Date")]
[Required(ErrorMessage ="Start date is required")]
public DateTime StartDate { get; set; }
[Display(Name = "End Date")]
[Required(ErrorMessage ="End date is required")]
public DateTime EndDate { get; set; }
[Display(Name = "Text To Date Picker")]
public Nullable<DateTime> TestDate { get; set; }
}
View:
@model DotNet6MVCWebApp.Models.Todo
@{
ViewBag.Title = "Edit";
}
<h2>Edit Item</h2>
@using (Html.BeginForm("Edit", "Todo", FormMethod.Post))
{
<div >
<div >
@Html.EditorFor(m => m.ItemId,
new { htmlAttributes = new {@class = "form-control",type="hidden"} })
</div>
<div >
@Html.LabelFor(m => m.Description)
@Html.EditorFor(m => m.Description,
new { htmlAttributes = new { @class = "form-control"} })
@Html.ValidationMessageFor(m=>m.Description)
</div>
<div >
@Html.LabelFor(m => m.StartDate)
@Html.EditorFor(m => m.StartDate,
new { htmlattributes = new { @class = "form-control datepicker",
type="date" } })
@Html.ValidationMessageFor(m=>m.StartDate)
</div>
<div >
@Html.LabelFor(m => m.EndDate)
@Html.EditorFor(m => m.EndDate,
new { htmlattributes = new { @class = "form-control datepicker",
type="date"} })
@Html.ValidationMessageFor(m=>m.EndDate)
</div>
<div >
@Html.LabelFor(m => m.TestDate)
@Html.TextBoxFor(model => model.TestDate, "{0:d/M/yyyy}",new { id="textTodate", @class = "form-control", type = "text" })
</div>
<input type="submit" value="Update" />
</div>
}
Script:
@section scripts {
<script>
$(document).ready(function () {
$("#textTodate").click(function (e) {
$("#textTodate").prop('type','date');
});
});
</script>
}
Note:
This is loading with the existingdate
. While user clicking it to modify I am changing it fromtextbox
todate picker
by its clickevent
Output:
Hope above steps guided you accordingly.