How to Put Javascript into an ASP.NET MVC View - asp.net

I'm really new to ASP.NET MVC, and I'm trying to integrate some Javascript into a website I'm making as a test of this technology.
My question is this: how can I insert Javascript code into a View?
Let's say that I start out with the default ASP.NET MVC template. In terms of Views, this creates a Master page, a "Home" View, and an "About" view. The "Home" View, called Index.aspx, looks like this:
<%# Page Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage" %>
<asp:Content ID="indexTitle" ContentPlaceHolderID="TitleContent" runat="server">
Home Page
</asp:Content>
<asp:Content ID="indexContent" ContentPlaceHolderID="MainContent" runat="server">
<h2><%= Html.Encode(ViewData["Message"]) %></h2>
<p>
To learn more about ASP.NET MVC visit http://asp.net/mvc.
</p>
<p>Welcome to this testing site!</p>
</asp:Content>
Adding a <script> tag here didn't work. Where and how should I do it?
P.S.: I have a feeling I'm missing something very basic... Thanks in advance!

One thing you may want to consider is adding a "scripts" content place holder to your master page, that loads scripts at the end of the body. This way you load your scripts at the end of the page so that it doesn't slow down loading the DOM elements (once a script starts loading it only does one request at a time, because the code can affect the DOM). This gets a little tricky with PartialView -- if you include code in them you need to figure out a way to delay executing anything that relies on later scripts after those scripts have loaded. A compromise might be to load things like jQuery in the header and the rest of your common scripts at the end of the body.
Site.Master
<body>
...
<asp:ContentPlaceHolder runat="server" id="MainContent"></asp:ContentPlaceHolder>
...
<script type="text/javascript" src="<%= Url.Content( "~/scripts/jquery-1.4.1.min.js" ) %>"></script>
<asp:ContentPlaceHolder runat="server" id="ScriptContent"></asp:ContentPlaceHolder>
</body>
</html>
View
<asp:Content runat="server" ID="mainContent" ContentPlaceHolderID="MainContent">
... HTML ...
</asp:Content>
<asp:Content runat="server" ID="scriptContent" ContentPlaceHolderID="ScriptContent">
<script type="text/javascript">
$(function() {
$('.selector').click( function() {
...
});
});
</script>
</asp:Content>

Just stumbled on this question and would like add a comment that in Visual Studio 2013 it can be done in more elegant way.
In your master page just put the following code at the bottom of the page (in the default generated master page this code is already there):
<body>
...
#RenderSection("scripts", required: false)
</body>
</html>
Then in your view just at the bottom the following code:
#section scripts
{
<script src="...script url..."></script>
}
or if you use bundles
#section scripts {
#Scripts.Render("~/bundles/<script id>")
}
or you can put a <script>...</script> section with your Javascript code into the #section scripts block in the view.

Go create an additional <asp:ContentPlaceHolder> inside of the <head> of your masterpage and then your views will have a third <asp:Content> section for you to register external .js files, custom <script> blocks, external .css files, and custom <style> blocks.

The <script> tag needs to go inside an <asp:Content> block. (Otherwise, where would it end up?)

Related

Embedding an Angular app inside .net ASPX page with master page

I've an ASP.NET Web application with master page containing a header, tabs, BodyContent(each page content goes here), footer place holders for user controls (header, tabs, footer) and page content (MainContent). The Tabs user control has unordered list of tabs, for example let's consider Tab's text as TabOne, TabTwo, TabFour, One click of each tab respective webpage loads with the help a javascript function with below line of code:
window.location.href = "TabOne.aspx";
Now I got a new request to add a tab TabThree to load an angular page showing Header, tabs, footer and the BodyContent holding the content of angular application i.e., on click of TabThree, I've to load an angular application in existing ASP.NET web application similar to the reference link(How to include external Angular 2 app in ASP.NET Webforms aspx page)
//TabThree.aspx
<%# Page Title="" Language="C#" MasterPageFile="~/Base.Master" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="Programs.Default" %>
<%# MasterType VirtualPath="~/Base.Master" %>
<asp:Content ID="Header" ContentPlaceHolderID="Header" runat="server">
<%--<base href="/AngularComponents/">--%> //No difference with uncommenting the base href
<%--<base href="/">--%>
<script type="text/javascript" src="../Tabs.js"></script>
</asp:Content>
<asp:Content ID="Tab" ContentPlaceHolderID="Tab" runat="server">
</asp:Content>
<asp:Content ID="BodyContent" ContentPlaceHolderID="BodyContent" runat="server">
<div id="pageContent">
<app-root>Loading...</app-root>
<script type="text/javascript" src="AngularModules/inline.bundle.js"></script>
<script type="text/javascript" src="AngularModules/main.bundle.js"></script>
<script type="text/javascript" src="AngularModules/polyfills.bundle.js"></script>
<script type="text/javascript" src="AngularModules/vendor.bundle.js"></script>
<link href="AngularModules/styles.bundle.css" rel="stylesheet" />
</div>
</asp:Content>
<asp:Content ID="Footer" ContentPlaceHolderID="Footer" runat="server">
</asp:Content>
If I run the angular application independently it launches fine with ng serve -o command and it comes up fine at the URL (http://localhost:4200/#/TabThree?id=TID100). Now I've copied the dist folder to the ASP.NET Web application workspace and renamed it as AngularModules, On click of TabThree I've tried to load the angular component into Bodycontent with one of the below line of code for navigation:
window.location.href = "TabThree.aspx/#/TabThree?ID=TID100";
window.location.href = "TabThree.aspx?AngularComponents/#/TabThree?ID=TID100";
The Head content loads fine but the Bodycontent which supposed to load Angular component of TabThree is blank with the console error logged as below:
ERROR Sys.ParameterCountException: Sys.ParameterCountException: Parameter count mismatch.
"ERROR"
{
[functions]: ,
__ proto __: { },
__zone_symbol__currentTask: { },
description: "Sys.ParameterCountException: Parameter count mismatch.",
message: "Sys.ParameterCountException: Parameter count mismatch.",
name: "Sys.ParameterCountException",
stack: "Sys.ParameterCountException: Sys.ParameterCountException: Parameter count mismatch.
at String$startsWith (http://localhost:62557/ScriptResource.axd?
d=gb2H0hcR0_2oXWpLxJmdTg2S_j-8tZAZO1r6sTjByVD4-_6_cs99E6CayZY9pi0-N-ip5bmZNlhZWaB-IG2xnFZG-NKKnY8LqkMvfx1uzDhC1zqaP8PQi4JB24Hq7urD6rwOMv6ZCQbxzc19pQ0mcl6iexnSPre_a0zN-jpBGmFTlZ5rxoZ47qCy4shfjh4T0&t=ffffffff87bbe9c7:494:12)
at startsWith
I referred the link (Including an Angular2 application to Asp.Net Webforms Page) but that too didn't solve the problem and I'm not able to launch the Angular component as a Tab in the BodyContent placeholder.
I've studied both the reference links but they don't have the right information about how the routing/navigation is happening to load the angular component in the ASPX Page.
I've tried other approaches than mentioned above which redirects the entire page and launch Angular application as a standalone but my requirement is to inscribe the angular component into the Bodycontent of the TabThree.aspx page so it would be consistent with the other Tabs/pages.
Any help in solving this Routing issue in the hybrid application would be a great help and I would appreciate the same.
Thanks in Advance!!
I didn't find any possible duplicate for the same and I've linked the references as well, Hopefully this is not marked as duplicate.
I've fixed with the help of IFrame in the aspx page.
//TabThree.aspx
<div id="dvngComponent" runat="server"></div>
//TabThree.aspx.cs
string url = "AngularComponents/#/TabThree?ID=TID100";
HtmlGenericControl ngComponent = new HtmlGenericControl("iframe");
ngComponent.Attributes.Add("id", "frmNgComponent");
ngComponent.Attributes.Add("src", url);
ngComponent.Attributes.Add("allowtransparency", "true");
ngComponent.Attributes.Add("frameBorder", "0");
ngComponent.Style["margin"] = "0 0 0 0";
ngComponent.Style["width"] = "100%";
ngComponent.Attributes.Add("height", "300px");
dvngComponent.Controls.Add(ngComponent);

Failure to implement external css file in .aspx content page in asp.net WebForms application

I am struggling to implement an external CSS file in the content pages of my asp.net WebForms application. The content page thus have a master page (Site.Master) in which I included the following code in the head section:
<asp:ContentPlaceHolder ID="HeadContent" runat="server">
<link href="Styles/pokerpsych.css" rel="stylesheet" type="text/css" />
</asp:ContentPlaceHolder>
The asp:ContentPlaceholder tag thus contains the link to the CSS file that I want to apply to all pages. The styling in this link is thus successfully applied to the content in the body tag of the Site.Master page however the styles specified in this file is not applied to IDs that are specified for content pages. In one of my content pages I have for instance the following code:
<%# Page Title="" Language="C#" MasterPageFile="~/Site.Master" AutoEventWireup="true" CodeBehind="PostHand.aspx.cs" Inherits="PokerPuzzleWebforms.PostHand" %>
<asp:Content ID="Content1" ContentPlaceHolderID="MainContent" runat="server">
<header>
<h1>Post your hand here</h1>
</header>
<main>
<label runat="server" for="titleBox" id="titleLabel" >Title</label>
<input type="text" id="titleBox" name="titleBox" runat="server" />
</main>
</asp:Content>
I am thus trying to apply styling to the label for the textbox (id="titleLabel") although I have not been successful.
I have validated the CSS file and there seems to be no errors. I have also tried to override the pokerpsych.css with another external CSS file by adding the following code in the content page:
<asp:Content ID="Head" ContentPlaceHolderID="HeadContent" runat="server">
<link href="Styles/posthandstyle.css" rel="stylesheet" type="text/css" runat="server"/>
</asp:Content>
I also tried embedding a style tag within the asp:Content tag although this was not successful. I am however only able to apply the styles to the id when I make use of inline styles although I would prefer to include an external file to apply the styles.
Below is the CSS file (pokerpsych.css):
body {
}
#test{
color:red;
}
#titleLabel {
color:red !important;
margin-right:100px;
}
From user1429080's comment:
This is probably caused by dynamic ID handling in Web Forms. The ID of the textbox in the rendered HTML is likely different from just titleLabel. Check by View source on the rendered page.
The easiest workaround might be to use class-based CSS and refer to the correct class on the control in the ASPX page instead of the IDs.

Umbraco Nested Masterpages

I'm trying to create nested master pages in Umbraco 4.7.1 and I'm having issues.
I've got a masterpage doctype and an index doctype which is a child of masterpage.
Then I have a separate doctype called slide show.
My content looks like this:
Index
SlideShow
My master page template has the reference to the index like this:
<asp:ContentPlaceHolder ID="Content" runat="server" />
then inside the index my code is between
<asp:Content ContentPlaceHolderID="Content" runat="server">
</asp:Content>
and inside the Index template I reference the next level which is an Image slider
<asp:ContentPlaceHolder ID="SlideShow" runat="server" />
and the SlideShow template has code between
<asp:Content ContentPlaceHolderID="SlideShow" runat="server">
</asp:Content>
It worked for the Index but not for the slideshow.
The only difference I can think of off hand is the doctype for index is actually a child doctype of the master. And the SlideShow doctype is actually it's own doctype. Not a child of any of them.
Any ideas how to get this working?
Having nested pages inside Umbraco is perfectly fine. In fact, it's actually an ASP.Net mechanism which doesn't necessarily relate to any heirachy in Umbraco. So it's possible to have unique Umbraco document types which don't inherit from each other, yet one master template is nested in the other.
Master templates work in a way where a master doesn't specify which templates inherit from it, it's always the child template referring to the master template, much like inheritence in object orientated programming languages. The <asp:Content /> tag in the child specifies which <asp:ContentPlaceHolder /> it uses from the parent.
I'm a bit confused how you've setup the master templates from the description, but you should try to have it setup like the following ...
Root Master Template:
<asp:ContentPlaceHolder ID="Content" runat="server" />
Index Master Template:
<asp:Content ContentPlaceHolderID="Content" runat="server">
<!-- your html -->
<asp:ContentPlaceHolder ID="IndexLeft" runat="server" />
<!-- your html -->
<asp:ContentPlaceHolder ID="IndexRight" runat="server" />
<!-- your html -->
</asp:Content>
Slide Show Master Template:
<asp:Content ContentPlaceHolderID="IndexLeft" runat="server">
<!-- your html -->
</asp:Content>
<asp:Content ContentPlaceHolderID="IndexRight" runat="server">
<!-- your html -->
</asp:Content>
You can create as many nested templates as you want, sanity-permitting. Making a document type use the template Index won't include the slide show. You'd need to give it the Slide Show template instead.
There's more info on it here: http://msdn.microsoft.com/en-us/library/ie/x2b3ktt7.aspx
Hope it helps.

The Controls collection cannot be modified because the control contains code blocks (i.e. <% ... %>)

I am trying to add a panel as a child control of another panel in the codebehind of a master page, it's a simple as:
Panel1.Controls.Add(Panel2)
However when I try to do that, I get this error:
The Controls collection cannot be modified because the control contains code blocks (i.e. <% ... %>).
There are a number of questions that talk about having <%= %> elements in the head section, which I do not have. I have been so far as to remove all <% %> elements from this page, to no avail, the error still occurs. Can anyone suggest a way to get this to work?
* Example for Answer B *
=== code with error ===
<script type="text/javascript">
jQuery(document).ready(
function() {
alert('Hello!');
jQuery("#<%=TxtSampleId.ClientID %>").focus();
}
);
</script>
=== code without error ===
<asp:PlaceHolder id="dontCare" runat="server">
<script type="text/javascript">
jQuery(document).ready(
function() {
alert('Hello!');
jQuery("#<%=TxtSampleId.ClientID %>").focus();
}
);
</script>
</asp:PlaceHolder>
The "The Controls collection cannot be modified because the control contains code blocks (i.e. <% ... %>)." error can be very annoying to say the least. It's a bug that Microsoft refuses to fix because there are workarounds. It happens when you try to dynamically load controls from the code behind, but your page source conflicts. Could be a few things going on...
Note: Stack Overflow doesn't handle syntax of code examples well, so I'll reference each answer with a letter, and in a later post, I'll attempt to type out an example. But I don't want to clutter this post because I want to get my points across.
A.) you have a <% Response.Write("something") %> in your page source. Or a <% CodeBehindMethod() %>. Remove it and be creative to populate it a different way!! One way is to place an ASP.NET Panel control (like a Panel ==> turns into a div tag when it renders to HTML) onto your page and dynamically populate the inner HTML attribute of that control. There are other ways of dealing with this.
B.) you are trying to use jQuery inside of an inline script block within your control, you will also get this. Surround the inline javascript code block with an ASP.NET PlaceHolder tag. It's that simple. If you don't, some jQuery functionality will work, but not all of it!
C.) If you are using Script Manager without a Masterpage, I'd suggest you start using a Masterpage to avoid issues later. Then use an ASP.NET ContentPlaceHolder for your head and your body tags to make customizing pages easier. When you reference your javascript files within your masterpage, and you're using Script Manager, make sure to put a Scripts tag inside your ScriptManager tag. Then inside the Scripts tag, place a ScriptReference tag with a Path of the full path of your Javascript files in there. Make sure to put a tilda and forward slash "~/" in the beginning of your path from the root of your web app. Many will put their ScriptManager tag in their control. Don't do this. Put it in your masterpage! It makes life easier.
D.) If A, B or C didn't answer your question, then I'd suggest stripping away every piece of your page and all controls in it, and add each one at a time. If you have a huge hierarchy of page and control inheritance (if your application doesn't have a Masterpage), good luck! You'll eventually figure out what caused it.
* Example for Answer C *
=== code without error ===
Masterpage code:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><meta http-equiv="X-UA-Compatible" content="IE=7" />
<html xmlns="http://www.w3.org/1999/xhtml">
<title>Stack Overflow Example</title>
<link rel="stylesheet" type="text/css" href="/style/jquery-ui-1.8.10.custom.css">
<asp:ContentPlaceHolder id="head" runat="server">
<asp:ContentPlaceHolder>
</head>
<body>
<form id="Form1" method="post" runat="server">
<asp:ScriptManager ID="anything" runat="server">
<Scripts>
<asp:ScriptReference Path="~/scripts/md5.js" />
<asp:ScriptReference Path="~/scripts/jquery-1.4.4.min.js" />
<asp:ScriptReference Path="~/scripts/jquery-ui-1.8.10.custom.min.js" />
<asp:ScriptReference Path="~/custom_crap.js" />
</Scripts>
</asp:ScriptManager>
<asp:ContentPlaceHolder id="body" runat="server">
</asp:ContentPlaceHolder>
</form>
</body>
</html>
====================================================
Page source:
<asp:Content runat="server" ID="headcontent" ContentPlaceHolderID="head">
.. place your page specific header files here (js, css, etc..)
</asp:Content>
<asp:Content runat="server" ID="bodycontent" ContentPlaceHolderID="body">
.. place your page specific body HTML or ASP.NET code here
</asp:Content>

loading javascript file in ASP.NET for a single page

I'm using ASP.NET with a master page containing a script manager. I want to add a javascript file to only one page, but all pages inherit from the master. What is the proper way to accomplish this?
thanks in advance
Add a script manager proxy to the page you wish to add the javascript to and then add the javascript reference using the script manager proxy
In the Master Page add a content container in the HEAD section, in your page put the Javascript tag inside the instance of that container.
EDIT - for d03boy
On MasterPage:
<head runat="server">
<asp:ContentPlaceHolder ID="HeadContent" runat="server" />
</head>
On ContentPage:
<asp:Content ID="LocalHeadContent" ContentPlaceHolderID="HeadContent" runat="server">
<script type="javascript" \>
</asp:Content>
For any content page that doesn't have something to include in the page header there's no need to even create the Content tag.
Can you just use the ClientScriptManager?
if (!Page.ClientScript.IsClientScriptIncludeRegistered("MyKey"))
{
Page.ClientScript.RegisterClientScriptInclude("MyKey", "~/js/script.js");
}
There are a couple of ways to accomplish what you are looking for.
1- put a content place holder in the section of your master page
<head runat="server">
<asp:ContentPlaceHolder runat="server" ID="JavascriptPlaceHolder">
</asp:ContentPlaceHolder>
</head>
and in the specific page you want to add a javascript file add:
<asp:Content ID="Content2" ContentPlaceHolderID="JavascriptPlaceHolder" Runat="Server">
<script type="text/javascript" src="myfile.js" ></script>
</asp:Content>
2- When you are not using Update Panels, use the ClientScript:
Page.ClientScript.RegisterClientScriptInclude("MyKey", "/myfile.js");
3- When using Update Panel and partial page rendering, use the ScriptManager object to register your javascript: (For a script that should be available for the onload event or at least be available when an update panel refreshes)
string javascript_string = "function myAlert(){ alert('me'); }";
ScriptManager.RegisterStartupScript(this, typeof(string), "MyKey", javascript_string, false);
Use the content place holder where you can, then use either other technique when you can't.
How to embed javascript into a content page?

Resources