How can I avoid adding javascript to this editor?

I wrote the following EditorTemplate, which builds loosely on some other SO questions and Google results:

@model Nullable<DateTime>
@{
    var metadata = ModelMetadata.FromStringExpression("", ViewData);
    string value;
    if(!String.IsNullOrEmpty(metadata.EditFormatString)) {
        if(Model.HasValue) {
            value = String.Format(metadata.EditFormatString, Model.Value);
        }
        else {
            value = metadata.NullDisplayText;
        }
    }
    else {
        value = Model.ToString();
    }
}
@Html.TextBox("", value, new { @class = "textBoxDate" })
<script type ="text/javascript">
    $(document).ready(function () {
        $('.textBoxDate').datepicker();
    });
</script>

      

I don't like the fact that the script is written below each textBoxDate

. I understand why, and I know that one possible solution would be to dump the script to a .js file and link to it in my page. It's not terribly difficult or anything else, but I was hoping there would be a solution that would be a little more ... seamless / magical (why? Fun, that would be neat, just because ...). Any ideas?

+3


source to share


1 answer


I think deleting the script in the .js file and linking to it on your page is the funniest and neat approach to this problem.

If you were looking for a less tidy solution, you could add a couple of HtmlHelper extensions to add case dependencies, as the templating engine meets them and then prints out a bunch of script tags at the end of the page.

private const string requiredJavascriptIncludesContextItemsKey = "requiredJavascriptIncludesContextItemsKey";

public static void Require(this HtmlHelper html, string src)
{
    var collection = (HashSet<string>) html.ViewContext.HttpContext.Items[requiredJavascriptIncludesContextItemsKey] ?? new HashSet<string>();
    collection.Add(src);
    html.ViewContext.HttpContext.Items[requiredJavascriptIncludesContextItemsKey] = collection;
}

public static HtmlString RequiredJavascriptIncludes(this HtmlHelper html)
{
    var sb = new StringBuilder();
    foreach (var src in (HashSet<string>) html.ViewContext.HttpContext.Items[requiredJavascriptIncludesContextItemsKey] ?? new HashSet<string>())
    {
        sb.Append(string.Format("<script type='text/javascript' src='{0}></script>", src));
    }

    return new HtmlString(sb.ToString());
}

      



You can call the method @Html.Require

in any template. In your case it would be like this:

@model Nullable<DateTime>
@{
    var metadata = ModelMetadata.FromStringExpression("", ViewData);
    string value;
    if(!String.IsNullOrEmpty(metadata.EditFormatString)) {
        if(Model.HasValue) {
            value = String.Format(metadata.EditFormatString, Model.Value);
        }
        else {
            value = metadata.NullDisplayText;
        }
    }
    else {
        value = Model.ToString();
    }
}
@Html.TextBox("", value, new { @class = "textBoxDate" })
@Html.Require(Html.Content("scripts/datepicker.js"))

      

Then, at the bottom of the base template page, you make a call @Html.RequiredJavascriptIncludes()

and all your registered js dependent entries will appear as script tags at the end of the html document.

+3


source







All Articles