Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Populate a Razor Section From a Partial

My main motivation for trying to do this is to get Javascript that is only required by a partial at the bottom of the page with the rest of the Javascript and not in the middle of the page where the partial is rendered.

Here's a simplified example of what I'm trying to do:

Here is the layout with a Scripts section right before the body.

<!DOCTYPE html> <html> <head>     <title>@ViewBag.Title</title>     <link href="@Url.Content("~/Content/Site.css")" rel="stylesheet" type="text/css" />     </head>  <body>     @RenderBody()     <script src="@Url.Content("~/Scripts/jquery-1.4.4.min.js")" type="text/javascript"></script>     @RenderSection("Scripts", false) </body> </html> 

Here's an example view using this layout.

<h2>This is the view</h2>  @{Html.RenderPartial("_Partial");}  @section Scripts { <script type="text/javascript">         alert("I'm a view."); </script> } 

And here's the partial being rendered from the view.

<p>This is the partial.</p>  @* this never makes it into the rendered page *@ @section Scripts { <script type="text/javascript">     alert("I'm a partial.");  </script> } 

In this example, the markup specified in the view is placed into the section, but the markup from the partial is not. Is it possible to populate a section from a partial view with Razor? If not, what are some other methods of getting Javascript that's only needed by partials at the bottom of the page without including it globally?

like image 882
Craig M Avatar asked Mar 18 '11 17:03

Craig M


People also ask

How do I render a partial view in Razor?

For this go to Solution Explorer then select Views -> Shared Folder -> Right-click -> Add View. Now for the View -> Home -> Index. cshtml. Here I am rendering a Partial View using 4 types, so the index.

How do you call a partial view inside another partial view?

To call a partial view from another partial view, we follow the same approach as we follow when we call partial view from the content page. Let's take an example. This is the code of 1st partial view. Notice that in above partial view, we are calling another partial view named "_View2" that is created below.


2 Answers

The way I dealt with this is to write a couple extension methods to the HtmlHelper class. That allows partials views to say that they require a script, and then in the layout view that writes the tag I call to my helper method to emit the required scripts

Here are the helper methods:

public static string RequireScript(this HtmlHelper html, string path, int priority = 1) {     var requiredScripts = HttpContext.Current.Items["RequiredScripts"] as List<ResourceInclude>;     if (requiredScripts == null) HttpContext.Current.Items["RequiredScripts"] = requiredScripts = new List<ResourceInclude>();     if (!requiredScripts.Any(i => i.Path == path)) requiredScripts.Add(new ResourceInclude() { Path = path, Priority = priority });     return null; }  public static HtmlString EmitRequiredScripts(this HtmlHelper html) {     var requiredScripts = HttpContext.Current.Items["RequiredScripts"] as List<ResourceInclude>;     if (requiredScripts == null) return null;     StringBuilder sb = new StringBuilder();     foreach (var item in requiredScripts.OrderByDescending(i => i.Priority))     {         sb.AppendFormat("<script src=\"{0}\" type=\"text/javascript\"></script>\n", item.Path);     }     return new HtmlString(sb.ToString()); } public class ResourceInclude {     public string Path { get; set; }     public int Priority { get; set; } } 

Once you have that in place your partial view just needs to call @Html.RequireScript("/Path/To/Script").

And in the layout view's head section you call @Html.EmitRequiredScripts().

An added bonus of this is that it allows you to weed out duplicate script requests. If you have multiple views/partial views that need a given script you can safely assume that you will only output it once

like image 178
Mr Bell Avatar answered Sep 29 '22 07:09

Mr Bell


Partial views cannot participate in their parent views' sections.

like image 27
SLaks Avatar answered Sep 29 '22 08:09

SLaks