Single javascript function for multiple web pages - asp.net

I have around 40 aspx pages in my website.
I want to use a javascript function which needs to be called when any of the 40 pages is loaded.
something like
I could have this function in the "head" section of each of the 40 aspx pages and then call in the body onload event. But I would like to have this function at a single place.
This is an existing app so I cannot create a master page and have all the pages derive from it.
Any ideas?

You will need to put the function in a .js file and call from your pages, but you will need to link to the script in all your 40 pages, since you can't add master page.

You can create a base class that it will be inherited by all these pages and write the logic of inserting javascript there.
So, do something like it:
Create a base class:
[Serializable]
public class RequiresFunctionBasePage : System.Web.UI.Page
{
public RequiresFunctionBasePage()
{
this.Load+= new delegate
{
this.ClientScript.RegisterClientScriptInclude("yourScript", "http://yoursite.com/yourJs.js");
this.ClientScript.RegisterStartupScript(this.GetType(),
"functionOnload", "functionName();", true);
}
}
}
And into your aspx codebehind:
public partial class yourPageNameGoesHere : RequiresFunctionBasePage
{
(...)

I suppose if you wanted to make it difficult/elegant, you could make an HttpModule that injects the script. That way it's only in one place and you can wire it up in the web.config.
Here's a sample httpModule
Public Class JavascriptInjector
Implements IHttpModule
Public Sub Init(ByVal context As System.Web.HttpApplication) Implements System.Web.IHttpModule.Init
AddHandler context.PreRequestHandlerExecute, AddressOf PreRequestHandlerExecute
End Sub
Private Sub PreRequestHandlerExecute(ByVal sender As Object, ByVal e As EventArgs)
Dim myPage = TryCast(HttpContext.Current.CurrentHandler, Page)
If myPage Is Nothing Then Exit Sub
AddHandler myPage.InitComplete, AddressOf Page_Init
End Sub
Sub Page_Init()
Dim myPage = TryCast(HttpContext.Current.CurrentHandler, Page)
If myPage Is Nothing Then Exit Sub
Dim path = myPage.ResolveUrl("~/js/jscript.js")
myPage.ClientScript.RegisterClientScriptInclude(myPage.GetType, "common", path)
End Sub
Public Sub Dispose() Implements System.Web.IHttpModule.Dispose
End Sub
End Class
Here's an entry in the web.config
<httpModules>
<add name="javascriptInjector" type="JavascriptInjector"/>
</httpModules>

You will need to modify the masterpage to include a new JS file with your new function or place your JS function in one of the JS files already included in the masterpage.

For a fully client side solution you could create a javascript file (possibly named script.js) that you link to from the head of your master page. In that file put your function.
So, the javascript in the script.js file would be something like this:
function SampleFunction(text) {
alert(text);
// or whatever code you want
}
and then in the head of your pages
<script type="text/javascript" src="script.js"></script>
and then your onload can be
onload="SampleFunction('hi there');"
have fun :)
robb

Related

How to use class code of vb.net in asp.net

I'm having trouble with using my vb.net code in asp.net webpage.
<%# Page Language="vb" AutoEventWireup="false" MasterPageFile="~/Site.Master" CodeBehind="WebForm1.aspx.vb" Inherits="Banking_Application.WebForm1" CodeFile="~/WebForm1.aspx.vb" %>
class name is WebForm1. I've written code in a separate file and I want to use it in page.
Like
<% Dim total As Integer
Dim val As tests.WebForm1
val = New tests.WebForm1
total = val.TotalBranches()
total.ToString()
%>
I'm new to vb.net and asp.net.
All suggestions are welcome.
Thanks!
Well first of all i need to clarify a few things for you:
in Asp.net, you can embed code in your aspx page using <% %> code block, or write it in a separate file and use it from there.
in your page declaration, you specify the code behind of your page using the CodeBehind= attribute, so if you want to place your code in WebForm1.vb, your page declaration should include CodeBehind="WebForm1.vb" .
note: CodeFile="~/WebForm1.aspx.vb" is not needed.
the structure of the code behind for you aspx page, should look like that:
Public Class WebForm1
Inherits System.Web.UI.Page
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
End Sub
Public Function test1()
Return "test"
End Function
End Class
and you can add more functions as needed. in the example above, i have added a function called test1 for the purpose of this example.
now, after you have created your code behind in the correct structure, you can call its methods from the aspx page as if it was the same page:
<% =test1()
%>
this will return "test" as specified by the function in code behind.
you do not need to instantiate the class.
I think you are missing what is happening with the mechanics of asp.net.
You either:
Write code directly in the aspx page (within the html)
Or, you wrtie code in the code behind page... your WebForm1.aspx.vb page. From the code behind page, you can access and manipulate the server controls that is on the aspx (html) side...

Why can't I add a control the page's header from the an inline ASPX code nugget?

Why can't I add a control the page's header from the an inline ASPX code nugget? It works from the code behind.
The markup just doesn't get added to the page.
Is it the page life cycle?
In aspx page:
<%
StyleSheet.AddToHeader(Page, New List(Of String)({
"~/CSS/bootstrap.min.css",
"~/CSS/skin.css"
}))
%>
Imports Microsoft.VisualBasic
Imports System.Web.UI
Public Class StyleSheet
Public Shared Sub AddToHeader(ByRef currentPage As Page, ByVal pathList As List(Of String))
For Each singlePath In pathList
Dim lineBreak As New Literal()
Dim stylesheet As New HtmlLink()
lineBreak.Text = Environment.NewLine
stylesheet.Attributes.Add("rel", "stylesheet")
stylesheet.Attributes.Add("type", "text/css")
stylesheet.Href = currentPage.ResolveUrl(singlePath)
currentPage.Header.Controls.Add(lineBreak)
currentPage.Header.Controls.Add(stylesheet)
Next
End Sub
End Class
The code that is executed inline (inside <% and %> ) is done while it is streaming to the client computer.
You cannot do that and expect the header to be updated because you are altering the object AFTER it has performed it's "RenderControl" internal routine.
Most code behind happens before the rendering takes place which is why you can do it behind the scenes without issue.

How to use Asp.NET Custom WebControl in Source-View

I created a Label control inheriting from Label WebControl in CustomLabel.vb in my project where I want to use it. And I would like to use the code below in source-view as such:
<custom:SettingLabel ID="lblHelloWorld" runat="server"/>
How can I do that without creating a WebContolLibrary and using it as reference?
Namespace InternetLending.Controls
Public Class SettingLabel
Inherits Label
Protected msDefaultText As String
Protected moConfigXML As New ConfigXMLParser()
Public Overridable Property DefaultText() As String
Get
Return Me.msDefaultText
End Get
Set(ByVal vsValue As String)
Me.msDefaultText = vsValue
End Set
End Property
Protected Overrides Sub OnLoad(ByVal e As System.EventArgs)
MyBase.OnLoad(e)
If Not String.IsNullOrEmpty(Me.moConfigXML.GetLabelTextByID(Me.ID)) Then
Me.Text = Me.moConfigXML.GetLabelTextByID(Me.ID)
Else
Me.Text = Me.DefaultText
End If
End Sub
End Class
End Namespace
You just need to add this to the top of your page. You don't need to make a separate library or anything.
<%# Register Assembly="Assembly" Namespace="Assembly.Controls" TagPrefix="custom" %>
The problem here is that you are not taking into account the default namespace.
Try using the following directive:
<%# Register Assembly="InternetLending" Namespace="InternetLending.InternetLending.Controls" TagPrefix="custom" %>
Or change your Namespace for the SettingLabel control like so:
Namespace Controls
Public Class SettingLabel
Inherits Label
and then use the following directive:
<%# Register Assembly="InternetLending" Namespace="InternetLending.Controls" TagPrefix="custom" %>
See: Managing Namespaces in VB.Net for more info.
I think you can just register the assembly in the web.config or page directive, even if it's in the same project.
<add tagPrefix="MyControls" namespace="MyProgram.Controls.MyControl" assembly="MyProgram.Controls.MyControl" tagName="MyControl" />

Adding to page control collection from inside a user control

I have an asp.net usercontrol which represents a "popup" dialog. Basically, it's a wrapper for the jQuery UI dialog which can be subclassed to easily make dialogs.
As part of this control, I need to inject a div into the page the control is used on, either at the very top or very bottom of the form so that when the popup is instantiated, it's parent is changed to this div. This allows "nested" popups without the child popup being trapped inside the parent popup.
The trouble is, I can't find a safe way to inject this div into the page. A usercontrol doesn't have a preinit event, so I can't do it there, and calling Page.Form.Controls.Add(...) in Init, Load or PreRender causes the standard exception "The control collection cannot be modified during DataBind, Init, Load, PreRender or Unload phases."
I thought I had found a solution by using...
ScriptManager.RegisterClientScriptBlock(Page, Me.GetType, UniqueID + "_Dialog_Div", containerDiv, False)
... which seemed to work well normally, but recently a coworker tried putting an UpdatePanel inside the dialog and now she's getting the error "The script tag registered for type 'ASP.controls_order_viewzips_ascx' and key 'ctl00$ContentBody$OViewZips_Dialog_Div' has invalid characters outside of the script tags: . Only properly formatted script tags can be registered."
How are you supposed to add controls to the pages control collection from inside a user control?
I'm not sure why you really need to add this div to the page's form, but this should work:
Public Class WebUserControl1
Inherits System.Web.UI.UserControl
Private Sub UC_Init(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Init
AddHandler Me.Page.Init, AddressOf Me.Page_Init
End Sub
Private Sub Page_Init(ByVal sender As Object, ByVal e As EventArgs)
Dim dialogDiv As New Panel
dialogDiv.ID = "DialogDiv"
If Not Page.Form.Controls.Contains(dialogDiv) Then
Page.Form.Controls.AddAt(0, dialogDiv)
End If
End Sub
End Class
How to implement it in C#. I'm always getting the error The control
collection cannot be modified on Load, PreRender
I need a Literal Control to be added to my master page's head from a user control. The literal control will contain the css link.
Do you want to add the literal to the HeadContent-ContentPlaceHolder control in the master or to the page's header(the html head element)? However, here i show both.
Here's the codebehind of your UserControl:
public partial class UC_AddToMaster : System.Web.UI.UserControl
{
private void Page_Init(object sender, System.EventArgs e)
{
this.Page.Init += UC_AddToMaster_Init;
}
private void UC_AddToMaster_Init(object sender, EventArgs e)
{
Literal literal = new Literal{ Text = "Hi World!" };
// if you want to add it to the header of the page:
if (!Page.Header.Controls.Contains(literal))
{
Page.Header.Controls.AddAt(0, literal);
}
// if you want to add it to the master's HeadContent ContentPlaceHolder control:
var siteMaster = Page.Master as SiteMaster;
if (siteMaster != null)
{
if (!siteMaster.Head.Controls.Contains(literal))
{
siteMaster.Head.Controls.AddAt(0, literal);
}
}
}
}
For the HeadContent approach mentioned above i've provided following property in the master:
// in the master
public ContentPlaceHolder Head { get { return this.HeadContent; } }
Therefore i needed to cast the page's master to it's actual type(SiteMaster here) in the UserControl. Otherwise i couldn't access this property.
Usercontrol doesn't have a PreInit event, but nothing's stopping you from adding a handler to the Page PreInit event in your UserControl:
Page.PreInit += new EventHandler(Page_PreInit);
edit - you're right - you can't capture PreInit from a usercontrol, though I'm surprised you can't - but you can still change the page controls collection by adding code to the constructor of the UserControl. I tried this and it works.
public MyUsercontrol()
{
Page page = (Page)HttpContext.Current.Handler;
Literal lit = new Literal();
lit.Text="text";
page.Controls.Add(lit);
}
Adding an event handler to Page.PreInit in the constructor compiles but it never fires.
(end edit)
That said, I'm not exactly sure why this is necessary to achieve your goal. Why don't you just have your dialog control render it's own div in-line wherever you drop it into the form, and use that as the parent, instead of trying to create one somewhere else in the form? I can't think of why it would be important for it to physically be rendered at the beginning or end of the form. It's a dialog so it will always be invisible until you use it, right?

Using aspx controls in base class

I've got two aspx pages which are very similar and have various identical functions in the code behind. I'd like to create a base class which both the code behind classes derive from. Is it possible for the base class to access the controls on the aspx page. For instance:
class base
inherits System.Web.UI.Page
Sub prepareScreen()
'txtName is a text box on the aspx page
Me.txtName.text = "George"
end sub
end class
class codeBehind
inherits base
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
prepareScreen()
end sub
end class
Somewhat understandably the code fails to compile with:
'txtName' is not a member of 'clsbase'
Is it possible to link the two together?
You need to declare the control as a property of the base class. Then in the ASP markup, use the CodeFileBaseClass attribute.
The MSDN reference is no longer available.
class base
inherits System.Web.UI.Page
Protected Property txtName() As TextBox
Sub prepareScreen()
'txtName is a text box on the aspx page
Me.txtName.text = "George"
end sub
end class
class codeBehind
inherits base
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
prepareScreen()
end sub
end class
<%# page CodeFileBaseClass="base" inherits="codebehind" ... %>
It would be better if you refactor your code, so that you have no need to do something like this.
One better idea will be if you create a virtual method in the base class, which you can override in your child page(s), and set the value of your textbox, as you'll have an easy access to the textbox.
You could use FindControl, eg.
TextBox txtName=FindControl("txtName");
which would find the control on the rendered page even though it was rendered by the descendant class. Though this is breaking the point of OO and separation of function/data somewhat.
You can use ((TextBox)Page.FindControl("txtName")) to get the textbox. Be careful because if you use this base class else where the control might not exist
In response to your clarification:
You could Create a property:
protected TextBox txtName
{
get{return (TextBox)Page.FindControl("txtName");}
set{Page.FindControl("txtName") = vale;}
}
Or Create a Virtual property:
protected virtual TextBox txtName{get;set;}
In this case you would have to override it at your main class
protected override TextBox txtName{/*same as above*/}

Resources