Add scripts at the head of Aspx - asp.net

I want to add some scripts at the head of a website, written in aspx. However, aspx pages do not have head part, but it is generated afterwards. how I can write something at the head of a website written in aspx?

You will have a layout page that has a head part. In that render an optional section for your scripts.
In your layout file:
<head>
...
#RenderSection("scripts", required: false)
</head>
And in your view in which you want to add scripts to the head part of the page do this:
#section scripts
{
#Scripts.Render("~/YourScript.js")
}

Related

Cannot load jquery before other script

I need to load JQuery before anything else, so I created this code inside _Layout:
<!DOCTYPE html>
<html>
<body class="sidebar-enable" data-keep-enlarged="true">
<div class="wrapper">
#RenderBody()
</div>
<script src="~/js/jquery.min.js"></script>
#RenderSection("DataTableScript", required: false)
</body>
</html>
I have a ViewComponent called ProductsViewComponent, I load it inside a View called Home in this way:
#await Component.InvokeAsync("Products", new { date = "2018-09-05" })
Inside the ViewComponent I need to load the DataTableScript (which requires JQuery for works properly), so I created this logic inside the Default.cshtml (which is the html of ProductsViewComponent):
#{
Layout = "/Views/Shared/_LayoutViewComponent.cshtml";
}
#section DataTableScript{
<script src="~/js/vendor/jquery.dataTables.js"></script>
<script src="~/js/vendor/dataTables.bootstrap4.js"></script>
<script src="~/js/vendor/dataTables.responsive.min.js"></script>
<script src="~/js/vendor/responsive.bootstrap4.min.js"></script>
<script src="~/js/vendor/dataTables.buttons.min.js"></script>
<script src="~/js/vendor/buttons.bootstrap4.min.js"></script>
<script src="~/js/vendor/buttons.html5.min.js"></script>
<script src="~/js/vendor/buttons.print.min.js"></script>
<script src="~/js/vendor/dataTables.keyTable.min.js"></script>
<script src="~/js/vendor/dataTables.select.min.js"></script>
<script src="~/js/dataTable.js"></script>
}
I have specified another Layout because the ViewComponent is not able to render a section (see this question for further information)
inside the _LayoutViewComponent I placed this code:
#RenderBody()
#RenderSection("DataTableScript")
Essentially RenderBody calls _Layout and then the DataTableScript are loaded. But when I start the application I get the DataTableScript loaded before of JQuery and this is really weird because in the _Layout I specified to load the DataTableScript after JQuery.
You can use a partial to render your script tags.
Views/Shared/_DataTableScriptsPartial.cshtml
<script src="~/js/vendor/jquery.dataTables.js"></script>
<script src="~/js/vendor/dataTables.bootstrap4.js"></script>
<script src="~/js/vendor/dataTables.responsive.min.js"></script>
<script src="~/js/vendor/responsive.bootstrap4.min.js"></script>
<script src="~/js/vendor/dataTables.buttons.min.js"></script>
<script src="~/js/vendor/buttons.bootstrap4.min.js"></script>
<script src="~/js/vendor/buttons.html5.min.js"></script>
<script src="~/js/vendor/buttons.print.min.js"></script>
<script src="~/js/vendor/dataTables.keyTable.min.js"></script>
<script src="~/js/vendor/dataTables.select.min.js"></script>
<script src="~/js/dataTable.js"></script>
In your _Layout.cshtml declare a scripts section.
<!DOCTYPE html>
<html>
<head>
#RenderSection("head", required: false)
</head>
<body class="sidebar-enable" data-keep-enlarged="true">
<div class="wrapper">
#RenderBody()
</div>
<script src="~/js/jquery.min.js"></script>
#RenderSection("scripts", required: false)
</body>
</html>
In the page that uses your ViewComponent render the partial in the scripts section.
Products.cshtml
#{
Layout = "_Layout";
}
#await Component.InvokeAsync("Products", new { date = "2018-09-05" })
#section scripts {
#await Html.PartialAsync("_DataTableScriptsPartial")
}
You cannot specify a layout for a view component view. It's essentially a partial view. By the time the view component is processed the main layout is already set in stone. You should use a script loading library to conditionally include your additional scripts, and then externalize the JavaScript that serves your view component and have it run after the associated scripts are finished loading.
There's various different libraries/techniques you can use for this: CommonJS, AMD, RequireJS, etc. You'll need to do some research and figure out which is the best fit for you. However, this is a transformative thing. It will change the entire way you handle scripts with your application and might require some major restructuring of anything existing, as a result.
The easier approach is to simply just include the script in your main layout. If your layout includes this view component, then it's always going to need the scripts anyways, so just go ahead make it static. It doesn't have a the warm fuzzies of a completely self-contained unit of functionality that you're wanting your view component to be, but to get there is going to likely require far more effort that is warranted or reasonable for this one particular scenario.
For what it's worth, you can optimize things a bit by front-loading the scripts using the <link rel="preload" href="..." as="script" /> tag. This would go in your head, and prompt supporting browsers to go ahead and load in the script, without actually running it (which is the part that blocks rendering). Then, by the time you actually include the script before the closing body tag, it's likely already good to go, and the script tag will simply prompt the browser to run it.
UPDATE
One further options is to use a client-side library that supports "components". This would be a replacement for your view component, not something you'd add in addition to. However, the benefit of a client-side component is that you can contain all the JavaScript functionality in that and then the library simply runs over your document at the end and wires everything up. I personally like Vue, but there's other choices like React, Ember, Angular, etc. Consult with the documentation for each to evaluate if you might prefer this approach instead and which particular library you prefer. They all essentially do the same thing, but they each have their own unique ways of getting there.
I like Vue personally because it's light-weight and largely unobtrusive. It doesn't necessarily force you to do things in a certain way, so you can have a bit more freedom in that respect. Libraries like React and Angular tend to be more opinionated, and since they're geared more towards creating single page applications, can sometimes make it difficult to split responsibilities with server-side rendering such as Razor views. Just my opinion though.

MVC5: Cannot Reference Scripts folder from within EditorTemplate

I have an editor template which cannot reference anything from the scripts folder. If I place the same reference in my layout page it works perfectly:
<script src="#Url.Content("~/Scripts/tinymce/jquery.tinymce.min.js")"></script>
This works in my layout page but does not load in my Editor Template page.
Edit: Google Developer tools show 404 (Not Found). The file is in the correct location as it can be referenced from my layout Page.
In the body element of your layout page you need to have this code somewhere like this below:
<body> ... #Html.RenderScripts() </body>
and reference your script in your editor template like below:
#Html.Script(
<script src="#Url.Content("~/Scripts/tinymce/jquery.tinymce.min.js")"></script>
)
here is the alternative:
<body> ... #RenderSection("scripts", required: false) </body>
and on your template :
#section scripts {
<script src="#Url.Content("~/Scripts/tinymce/jquery.tinymce.min.js")"></script>
}

master and content pages

I have a master page and two content pages that uses the master page for layout and design. I have 2 css files for my master page. Now what I want to do is that when I run first content page master page uses the first css file and when I run the second content page it uses the other one. Any suggestions about how should I do this .
First off, this should not be your normal approach unless you are doing something unusual. The whole point of using a common master page is so that you can easily have a common look and feel across your website.
But you can do it a few ways. One way would be to put a placeholder in your master pages <head> section. Then create content for that placeholder in each content page that includes the appropriate css file.
You can use a ContentPlaceHolder in the master page, and inside the head to change the css differently on every next page, or just ignore it to keep some default.
Here is an example:
<head runat="server">
<asp:ContentPlaceHolder ID="styleHolder" runat="server" >
<link rel="stylesheet" type="text/css" href="default.css">
</asp:ContentPlaceHolder>
</head>
<body>
and inside on the page with the different css, just include the the PlaceHolder and change it.

Best Approach: Mutliple content place holders in MVC

I am converting an ASP.Net web forms project to MVC3. The master page contains multiple content place holders at different locations.
I replaced the first content place holder with #RenderBody() but I am confused with what to do of the second one.
One approach might be to separate views and place a #Html.RenderAction() for each content place holder method. Is there a better way to do it?
Razor has got sections understanding in place of asp.net webforms ContentPlaceHolders. Take a look at this introductionary link.
You can use sections. For example, to have a section for scripts, in the head tag of the layout.cshtml, you can specifiy
<head>
<title>#ViewBag.Title</title>
<link href="#Url.Content("~/Content/Site.css")" rel="stylesheet" type="text/css" />
<script src="#Url.Content("~/Scripts/jquery-1.4.4.min.js")" type="text/javascript"></script>
#RenderSection("scripts", false);
</head>
Inside of any view, you can now add a scripts section to inject your scripts:
#section scripts{
<script src="#Url.Content("~/Scripts/myscript.js")" type="text/javascript"></script>
}
the "false" param tells MVC to render the section if exists on the child page or do nothing if no call

Usercontrol access Javascript from a Content's Page's Master Page

Hello all I have a problem. I have a masterpage that all of my Content pages inherit from. Within this masterpage I have a script tag pointing to the Javascript file folder ~/Scripts/validation.js
On my content pages I use different usercontrols that require the use of many of the functions within the validation.js file however if I dont put the <script> tag and the Javascript functions within a contentholder on the contentpage the usercontrols do not see these functions and I get errors like OnNameValidation is not defined.
Of course I can copy the Javascript code into all of the pages but that's 30+ pages and a maintenance nightmare if I find a bug in one of the Javascript functions.
So the question (if you haven't already figured out from my long dissertation) is how can I declare the script tag with the path to the validation.js file so that contentpages and their usercontrols etc. can access the functions/code.
What you are trying to do should work, so I suspect that the path to your javascript file is wrong (without seeing your html code I can only assume). Keep in mind that you can only reference the javascript file like this: "~/Scripts/validation.js" if you have the link in a HEAD runat="server" tag. Without the runat="server" it won't find the file. You would have to do something like "../scripts/validation.js"
As a test I would try to call your javascript function in the masterpage, so you can rule out a bad file reference.
I picked up this tip from ScottGu here.
Add this to you user control which enables Intellisense in user controls but always evaluates false:
<% if (false) { %>
<script src="/Scripts/validation.js" type="text/javascript"></script>
<% } %>
I am currently doing this in my site by going to the Source code on the master page and putting the following in the head and outside of the ContentPlaceHolder.
<head>
<asp:ContentPlaceHolder ID="HeadContent" runat="server">
</asp:ContentPlaceHolder>
<script src="CP.js" type="text/javascript"></script>
</head>
The path you are assigning for your js file is probably not matching in all the pages.
script src="../JavaScript/Scriptaculous/scriptaculous.js"
It should have something like above this if you have separate folder for Scripts, MasterPages, Pages & Controls.

Resources