Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Use section in partial view

In my shared layout I would like to have a "scripts" section to stuff it with all the scripts needed for page functionality.

Layout.cshtml

<html>
<head>
    <title>Test</title>
    <script src="@Url.Content("~/Scripts/jquery-2.0.3.js")" type="text/javascript"> </script>

    @RenderSection("Scripts", required: false)

</head>
<body>
    @RenderBody()
</body>
</html>

So, my view loads a specific javascript, and I want it to be in "scripts" section, and it's working.

Index.cshtml

@model PlatformaPu.Areas.Inventura.Models.Home.Index

@section Scripts {
    <script src="@Url.Content("~/Areas/Inventura/Scripts/Home/Index.js")" type="text/javascript"></script>
}

{CONTENT REMOVED FOR BREVITY}

@section Footer {
    @Html.Partial("~/Views/Shared/_AppSelector.cshtml", Model.AppSelector)
}

Finally, my view renders a partial and I have a javascript that this partial loads.

_AppSelector.cshtml

@model PlatformaPu.Models.Shared._AppSelector

@section Scripts {
    <script src="@Url.Content("~/Scripts/Shared/_AppSelector.js")" type="text/javascript"></script>
}

{CONTENT REMOVED FOR BREVITY}

...and this is NOT working - javascript tag is NOT rendered in "scripts" section

How can I do this?

like image 330
OzrenTkalcecKrznaric Avatar asked Aug 12 '13 09:08

OzrenTkalcecKrznaric


People also ask

Can we use Layout in partial view?

Yes, even in Partial View also we can set Layout property which turns Partial View as normal View with Layout .

When should you use partial view?

A partial view is a Razor markup file ( . cshtml ) without an @page directive that renders HTML output within another markup file's rendered output. The term partial view is used when developing either an MVC app, where markup files are called views, or a Razor Pages app, where markup files are called pages.

Where should the javascipt be located in a partial view?

The JavaScipt should be contained in the script section in the partial view, so it is rendered at the bottom of the page. The problem is that MVC does not support the script section in a partial view, for example you can do the following in standard view but not a partial view:

How to add @section tag in a partial view?

Partial views don't support @section tag. You should add them in the view which references the partial view. See this question for more information: Injecting content into specific sections from a partial view ASP.NET MVC 3 with Razor View Engine.

What is a partial view?

The term partial view is used when developing either an MVC app, where markup files are called views, or a Razor Pages app, where markup files are called pages. This topic generically refers to MVC views and Razor Pages pages as markup files. Partial views are an effective way to:

How do I render a partial view in MVC?

In ASP.NET Core MVC, a controller's ViewResult is capable of returning either a view or a partial view. In Razor Pages, a PageModel can return a partial view represented as a PartialViewResult object. Referencing and rendering partial views is described in the Reference a partial view section.


2 Answers

As discussed in this question, it is not possible to use sections in a partial view:

Sections don't work in partial views and that's by design. You may use some custom helpers to achieve similar behavior, but honestly it's the view's responsibility to include the necessary scripts, not the partial's responsibility. I would recommend you using the @scripts section of the main view to do that and not have the partials worry about scripts.

You should add the script reference to the main view that references the partial.

like image 163
Electric Sheep Avatar answered Sep 27 '22 18:09

Electric Sheep


This is my first answer!

I've being working with webforms for years and now i'm dealing with MVC 5. Bit hard.

Perhaps is the wrong solution, but works :)

In Layout.cshtml. add second "ScriptsPartial" section

@RenderSection("ScriptsPartial", required: false)

In Index.cshtml, add ", new ViewDataDictionary(ViewData) { { "ViewPage", this } }"

@section Footer {
    @Html.Partial("~/Views/Shared/_AppSelector.cshtml", Model.AppSelector, new ViewDataDictionary(ViewData) { { "ViewPage", this } })
}

In _AppSelector.cshtml, remove this

@section Scripts {
    <script src="@Url.Content("~/Scripts/Shared/_AppSelector.js")" type="text/javascript"></script>
}

In _AppSelector.cshtml, add this in any place

@{
    if (ViewData.ContainsKey("ViewPage"))
    {
        System.Web.Mvc.WebViewPage viewPage = (System.Web.Mvc.WebViewPage)ViewData["ViewPage"];

        viewPage.DefineSection("ScriptsPartial", () =>
        {
            // viewPage.Write(Scripts.Render("~/AppSelector/Scripts")); // If you use a Bundle
            viewPage.WriteLiteral("<script src=\"" + Url.Content("~/Scripts/Shared/_AppSelector.js") + "\" type=\"text/javascript\"></script>");
        });
    }
}

Just "send" the View to the PartialView (no Parent property like in WebForms?) and use it to add content to "ScriptsPartial" section.

"ScriptsPartial" is needed because DefineSection throws an error "section already defined: Scripts"

So, no more than one PartialView can use "ScriptsPartial" section... not so good solution.

Best regards,

Paco Ferre

like image 33
Paco Ferre Avatar answered Sep 27 '22 16:09

Paco Ferre