Your first APL Web Page

The first web page example is tutorial/intro1.aspx, which is listed below. This page displays a button whose text is reversed each time you press it.

Note that the example is intended to be run in the framework of the tutorial and contains two lines of code (shown in italic) that refer to this framework and should be ignored.

<%@Register TagPrefix="tutorial" Namespace="Tutorial" Assembly="tutorial" %>
<script language="Dyalog" runat="server">

Reverse args
:Access public
:Signature Reverse Object,EventArgs
(args).Text(args).Text


</script>

<html>
<body>
<Form runat=server>
      <asp:Button id="Pressme" 
      Text="Press Me"
      runat="server"
      OnClick="Reverse" 
      />
</form>
<tutorial:index runat="server"/>
</body>
</html>

In this example, the page language is defined in the <script> section to be "Dyalog". This in turn is mapped to the APLScript compiler via information in the application's web.config file or the global IIS configuration file, machine.config.

The page layout is described in the section between the <html> and </html> tags. This page contains a Form in which there is a Button labelled (initially) "Press Me"

The Form and Button page elements may appear to be simple HTML, but in fact there is more to them than meets the eye and they are actually both types of ASP.NET intrinsic controls.

Firstly, the runat="server" attribute indicates that an HTML element should be parsed and treated as an HTML server control. Instead of being handled as pure text that is to be transmitted to the browser "as is", an HTML server control is effectively compiled into statements that then generate HTML when executed. Furthermore, an HTML server control can be accessed programmatically by code in the Script, whereas a pure HTML element cannot. On its own, runat="server" identifies the HTML element as a so-called basic intrinsic control.

When you add runat="server" to a Form, ASP.NET automatically adds other attributes that cause the values of its controls to be POSTed back to the same page. In addition, ASP.NET adds a HIDDEN control to the form and stores state information in it. This means that when the page is reloaded into the browser the state and contents of some or all of its controls can be maintained, without the need for you to write additional code.

The asp: prefix for the Button, identifies the control as a special ASP.NET intrinsic control. These are fully-fledged .NET Classes in the .NET Namespace System.Web.UI.WebControls that expose properties corresponding to the standard attributes that are available for the equivalent HTML element. You manipulate the control as an object, while it, at runtime, emits HTML that is inserted into the page.

At this point, it is instructive to study what happens when the page is first loaded and the appearance of the page is illustrated below.

intro1_1
Figure 1: intro1_1

The HTML that is transmitted to the browser is:

<html>
<body>
    <form name="ctrl1" method="post" action="intro1.aspx" id="ctrl1">
<input type="hidden" name="__VIEWSTATE"
value="YTB6NTQ3ODg0MjcyX19feA==5725bd57" />

        <input type="submit" name="Pressme" value="Press Me"
id="Pressme" />
    </form>
</body>
</html>

Firstly, notice that, as expected, the contents of the <script> section are not present. Secondly, because the Form and Button are intrinsic controls, ASP.NET has added certain attributes to the HTML that were not specified in the source code.

The Button now has the added attribute input type="submit", which means that pressing the Button causes the contents of the Form to be transmitted back to the sever.

The Form now has method="post" and action="intro1.aspx" attributes, which means that, when the Form is submitted, the data is POSTed back to intro1.aspx, the page that generated the HTML in the first place.

So when the user presses the button, the browser sends back a POST statement, with the contents of the Form, including the value of the HIDDEN field, requesting the browser to load intro1.aspx.

In the server, ASP.NET reloads the page and processes it again. In fact, because of the stateless nature of HTTP, the server does not know that it is reprocessing the same page, except that it is being executed by a POST command with the hidden data embedded in the Form that it put there the first time around. This is the mechanism by which ASP.NET remembers the state of a page from one invocation to another.

This time, because a POST back is loading the page, and because the Pressme button caused the POST, ASP.NET executes the function associated with its onClick attribute, namely the APLScript function Reverse.

When it is called, the argument supplied to Reverse contains two items. The first of these is an object that represents the control that generated the onClick event; the second is an object that represents the event itself. In fact, Reverse and its argument are very similar to a standard Dyalog callback function.

Reverse args
:Access public
:Signature Reverse Object,EventArgs
(args).Text(args).Text

The code in the Reverse function is simple. The expression (⊃args) is a namespace reference (ref) to the Button, and (⊃args).Text refers to its Text property whose value is reversed. Note that Reverse could just as easily refer to the Button by name, and use Pressme.Text instead.

After pressing the button, the page is redisplayed as shown below:

intro1_2
Figure 2: intro1_2

This time, the HTML generated by intro1.aspx is:

<html>
<body>
    <form name="ctrl1" method="post" action="intro1.aspx" id="ctrl1">
<input type="hidden" name="__VIEWSTATE"
value="YTB6NTQ3ODg0MjcyX2Ewel9oejV6MXhfYTB6X2h6NXoxeF9hMHph
MHpoelRlXHh0X2VNIHNzZXJQeF9feF9feHhfeHhfeF9feA==45acf576"
/>

        <input type="submit" name="Pressme" value="eM sserP"
id="Pressme" />
    </form>
</body>
</html>

Returning to the Reverse function, note that the declaration statements at the top of the function are essential to make it callable in this context.

Reverse args
:Access public
:Signature Reverse Object,EventArgs
(args).Text(args).Text

Firstly the Reverse function must be declared as a public member of the script. This is achieved with the statement.

:Access Public

Secondly, the .NET runtime will only call the function if it possesses the correct signature, which is derived from its parameters and their types.

The required signature for a method connected to an event, such as the OnClick event of a Button, is that it takes two parameters; the first of which is of type System.Object and the second is of type System.EventArgs. The Reverse function declares its parameters with the statements:

:Signature Reverse Object,EventArgs

Note that the parameter declarations do not include the System prefix. This is because when the script is compiled the names are resolved using the current value of ⎕USING. When the APLScript is compiled, the default value for ⎕USING is automatically defined to contain System along with most of the other namespaces that will be used when writing web pages

(Strictly speaking, the first argument is expected to be of type System.Web.UI.WebControls.Button, but as this type inherits ultimately from System.Object the function signature is satisfied.)

Note that if the Reverse function is defined with a signature that does not match that expected signature for the OnClick callback, the function will not be run.

Furthermore, if the function associated with the OnClick statement is not defined as a public method in the APLScript the page will appear to compile but the Reverse function will not get executed.

Note that unlike Web Services, there is no requirement for a :Class or :EndClass statement in the script. This is because a file with an .aspx extension implicitly generates a class that inherits from System.Web.UI.Page.