.Net, Programming

How to render a section in partial view contains scripts and style tags?

If you have any requirement to create widget or feature to reuse in multiple views and also want to use only specific scripts and styles while it has been added in view to render as the partial view. For example, you have to add the slider and use as a partial view to add in multiple views where and in that partial view some specific script needed to add and while you render the main view and also some styles added. you can’t do normally to add scripts in that section defined in _Layout.cshtml. you can better understand this problem using below scenario

Problem

The problem is created when you are considering a section and add scripts in that section to render in view as partial view and that scripts not to be added for example:
If you have a section in _Layout.cshtml

<!DOCTYPE html>
<html>
<head> </head>
<body> ...
<a href="http://@Url.Content(">http://@Url.Content(</a> @RenderSection("Scripts", false)
</body>
</html>

Add partial view “PartialScripts.chtml” in shared folder

@Section Scripts
<a href="http://@Url.Content(">http://@Url.Content(</a>
<a href="http://@Url.Content(">http://@Url.Content(</a>
<a href="http://@Url.Content(">http://@Url.Content(</a>
<a href="http://@Url.Content(">http://@Url.Content(</a>
End Section

Now if you are trying to call partial view in view like this

@ModelType MvcExample.MyModel
@Code
ViewData("Title") = "Test"
End Code
@Html.Partial("ValidationScripts")
<h2>Just for Test</h2>
...

Now Problem is the section with script tags not properly rendered like this and even you add style/CSS it will be the same problem

<!DOCTYPE html>
<html>
<head> </head>
<body> ...
<a href="http://@Url.Content(">http://@Url.Content(</a>
</body>
</html>

Solution

Create extension methods to render script or style tags as usual with normal view.
Use these extension methods:

public static class HtmlHelperExtensions
    {
        private
        const string _jSViewDataName = "RenderJavaScript";
        private
        const string _styleViewDataName = "RenderStyle";
        public static void AddJavaScript(this HtmlHelper htmlHelper, string scriptURL)
        {
            List<string> scriptList = htmlHelper.ViewContext.HttpContext.Items[HtmlHelperExtensions._jSViewDataName] as List<string>;
            if (scriptList != null)
            {
                if (!scriptList.Contains(scriptURL))
                {
                    scriptList.Add(scriptURL);
                }
            }
            else
            {
                scriptList = new List<string>();
                scriptList.Add(scriptURL);
                htmlHelper.ViewContext.HttpContext.Items.Add(HtmlHelperExtensions._jSViewDataName, scriptList);
            }
        }
        public static MvcHtmlString RenderJavaScripts(this HtmlHelper htmlHelper)
        {
            StringBuilder result = new StringBuilder();
            List<string> scriptList = htmlHelper.ViewContext.HttpContext.Items[HtmlHelperExtensions._jSViewDataName] as List<string>;
            if (scriptList != null)
            {
                foreach (string script in scriptList)
                {
                    result.AppendLine(string.Format("<a href="http://0">http://0</a>", script));
}
            }
            return MvcHtmlString.Create(result.ToString());
        }
        public static void AddStyle(this HtmlHelper htmlHelper, string styleURL)
        {
            List<string> styleList = htmlHelper.ViewContext.HttpContext.Items[HtmlHelperExtensions._styleViewDataName] as List<string>;
            if (styleList != null)
            {
                if (!styleList.Contains(styleURL))
                {
                    styleList.Add(styleURL);
                }
            }
            else
            {
                styleList = new List<string>();
                styleList.Add(styleURL);
                htmlHelper.ViewContext.HttpContext.Items.Add(HtmlHelperExtensions._styleViewDataName, styleList);
            }
        }
        public static MvcHtmlString RenderStyles(this HtmlHelper htmlHelper)
        {
            StringBuilder result = new StringBuilder();
            List<string> styleList = htmlHelper.ViewContext.HttpContext.Items[HtmlHelperExtensions._styleViewDataName] as List<string>;
            if (styleList != null)
            {
                foreach (string script in styleList)
                {
                    result.AppendLine(string.Format("	<link href="{ 0}                     " rel="stylesheet" type="text / css" />", script));
                }
            }
            return MvcHtmlString.Create(result.ToString());
        }
    }

You can use these extension methods like this for the script to render in partial view:

@{
Html.AddJavaScript("http://cdn.jquerytools.org/1.2.7/full/jquery.tools.min.js");
}

For add style in partial view:

@{
Html.AddStyle("http://code.jquery.com/ui/1.11.0/themes/smoothness/jquery-ui.css");
}

In _Layout.cshtml you have to add this code section to render works

<!DOCTYPE html>
<html lang="en">
<head>
@Html.RenderStyles()
@Html.RenderJavascripts()
</head>

Leave a Reply

Your email address will not be published. Required fields are marked *