Question

I'd like to configure the EditorFor template for every datatime objects in any of my models.

I'm getting this error:

\EditorTemplates\DateTime.cshtml(1): error CS1973: 'System.Web.Mvc.HtmlHelper' has no applicable method named 'TextBox' but appears to have an extension method by that name. Extension methods cannot be dynamically dispatched. Consider casting the dynamic arguments or calling the extension method without the extension method syntax.

Here's the entire code that's inside of the EditorTemplate called, DateTime.cshtml places in the EditorTemplates folder.

Any ideas?

Here's what I call in my View:

<div class="editor-label">
    @Html.LabelFor(model => model.DateOfBirth)
</div>
<div class="editor-field">
    @Html.EditorFor(model => model.DateOfBirth)
    @Html.ValidationMessageFor(model => model.DateOfBirth)
</div>

And this is the custom EditorTemplate I made:

@Html.TextBox("", Model, new { @class = "date-selector" });

THE EDITOR IS WORKING

Basically, for every datetime object in my models, I want to add the class "date-selector" to that html element. This is for jQueryUI purposes.

What am I doing wrong?

Was it helpful?

Solution

You can create an extension method as below:

 public static MvcHtmlString CalenderTextBoxFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression)
    {
        return htmlHelper.TextBoxFor(expression, "{0:M/dd/yyyy}", new { @class = "datepicker text" });
    }

Then use in view as below:

@Html.CalenderTextBoxFor(model => model.Employee.HireDate)

OTHER TIPS

You need to define the model type of the editortemplate. Add "@model DateTime" to the top of the cshtml file:

@model DateTime
@Html.TextBox("", Model, new { @class = "date-selector" }); 
THE EDITOR IS WORKING 

I know this is an older question, but I had the same frustrating issue and I didn't want to create an EditorTemplate that applied to all DateTime values (there were times in my UI where I wanted to display the time and not a JQueryUI drop-down calendar). In my research, the root issues I came across were:

  • The standard TextBoxFor helper allowed me to apply a custom class of "date-picker" to render the unobtrusive JQueryUI calender, but TextBoxFor wouldn't format a DateTime without the time, therefore causing the calendar rendering to fail.
  • The standard EditorFor would display the DateTime as a formatted string (when decorated with the proper attributes such as [DisplayFormat(ApplyFormatInEditMode = true, DataFormatString = "{0:dd/MM/yyyy}")], but it wouldn't allow me to apply the custom "date-picker" class.

Therefore, I expanded upon @Ashraf's answer and created custom HtmlHelper class that has the following benifits:

  • The method automatically converts the DateTime into the ShortDateString needed by the JQuery calendar (JQuery will fail if the time is present).
  • By default, the helper will apply the required htmlAttributes to display a JQuery calendar, but they can be overridden if needs be.
  • If the date is null, MVC will put a date of 1/1/0001 as a value. This method replaces that with an empty string.

I post this here in hopes that it might help someone else at some point. Any suggestions on changes needed are welcome.

public static MvcHtmlString CalenderTextBoxFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression, object htmlAttributes = null)
{
  var mvcHtmlString = System.Web.Mvc.Html.InputExtensions.TextBoxFor(htmlHelper, expression, htmlAttributes ?? new { @class = "text-box single-line date-picker" });
  var xDoc = XDocument.Parse(mvcHtmlString.ToHtmlString());
  var xElement = xDoc.Element("input");
  if (xElement != null)
  {
    var valueAttribute = xElement.Attribute("value");
    if (valueAttribute != null)
    {
      valueAttribute.Value = DateTime.Parse(valueAttribute.Value).ToShortDateString();
      if (valueAttribute.Value == "1/1/0001")
        valueAttribute.Value = string.Empty;
    }
  }
  return new MvcHtmlString(xDoc.ToString());
}

And for those that want to know the JQuery syntax that looks for objects with the date-picker class decoration to then render the calendar, here it is:

$(document).ready(function () {
  $('.date-picker').datepicker({ inline: true, maxDate: 0, changeMonth: true, changeYear: true });
  $('.date-picker').datepicker('option', 'showAnim', 'slideDown');
});

Hopefully this helps someone in the future that has this need.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top