Header Manipulation in the Web Control Framework
September 21, 2008 •
A question that comes up frequently on the forums is how to access and set the header in a Web Connection Web Control page. For example, how can you set the title dynamically from code in a simple layout like this:
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server" id="Header">
<title></title>
<link href="westwind.css" rel="stylesheet" type="text/css" />
</head>
The problem is that in the WCF the header is not an object so you can’t you can’t directly access the title as a property in any way. One really easy way to add dynamic functionality to the header is to add an eval expression to the header:
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server" id="Header">
<title><%= this.Page.PageTitle %></title>
<link href="westwind.css" rel="stylesheet" type="text/css" />
</head>
To make this work you’ll need to add a property to the page first. Once you’ve added the property you can set in code and assign whatever value suits you:
*****************************************************************
DEFINE CLASS AjaxMethodCallback_Page as WWC_WEBPAGE OF WWC_WEBPAGE_FILE
*****************************************************************
*** Your Implementation Page Class - put your code here
*** This class acts as base class to the generated page below
*****************************************************************
#IF .F.
*** This line provides Intellisense: Ensure your path includes this page's location
LOCAL this as AjaxMethodCallback_Page_WCSX of ajaxmethodcallback_page.prg
#ENDIF
PageTitle = "Hello World"
*****************************************************************
* OnLoad
****************************************
FUNCTION OnLoad()
this.PageTitle = "Hello" + Process.User.Username + ". " + TIME()
ENDFUNC
* Onload
The property is created to have somewhere to store the value that can then be assigned. When the page is rendered the eval expression picks up the title and renders it.
You can use a similar approach for anything else you want to embed. If you want to embed script at the top or bottom you might create a placeholder string that holds that literal content.
Header Manipulation – adding content to the header
In the next release of Web Connection there will be a new wwWebHead control that maps the header object to a control. This provides a little more control over header output by giving you the ability to write out header content directly through code. You can write content at the top or bottom of the header using literal strings or controls.
For example, if you wanted inject a script tag into the page in the header you could use:
this.Page.Header.AddControlAtTop([<script src="scripts/jquery.js" type="text/javascript"></script>])
AddControlAtTop injects at the very top of the Header. AddControl() injects at the bottom – this allows a little bit of control over placement that often is necessary especially when injecting things like script tags or css styles that have to respect a certain order.
Script Manipulation from Code
The main reason this change was made now is precisely because of the additional control it affords for script placement. The next major update to Web Connection will integrate more tightly with jQuery and also use a custom utility library. This update will replace the existing Ajax controls and the wwScriptLibrary with a jQuery based equivalent version.
Since jQuery is often used in combination with other plug-ins and libraries placement of the jQuery library is crucial – specifically it should be loaded before any plug-ins or utilities, so that if any manually added plug-ins run after jQuery is loaded. The new header options allow for this precise placement necessary so that the auto-loaded (optional) jQuery script can co-exist properly with any plug-ins that might also be used in combination.
Please note that as before – it’s completely possible to turn off the auto loading of any script libraries on each of the controls that use them. The default auto loads, but you can clear out the the script location to for any resource or explicitly point it at your own locations instead of using the defaults. The goal isn’t to limit you and force you to use a packaged version, but to make using components as easy as possible without requiring any additional setup.