Introduction to client-side scripting

Use this general information to guide you when you write client-side scripts for the portal.

Local variables

Unlike server script, which does not allow you to save data locally in the script, you can do this with client scripting. With server-side scripting, you can save variables to only SessionVariables, LayoutVariables or the data stores. The scripts themselves are stateless. With client-side scripting, if you declare a variable outside of any function, it will retain any value you give it and can be accessed the next time an event handler is called.

This is also true of client-side global scripts, which are discussed in Client-side global scripts.

Registering event handlers

At the top of each template is a method called OnScriptInitializing. This method is used to register handlers for the various event handlers in the script when the layout is being initialized for the first time.

Event handlers can be registered and unregistered as necessary in other event handlers as well.

For example, if you want some custom script to be executed when a button is clicked, you could define a method:


function OnClick(context, parms) {
    /// <param name="context" type="GridClickContextI"></param>
    /// <param name="parms" type="GridClickParmsI"></param>
    ...Your custom code here......
}

To be executed, you must associate the method with the event. Add this line to the OnScriptInitializing method:

context.Handlers.RegisterClickHandler(OnClick)

Once registered, the method will be called at the appropriate time.

The Handlers object contains methods to register handlers for every possible event.

Event handlers associated with named regions are registered in a slightly different way. Instead of there being a single handler for each event type, you must register a separate handler for each region. Visible regions are always eligible for events, but the layout might not need to do anything in most cases. Therefore, for efficiency, set up in the architecture is avoided when an event handler is not registered for a particular region.

For example, if you want some custom script to be executed when the mouse enters a region, you could define a method like this:


function OnMouseIn(context, parms) {
    /// <param name="context" type="GridRegionalMouseInContextI"></param>
    /// <param name="parms" type="GridRegionalMouseInParmsI"></param>
 ...Your custom code here...
}

To be executed, you must associate the method with the event. Add this line to the OnScriptInitializing method:

context.Handlers.RegisterRegionalMouseInHandler(OnMouseIn, regionName)

This way, you can have a separate handler for each region.

However, when the handler is called, the parms will contain the region's name and the record it is associated with, if applicable. Therefore, you can still have a single handler for each event type if desired. Simply register the same handler repeatedly for each region. In that case, you can look at the region's name in the parms to determine which region generated the event.

Unregistering event handlers

There can be only one handler registered at a time for each event or event/region combination. If a new handler is registered, the old handler will no longer be invoked. When a handler is no longer necessary and a replacement handler is also unnecessary, the handler can simply be unregistered.

For example:

context.Handlers.UnregisterClickHandler()

context.Handlers.UnregisterRegionalHoverHandler("region")

Changing data

When a client-side API is used to change data, the client-side API to get the data will not reflect the changed value until the change has taken effect in the architecture.

Event bubbling

Be aware that events do not bubble up. Only the inner-most component or region that has an event handler registered will receive the event. For example, if you have a regional click handler registered AND a component in that region is clickable, when the user clicks on the component, only the component will get the event. This is true for all events, including mouse move, etc.

If the inner component that captured the event has its own independent scripting, it could alert its parent. If it does not, there is currently no way for the parent to know that anything happened.

Invoking event handlers

Generally, all event handlers take two parameters. The first gives access to the context of the event and the second gives the specific parameters for the event in question.

For example, in the click handler case above, the first parameter, context, is a GridClickContextI. It contains general APIs that may be needed, such as error logging, access to data, the UI, etc. The second parameter, parms, is a GridClickParmsI. It contains APIs specific to the event that just occurred. In this case, a component was just clicked. Therefore, information about the particular component that was clicked will be available here.

IntelliSense is to be used to find the particular APIs available in any given scenario and to see the documentation for those APIs.

For IntelliSense to work in JavaScript, Microsoft Visual Studio requires some special comments to be present in the code. They look like this:

/// <reference path="interface library" />

and

/// <param name="the parameter name" type="the parameter type"></param>

They have been set up for you in the script template. It is important not to remove these lines. If you do, IntelliSense will not be able to assist you in selecting the correct APIs.

If there is a server-side handler registered for an event, and you also register a client-side event handler, the client-side handler will run first and then the server-side handler will run. If the client-side handler decides that the server-side portion does not need to run, it can stop the handler from running with:

parms.StopServerSideHandler(true)

This must be run every time the client-side handler runs to stop the server-side handler from also running. To help you remember to call this API when a round trip to the server is unnecessary (for performance), this line is in the client-side handler template as a commented-out line.

The architecture knows whether or not there is a server-side handler registered. If one has not been registered, a round trip will not be made to the server even if StopServerSideHandler() has not been called.