AndrewStein
AndrewStein

Reputation: 101

Pre-entered jqueryui datepicker "MM yy" formatted dates fail to render on ASP.Net server-side validation failure

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:

Date only from TextBoxFor()

@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

Answers (1)

AndrewStein
AndrewStein

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

Related Questions