Asp.Net Mvc Bundles and Specific Views - asp.net

I use DataTables in some specific tables and it needs at least 10 different js/css files to work in my situation. So i tried to put them in a bundle and called that bundle in that view. But no success.
My question is that: Are bundles only for entire site (loads in every page) or can i use some of them in specific views only?
BundleConfig
bundles.Add(new ScriptBundle("~/Content/DataTablesJS").Include("~/Content/DataTables/*.jss"));
bundles.Add(new StyleBundle("~/Content/DataTablesCSS").Include("~/Content/DataTables/*.css"));
View
#section Styles
{
#Scripts.Render("~/Content/DataTablesCSS")
}
#section Scripts
{
#Scripts.Render("~/Content/DataTablesJS")
<script src="~/Content/SayfaJSs/DataTables.jss" type="text/javascript"></script>
<script>
jQuery(document).ready(function() {
DataTables.init();
});
</script>
}
HTML Output
<script src="/Content/DataTablesCSS?v=z-Ctaq2TbplDFpORl0e9NGH8TjpB5hQ2cPam2OxmDEo1"></script>
<script src="/Content/DataTablesJS?v=2gXGKlcqr0bFFqv6Bbr9jB_7LVvvHDrghzBwHCgFJds1"></script>

In your layout you would have something like this:
#RenderSection("Scripts", required: false)
...Then in your view you would add your bundle reference like this:
#section Scripts {
#Scripts.Render("~/bundles/yourBundle")
}

I found the problem. It was using asterisk to get all scripts in folder. From asp.net website:
"Adding scripts by wildcard defaults to loading them in alphabetical order, which is typically not what you want. "
My scripts needs a special order. So i included them in order that i need:
bundles.Add(new StyleBundle("~/Content/DataTablesCSS")
.Include("~/Content/DataTables/dataTables.bootstrap.css",
"~/Content/DataTables/buttons.dataTables.min.css",
"~/Content/DataTables/select.dataTables.min.css"));
bundles.Add(new ScriptBundle("~/Content/DataTablesJS")
.Include("~/Content/DataTables/jquery.dataTables.min.js",
"~/Content/DataTables/dataTables.bootstrap.js",
"~/Content/DataTables/dataTables.buttons.min.js",
"~/Content/DataTables/dataTables.select.min.js",
"~/Content/DataTables/buttons.bootstrap.min.js",
"~/Content/DataTables/jszip.min.js",
"~/Content/DataTables/pdfmake.min.js",
"~/Content/DataTables/vfs_fonts.js",
"~/Content/DataTables/buttons.html5.min.js",
"~/Content/DataTables/buttons.print.min.js"));

Related

Cannot load script in ViewComponent

I created a ViewComponent which display a Table that require some plugin for enable specific functionalities. Inside the ViewComponent I tried to create a specific section:
#section DataTableScripts{
<script src="~/js/JQuery/jquery.dataTables.js"></script>
}
unfortunately I discovered that a ViewComponent cannot load a #section.
So I tried to include the script directly in the ViewComponent, but the problem is that the scripts are loaded before of JQuery which is loaded inside the _Layout, specifically:
ViewComponent
<script src="~/js/JQuery/jquery.dataTables.js"></script>
<script src="~/js/JQuery/dataTables.buttons.min.js"></script>
<script src="~/js/JQuery/dataTables.keyTable.min.js"></script>
<script src="~/js/JQuery/dataTables.responsive.min.js"></script>
<script src="~/js/JQuery/dataTables.select.min.js"></script>
<script src="~/js/JQuery/dataTables.bootstrap4.js"></script>
<script src="~/js/JQuery/jquery.dataTables.js"></script>
Layout
<script src="~/js/jquery.min.js"></script>
so in this case I'll get:
jQuery is not defined
How can I manage this situation?
Simply set the Layout for your ViewComponent .
#{
Layout = "/Views/Shared/_Layout.cshtml";
}
#section DataTableScripts{
<div>It works </div>
<script src="~/js/JQuery/jquery.dataTables.js"></script>
}
Here's the screenshot that works :
[Edit]
This approach does not seems a good way to do that . As #Kirk Larkin says , this will make the Layout render twice . Another patch is to write a new RefinedLayout.cshtml and set the Layout of ViewComponent as the RefinedLayout :
#{
Layout = "_RefinedLayout.cshtml";
}
#section DataTableScripts{
<div>It works </div>
<script src="~/js/JQuery/jquery.dataTables.js"></script>
}
For more information , refer workaround by MortenMeisler
You are using<script src="~/js/JQuery/jquery.dataTables.js"></script> twice. Just keep it once.
Specifying another layout for viewcomponents with scripts will duplicate scripts. And #section is just ignored during rendering.
So I replaced jquery document ready with plain javascript domcontentloaded and any jquery can be written inside domcontentloaded. Not a permanent good approach but works for me.
<script>
document.addEventListener('DOMContentLoaded', function (event) {
console.log($ === jQuery)
});
</script>

ZURB Foundation 6 Panini #ifpage not working

Using ZURB Foundation Template, building with NPM.
I have the following code in my default.html layout page:
<script src="{{root}}assets/js/app.js"></script>
{{#ifpage 'admin'}}
<script src="{{root}}assets/js/single-page/admin.js"></script>
{{/ifpage}}
{{#ifpage 'dashboard'}}
<script src="{{root}}assets/js/single-page/dashboard.js"></script>
{{/ifpage}}
In gulpfile.js I have as a member of the 'javascript' PATHS array:
'!src/assets/js/single-page/**/*'
I then, do:
gulp.task('single-page', function() {
return gulp.src('src/assets/js/single-page/**/*')
.pipe(gulp.dest('dist/assets/js/single-page'))
.on('finish', browser.reload);
});
Then...
gulp.task('build', function(done) {
sequence('clean', ['pages', 'sass', 'javascript', 'single-page', 'images', 'php', 'chart_data', 'copy'], 'styleguide', done);
});
And finally...
gulp.task('default', ['build', 'server'], function() {
gulp.watch(PATHS.assets, ['copy']);
gulp.watch(['src/pages/**/*'], ['pages']);
gulp.watch(['src/{layouts,partials,helpers,data}/**/*'], ['pages:reset']);
gulp.watch(['src/assets/scss/**/{*.scss, *.sass}'], ['sass']);
gulp.watch(['src/assets/js/**/*.js'], ['javascript']);
gulp.watch(['src/assets/js/single-page/**/*.js'], ['single-page']);
gulp.watch(['src/assets/img/**/*'], ['images']);
gulp.watch(['src/assets/php/**/*'], ['php']);
gulp.watch(['src/assets/chart_data/**/*'], ['chart_data']);
gulp.watch(['src/styleguide/**'], ['styleguide']);
});
My three pages are all PHP pages with the names index.php, admin.php, and dashboard.php. The js/single-page directory is being written to the dist folder and the two JS files are there.
The Panini conditional doesn't seem to be working so the admin-specific and dashboard-specific paths do not appear on their respective PHP pages.
Colin Marshall in his answer to How to add JavaScript just for one specific page? mentions a config.yml file and a gulpfile.babel.js file, neither of which are in my project's directory.
Any suggestions?
Thank you.
Simple fix after a bit of fiddling. Seems Panini 'page' var returned the full page name including .php. Once I checked for admin.php or dashboard.php all worked fine.
I can only imagine there's some code change I can make to return the page name without the file extension.

Dust.js - Render precompiled anonymous template on client side

Is there a way to render a precompiled template that has no name on the client side in DustJs?
Because documentation only shows with a name:
<!-- precompiled templates -->
<script type="text/javascript" src="/lib/templates.js"></script>
<script type="text/javascript">
// The templates are already registered, so we are ready to render!
dust.render('hello', { world: "Saturn" }, function(err, out) {
document.getElementById('output').textContent = out;
})
</script>
EDIT : Ok it's probably too complicated to load a file, and I just noticed that when we compile without specifying name (in order to compile many template simultaneously), the path of the template is set as the default name. It is even editable with --pwd flag.
There is therefore always a name so the above function can operate.
It sounds like you would like to load templates by their path after they have been precompiled. Dust allows you to do this via AMD (require.js) compatibility.
http://www.dustjs.com/guides/setup/#amd
Once you've loaded require.js and set define.amd.dust = true, you can call dust.render with the path to a template and Dust will automatically load it for you.
Note that this requires that you compile your templates with the --amd flag.
<script src="r.js"></script>
<script type="text/javascript">
define.amd.dust = true;
require(["lib/dust-full"], function(dust) {
dust.render('path/to/your/template', function(err, out) { ... });
});
</script>
The Dust repository has an example of using AMD to load templates.

How to conditionally load / bundle CSS files in Meteor 1.0?

I know this question has been asked before but I'm wondering if something has changed with the advent of 1.0.
I don't want Meteor to automatically bundle together every single CSS file in my app. My admin pages are going to have a completely different CSS than my client-facing pages and using namespaces seems like a really over-complicated solution. How do I have Meteor load certain CSS files on certain pages and NOT load certain CSS files on certain pages?
The same question goes for JS files.
I know someone said this would be useful:
https://github.com/anticoders/meteor-modules
Any comments on this package for conditional CSS and JS?
You can just put your CSS files somewhere under /public and manually include them from your templates where required. Everything under /public will NOT get bundled, and the URL will have the /public removed e.g.
Create two files: your_meteor_project/public/one.css and ......./two.css. These will be available from your client at http://example.com/one.css (i.e. the "public" does not form part of the URL, it's like the document root for using meteor as a plain old web server).
meteor create cssSwitcher
cd cssSwitcher/
mkdir public
echo 'html, body { background-color: red; }' > public/one.css
echo 'html, body { background-color: blue; }' > public/two.css
Create a reference to a helper function "appropriateStylesheet" in the head of your HTML :
HTML template
<!-- add code to the <body> of the page -->
<body>
<h1>Hello!</h1>
{{> welcomePage}}
</body>
<!-- define a template called welcomePage -->
<template name="welcomePage">
<!-- add code to the <head> of the page -->
<head>
<title>My website!</title>
<link rel="stylesheet" href="/{{appropriateStylesheet}}" type="text/css" />
</head>
<p>Welcome to my website!</p>
<button id="red">Red</button>
<button id="blue">Blue</button>
</template>
Create a helper function.
JavaScript:
if (Meteor.isClient) {
Session.set("stylesheet","red.css");
Template.registerHelper("appropriateStylesheet", function() {
return Session.get("stylesheet");
});
Template.welcomePage.events({
'click #blue' : function() { Session.set("stylesheet","two.css"); },
'click #red' : function() { Session.set("stylesheet","one.css"); },
});
}
You can do exactly the same thing with JS files. Put them under /public and meteor ignores them.

Bundle Scripts.Render In Area View Not Working

I have an MVC 4 site with an area. I setup two script bundles, one for all common scripts the site will need and the other for scripts related to area. I have a common layout view for the site where the common site bundles are referenced using Scripts.Render(). I have a second layout view for the area, which uses the common layout view, where I would like to render the area-specific javascript files, but it does not work and no files are rendered at all. If I move the bundle render to the root layout view, it renders fine.
Any reason why this does not work in the area view and how I can get it to work? I'd rather not have these area-specific scripts available for all users, since only a very small, defined subset actually need them.
Common Layout View:
#Scripts.Render(#"~/Scripts/all_scripts")
...
#RenderSection("Javascript", required: false)
Area Specific View:
#section Javascript {
#Scripts.Render(#"~/Scripts/area_scripts")
#RenderSection("Javascript", required: false)
}
I tested this and it appears to be working fine. Admin specific scripts are rendered in the admin index view (and works in the admin layout too). Are all the bundles/paths configured correctly?
BundleConfig.cs
bundles.Add(new ScriptBundle("~/bundles/jqueryui").Include(
"~/Scripts/jquery-ui-{version}.js"));
bundles.Add(new ScriptBundle("~/bundles/jqueryadmin").Include(
"~/Scripts/Admin/jquery.unobtrusive-ajax-admin*",
"~/Scripts/Admin/jquery.validate-admin*"));
_Layout.cshtml
#Scripts.Render("~/bundles/jqueryui")
#RenderSection("Javascript", required: false)
_AdminLayout.cshtml
#{
ViewBag.Title = "_AdminLayout";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<h2>AdminLayout</h2>
#section Javascript{
#RenderSection("Javascript", required: false)
}
AdminHome/Index.cshtml
#{
ViewBag.Title = "Index";
Layout = "~/Areas/Admin/Views/Shared/_AdminLayout.cshtml";
}
<h2>Index</h2>
#section Javascript{
#Scripts.Render("~/bundles/jqueryadmin")
}
Hope this helps.

Resources