Adding to Script Bundle from Partial View in .Net MVC 5

Adding to script bundle from partial view in .NET MVC 5

It just seemed to be specific to my jquery bundle. It now works, I have added a widgetspecific bundle where you can add scripts to render in the main layout. The bundle also handles the adding of the same file several times (which can happen if the same widget exists several times on the same page) and only renderes it once. My solution added below, which doesnt seem to be that well documented from the searches Ive done so far.

In BundleConfig.cs:

bundles.Add(new ScriptBundle("~/widgetspecific"));

In _Layout.cshmtl:

@Scripts.Render("~/widgetspecific")

In Widget.cshtml:

@{
var bundle = System.Web.Optimization.BundleTable.Bundles.GetBundleFor("~/widgetspecific");

bundle.Include("~/Scripts/andreas.js");
}

Is anyone aware of negative aspects to this solution?

Injecting content into specific sections from a partial view ASP.NET MVC 3 with Razor View Engine

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 using the @scripts section of the main view to do that and not have the partials worry about scripts.

How to include script bundle in scripts section in view

Why mix the rendersection with bundling? If you choose to down the route of bundling, you can simply put your scripts in .JS file ,put it in their own bundle if you like and call that bundle on your view. For ex:

     bundles.Add(new ScriptBundle("~/bundles/myscripts").Include(
"~/Scripts/myscript1.js",
"~/Scripts/myscript2.js"));

then view will have the following:

    @Scripts.Render("~/bundles/myscripts")   

Also make sure your Web.config has compilation debug set to false like below:

  <compilation debug="false" />            

it makes sure the scripts are bundled and minified.

Update

Based on comments and my recent experience, I can see why would we want to use the two together. Perfect case of learning in the community! :) So, if you decide to come back for refactoring, I would make sure there are no typos to begin with. If it still does not work, please let me know what the problem is and I will update the answer accordingly. Thanks everyone!

Asp.net MVC Multiple (of the same) Partial Views on a page with script tags inside Partial View

David,

I use a couple of static htmlhelpers in my code for exactly this scenario. it works on the principle that the context.items collection gets populated per request and therefore if an item exists in the context.items collection then it doesn't get added twice. anyway, enough of the scottish words of wisdOOOm, 'yill jist be waantin the coade'...

for our Scripts:

public static MvcHtmlString Script(this HtmlHelper html, string path)
{
var filePath = VirtualPathUtility.ToAbsolute(path);
HttpContextBase context = html.ViewContext.HttpContext;
// don't add the file if it's already there
if (context.Items.Contains(filePath))
return MvcHtmlString.Create("");

// add the beast...
context.Items.Add(filePath, filePath);

return MvcHtmlString.Create(
string.Format("<script type=\"text/javascript\" src=\"{0}\"></script>", filePath));
}

for our cuddly css:

// standard method - renders as defined in as(cp)x file
public static MvcHtmlString Css(this HtmlHelper html, string path)
{
return html.Css(path, false);
}
// override - to allow javascript to put css in head
public static MvcHtmlString Css(this HtmlHelper html,
string path,
bool renderAsAjax)
{
var filePath = VirtualPathUtility.ToAbsolute(path);

HttpContextBase context = html.ViewContext.HttpContext;
// don't add the file if it's already there
if (context.Items.Contains(filePath))
return null;

// otherwise, add it to the context and put on page
// this of course only works for items going in via the current
// request and by this method
context.Items.Add(filePath, filePath);

// js and css function strings
const string jsHead = "<script type='text/javascript'>";
const string jsFoot = "</script>";
const string jsFunctionStt = "$(function(){";
const string jsFunctionEnd = "});";
string linkText = string.Format("<link rel=\"stylesheet\" type=\"text/css\" href=\"{0}\"></link>", filePath);
string jsBody = string.Format("$('head').prepend('{0}');", linkText);

var sb = new StringBuilder();

if (renderAsAjax)
{
// join it all up now
sb.Append(jsHead);
sb.AppendFormat("\r\n\t");
sb.Append(jsFunctionStt);
sb.AppendFormat("\r\n\t\t");
sb.Append(jsBody);
sb.AppendFormat("\r\n\t");
sb.Append(jsFunctionEnd);
sb.AppendFormat("\r\n");
sb.Append(jsFoot);
}
else
{
sb.Append(linkText);
}

return MvcHtmlString.Create( sb.ToString());
}

usage in both cases:

<%=Html.Css("~/Content/Site.Css")%>
<%=Html.Script("~/Scripts/default.js")%>

have fun...

[edit] - pay particular attn to the comment line:

// this of course only works for items going in via the current
// request and by this method

How to get an ASP.NET Core MVC view to refer to a script section in another file?

Thank you Jonespopolis for giving me this approach.

Essentially, what I need to do is to make a Layout template file, specifying that I am using my preexisting Layout file that I was already using, and declaring where all the JS tags would go. For instance, here's my template file:

@{
Layout = "_Layout";
}

@RenderBody()

@section Scripts
{
<% for (index in htmlWebpackPlugin.files.js) { %>
<script src="<%= htmlWebpackPlugin.files.js[index] %>"></script>
<% } %>
}

This template file refers back to my original _Layout.cshtml file:

<!DOCTYPE html>
<html lang="en">
<head>
<!-- Head content here -->
</head>
<body>
<!-- Header content here -->

<div class="container">
<main role="main" class="pb-3">
@RenderBody()
</main>
</div>

<!-- Footer content here -->
</footer>
@await RenderSectionAsync("Scripts", required: false)
</body>
</html>

The @await RenderSectionAsync("Scripts", required: false) line will render the Script section that I created in my template file.

From there, I used Webpack's Htmlwebpackplugin with the following config:

plugins: [
new HtmlWebpackPlugin({
inject: false,
template: 'Views/Shared/PageTemplate.cshtml',
filename: '../../Views/Shared/home.sources.cshtml',
minify: false
}),
],

Running the webpack command will net us a home.source.cshtml file containing everything in the template file, but it shows my actual JS references needed for home.cshtml. All that's left is to make this file be the Layout for the page, by inserting this at the beginning:

@{
Layout = "home.sources";
}

Running the application gives me the home page with all the correct JS tags downloaded! Now if I ever change my JS dependencies, I don't need to ever worry about generating the tags nor inserting them into the page, since all of that has been automated now, which is exactly what I wanted!



Related Topics



Leave a reply



Submit