J'essaie de créer un modèle d'éditeur pour un champ DateTime. L'affichage du champ fonctionne comme il se doit, mais lorsque le champ est affiché en haut du serveur, il perd sa valeur. J'utilise flatpickr pour la partie date et la partie heure.
Ma classe:
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; }
}
Manette:
public ActionResult Edit()
{
var myClass = new myClass
{
Id = 1,
MyDateTime = DateTime.Now,
};
ViewBag.Language = "en-US"; // "fr-FR"; //
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);
}
Voir:
@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>
Modèle d'éditeur (DateTime.cshtml)
@* 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, // Exactly the same as date format, but for the altInput field
altInput: true, // Show the user a readable date (as per altFormat), but return something totally different to the server.
allowInput: true,
allowInvalidPreload: true, // Allows the preloading of an invalid date. When disabled, the field will be cleared if the provided date is invalid
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}`);
// remove time part
if (dmy.split(' ').length > 1) dmy = dmy.split(' ')[0];
//console.log(dmy);
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];
//console.log(`${year}/${month}/${day}`);
//let hour = document.getElementById('HourPart').value;
//if (hour.length === 1) hour = `0${hour}`;
//let min = document.getElementById('MinutePart').value;
//if (min.length === 1) min = `0${min}`;
//console.log(`set: ${dmy} [${hour}:${min}]`);
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;
//console.log(date.getHours() + ":" + date.getMinutes());
document.getElementById("TimePart").value = tm;
document.getElementById("Value").value = dtm;
};
</script>
J'ai essayé plusieurs choses, mais à chaque fois la date est affichée sur le contrôleur en tant que 1er janvier 0001, [00:00].
Solution du problème
Le problème était que le modèle lui-même n'était pas stocké dans le modèle de l'éditeur :
une fois que j'ai remplacé:
@Html.TextBox("value", Model, new { @id = "Value", @class = "form-control", @readonly ="readonly" })
by
@Html.HiddenFor(model => model, new { @id = @dateTimeId, @class = "form-control", @readonly = "readonly" })
J'ai récupéré la valeur pour le DateTime...
Aucun commentaire:
Enregistrer un commentaire