Reputation: 101
I am using a jqueryui datepicker date (non-standard format: "MM yy" datepicker / "MMMM yyyy" C#). When the form fails server-side validation, dates that were pre-entered fail to re-render on return to form (i.e. inputs are empty). Note that the datepicker seems to work fine in this regard when standard (i.e. unspecified/default) date formats are used. Also note that the validation behaves fine when the failure is validated client side.
I believe this is due to the non-standard date format not being recognized by the datepicker on validation return, because if I select a date, turn off javascript in my browser (or else comment out the $("#internGradDate").datepicker...
statement (below)) and then submit the form for a server-side validation failure, the date will appear normally.
Following are some promising methods I have tried to set the date format in the view, though with no effect:
@Html.TextBoxFor(m => m.internGradDate, "{0:MMMM yyyy}")
Returned DatePicker Value in Wrong Format
@Html.TextBoxFor(model => model.internGradDate,
new { Value = Model.internGradDate.HasValue ?
Model.internGradDate.Value.ToString("MMMM yyyy") : string.Empty })
Lastly, if I view the datepicker input element in the Chrome dev tools "Elements", the "value" attribute appears normal (e.g. value="April 2019"), though the input itself is blank.
Javascript
$("#internGradDate")
.datepicker({ dateFormat: "MM yy", changeYear: true, yearRange: '1988:2028' })
.attr('readonly', 'true')
.datepicker("option", "changeMonth", true)
.datepicker("option", "showButtonPanel", true)
.datepicker("option", "onClose", function (e) {
var month = $("#ui-datepicker-div .ui-datepicker-month :selected").val();
var year = $("#ui-datepicker-div .ui-datepicker-year :selected").val();
$(this).datepicker("setDate", new Date(year, month, 1))
})
.keypress(function (event) {
if (event.keyCode == 8) {
event.preventDefault();
}
});
Data Transfer Object (DTO)
[Display(Name = "Graduation ")]
[DisplayFormat(DataFormatString = "{0:MMMM yyyy}", ApplyFormatInEditMode = true)]
public DateTime? internGradDate { get; set; }
Razor code
<div class="row form-group form-group-override">
<div class="col-sm-6">
@Html.LabelFor(model => model.internGradDate, htmlAttributes: new { @class = "control-label request-label" })
</div>
<div class="col-sm-6">
@Html.TextBoxFor(model => model.internGradDate, "{0:MMMM yyyy}")
@Html.ValidationMessageFor(model => model.internGradDate, "", new { @class = "text-danger" })
</div>
</div>
Controller Action
[HttpPost]
[ValidateAntiForgeryToken]
[ValidateInput(false)]
public ActionResult Add(Intern_DTO it, HttpPostedFileBase file1)
{
var Ntid = Session["username"].ToString();
string fileExt = "";
//Limit upload file size to 4 MB
if (file1 != null)
{
if (file1.ContentLength > 4194304)
{
ModelState.AddModelError("file1", "Please do not exceed 4 MB image size");
}
else
{
fileExt = Path.GetExtension(file1.FileName).ToLower();
if (fileExt != ".doc" && fileExt != ".docx" && fileExt != ".pdf")
ModelState.AddModelError("file1", "Resume filetypes must be docx, doc, or pdf");
}
}
if (!ModelState.IsValid)
{
string message = "We encountered an issue while create the Admin record. Please review the records below.";
TempData.Remove("message");
TempData.Add("message", message);
return View(it);
}
else
{
...
}
}
So, to summarize, I am unclear why the datepicker input is blank on server-side validation fail return to form, though its value attribute shows the expected contents (e.g. "April 2019", same as pre-form submission).
Let me know if any questions, and thanks for any insights.
Upvotes: 2
Views: 132
Reputation: 101
Appears to be due to the order of the datepicker directives - that I originally had "readonly" prior to completion of instantiation breaks it for a pre-existing value?
Thanks for all who looked!
$("#internGradDate")
.datepicker({
dateFormat: "MM yy",
changeYear: true,
changeMonth: true,
yearRange: '1988:2028',
showButtonPanel: true,
onClose: function (e) {
var month = $("#ui-datepicker-div .ui-datepicker-month :selected").val();
var year = $("#ui-datepicker-div .ui-datepicker-year :selected").val();
$(this).datepicker("setDate", new Date(year, month, 1))
}
}).keypress(function (event) {
if (event.keyCode == 8) {
event.preventDefault();
}
}).attr('readonly', 'true');
Upvotes: 1