I'm trying to create an Editor Template for a DateTime field.
The display of the field works as it should, however when the field gets posted back top the server it looses its value. I'm using flatpickr for the date part and the time part.
My Class:
public class myClass
{
[Key]
public int Id { get; set; }
[UIHint("DateTime")]
[DisplayFormat(ApplyFormatInEditMode = true, DataFormatString = "{0:yyyy-MM-dd HH:mm}")]
[DataType(DataType.DateTime)]
public DateTime MyDateTime { get; set; }
}
Controller
public ActionResult Edit()
{
var myClass = new myClass
{
Id = 1,
MyDateTime = DateTime.Now,
};
ViewBag.Language = "en-US";
ViewBag.MinDate = new DateTime(2022, 4, 1, 0, 0, 0).Date.ToString("yyyy-MM-dd");
ViewBag.MaxDate = DateTime.Today.Date.ToString("yyyy-MM-dd");
return View("Edit2", myClass);
}
My View
@model EditorTemplates.Models.myClass
@{
ViewBag.Title = "Edit2";
}
<h2>Edit2</h2>
@using (Html.BeginForm("Edit", "Home", FormMethod.Post))
{
@Html.AntiForgeryToken()
<div class="form-horizontal">
<h4>myClass</h4>
<hr />
@Html.ValidationSummary(true, "", new { @class = "text-danger" })
@Html.HiddenFor(model => model.Id)
<div class="form-group">
@Html.LabelFor(model => model.MyDateTime, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.MyDateTime, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.MyDateTime, "", new { @class = "text-danger" })
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Save" class="btn btn-default" />
</div>
</div>
</div>
}
<div>
@Html.ActionLink("Back to List", "Index")
</div>
My Editor Template (DateTime.cshtml)
<pre>@* usage : @Html.EditorFor(m => m.BirthDate, new { Language = 'fr-FR', MinDate = '2022-04-01', MaxDate = '2022-04-05' }) *@
@model System.DateTime
@{
//var value = Model.ToString("yyyy-MM-dd [HH:mm]");
var yearPart = Model.Year.ToString("0000");
var monthPart = Model.Month.ToString("00");
var dayPart = Model.Day.ToString("00");
var datePart = $"{yearPart}-{monthPart}-{dayPart}";
var hourPart = Model.Hour.ToString("00");
var minutePart = Model.Minute.ToString("00");
const string secondPart = "00";
var timePart = $"{hourPart}:{minutePart}";
Console.WriteLine($"{datePart} [{hourPart}:{minutePart}:{secondPart}]");
}
<div class="input-group" style="width: 320px">
@Html.TextBox("date", datePart, new { @class = "form-control", @style = "min-width:220px", @id = "DatePart" })
^__i class="far fa-clock fa-1x" aria-hidden="true">
@Html.TextBox("time", timePart, new { @class = "form-control", @style = "min-width:80px; max-width:80px", @id = "TimePart" })
</div>
@Html.TextBox("value", Model, new { @id = "Value", @class = "form-control", @readonly ="readonly" })
<script type="text/javascript">
let locale = '@ViewBag.Language';
let altFormat = 'F j, Y';
if (locale === 'fr-FR') altFormat = 'j F Y';
flatpickr('#DatePart',
{
altFormat: altFormat,
altInput: true,
allowInput: true,
allowInvalidPreload: true,
dateFormat: 'Y-m-d',
enableTime: false,
locale: '@ViewBag.Language',
minDate: '@ViewBag.MinDate',
maxDate: '@ViewBag.MaxDate',
onChange: function (selectedDates, dateStr, instance) {
console.log("onChange flatpickr date");
set();
}
});
flatpickr('#TimePart',
{
allowInput: true,
enableTime: true,
noCalendar: true,
dateFormat: "H:i",
time_24hr: true,
onChange: function (selectedDates, dateStr, instance) {
console.log("onChange flatpickr time");
set();
}
});
function set() {
let dmy = document.getElementById('DatePart').value;
console.log(`DatePart: ${dmy}`);
if (dmy.split(' ').length > 1) dmy = dmy.split(' ')[0];
let sep = '-';
if (dmy.split(sep).length !== 3) sep = '/';
const year = dmy.split(sep)[0];
const month = dmy.split(sep)[1];
const day = dmy.split(sep)[2];
const hm = document.getElementById('TimePart').value;
console.log(`TimePart: ${hm}`);
sep = ':';
const hour = hm.split(sep)[0];
const min = hm.split(sep)[1];
console.log(`Year : ${parseInt(year)}`);
console.log(`Month : ${parseInt(month)}`);
console.log(`Day : ${parseInt(day)}`);
console.log(`Hour : ${parseInt(hour)}`);
console.log(`Minute : ${parseInt(min)}`);
const dt = (`${year}-${month}-${day}`);
console.log(`date : ${dt}`);
const tm = (`${hour}:${min}`);
console.log(`time : ${tm}`);
const dtm = (`${month}/${day}/${year} ${hour}:${min}:00`);
console.log(`dtm : ${dtm}`);
const date = new Date(parseInt(year), parseInt(month)-1, parseInt(day), parseInt(hour), min);
console.log(`js date :${date}`);
document.getElementById("DatePart").value = dt;
document.getElementById("TimePart").value = tm;
document.getElementById("Value").value = dtm;
};
</script>
What I have tried:
I've tried several things, but each time the date gets posted to the controller as Jan 1st, 0001, [00:00].