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
Anchor Tag Download Attribute Not Working :Bug in Chrome 35.0.1916.114
Kendo Chart Legend:Label at Left, Color at Right
Something Similar to Treegrid in Jqgrid
Jquery UI Switchclass() Method Is Not Working Properly
Detect High Contrast Extension Use in Chrome Browser
Detecting Click Event on Padding Only
How to Detect MAC Os Inverted Color Mode in JavaScript/Css
Dynamically Changing Stylesheet Path Not Working in Ie and Firefox
Highcharts: Make the Legend Symbol a Square or Rectangle
How to Properly Escape Attribute Values in CSS/Js Attribute Selector [Attr=Value]
Customize Ng-Repeat in Angularjs for Every Nth Element
How to Show the Child Div on Mouse Hover of Parent Div
Hiding Div If Using Mobile Browser
Modify Pseudo-Element :After's Width Using JavaScript
How to Style Canvas Elements with CSS
How to Create and Apply CSS to JavaScript Alert
CSS Textarea That Expands as You Type Text
How to Disable JavaScript Function Calls from the Browser Console