3

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" class="btn btn-primary">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" class="btn btn-primary" /> </form> <table class="table table-bordered table-striped"> <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 class="col-sm-3"> <div class="form-group"> @Html.EditorFor(m => m.ItemId, new { htmlAttributes = new {@class = "form-control",type="hidden"} }) </div> <div class="form-group"> @Html.LabelFor(m => m.Description) @Html.EditorFor(m => m.Description, new { htmlAttributes = new { @class = "form-control"} }) @Html.ValidationMessageFor(m=>m.Description) </div> <div class="form-group"> @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 class="form-group"> @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 class="form-group"> @Html.LabelFor(m => m.StatusOfCompletion) @Html.EnumDropDownListFor(m => m.StatusOfCompletion, new { htmlattributes = new { @class = "form-control" } }) </div> <input type="submit" value="Update" class="btn btn-primary" /> </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.

5
  • Could you please show your Todo model defination? Commented May 16, 2022 at 10:03
  • Just replace @Html.EditorFor(model => model.StartDate,new { htmlAttributes = new { @class = "form-control"}}) you dont need explicitely write new { @class = "form-control datepicker", type="date" }. It would resolve your problem. Commented May 16, 2022 at 10:12
  • @MdFaridUddinKiron I updated the model class above. Please check. And, regarding the html attribute, i added datepicker so that user can pick the date instead of typing it. If I do not add the datepicker, it will be a simple textbox. Commented May 16, 2022 at 10:38
  • I got your concern clearly. Please try the answer I have provided. Commented May 17, 2022 at 5:21
  • Is there anything else that I can help you with? Commented May 27, 2022 at 2:11

2 Answers 2

1

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 of string in that case it will be like textbox. If you want that as a date picker I think in that case we should change the text to date picker.

Here is a working demo:

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 class="col-sm-3"> <div class="form-group"> @Html.EditorFor(m => m.ItemId, new { htmlAttributes = new {@class = "form-control",type="hidden"} }) </div> <div class="form-group"> @Html.LabelFor(m => m.Description) @Html.EditorFor(m => m.Description, new { htmlAttributes = new { @class = "form-control"} }) @Html.ValidationMessageFor(m=>m.Description) </div> <div class="form-group"> @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 class="form-group"> @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 class="form-group"> @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" class="btn btn-primary" /> </div> } 

Script:

@section scripts { <script> $(document).ready(function () { $("#textTodate").click(function (e) { $("#textTodate").prop('type','date'); }); }); </script> } 

Note: This is loading with the existing date. While user clicking it to modify I am changing it from textbox to date picker by its click event.

Output:

enter image description here

Sign up to request clarification or add additional context in comments.

3 Comments

We already have a date in the list. In the edit page, i want the all the details to be populated after which I should update the form( date) and post it. So how do we do that?
That's what I have provided the example of. Did you tried the solution?
You are welcome and glad to assist you.
0

To populate the date from the model into the date input field, you can use the Value property of the TextBoxFor helper. Add a date format as second argument in your @Html.EditFor.

Here's a sample code:

Modify the following line in your code:

@Html.TextBoxFor(x => x.dateOfBirth.Date, new { @class = "form-control", @id = "dob", @type = "date" }) 

to:

@Html.TextBoxFor(x => x.dateOfBirth, "{0:yyyy-MM-dd}", new { @class = "form-control", @id = "dob", @type = "date" }) 

Explanation:

Remove .Date from x => x.dateOfBirth.Date because you want to bind the complete DateTime object, not just the Date property. Add "{0:yyyy-MM-dd}" as the second argument of the TextBoxFor helper. This specifies the date format for displaying the value. Adjust the format string as per your requirements. With this change, the date from the model will be populated in the textbox of type date.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.