Web Application Flow

Web Properties Methods and Events

Positioning and Layout of Controls

 

A Web Application works differently than the more traditional desktop application. It is very important to understand that the client (your browser) does not own a single instance of a WebApp (WebApp.exe). There is no persistent connection between the browser and server application. Instead, you have a pool of WebApp processes waiting to be used. When a client needs to use one of these processes, it connects to it, it initializes the process and synchronizes it with the data from the client, it works with the process to handle whatever requests are needed and then it disconnects from the process. This process is returned to the application pool where it waits for another client request.

 

Starting an Application Process

When your Web Application starts a number of WebApp.exe processes are loaded and initialized. The number of processes created depends on your process pooling settings (and you do want to use process pooling).  This startup creates all of your objects, sets all of your properties and is then added the process pool.

Here are some things to remember about this initialization process:

 

Starting a Web Application in your Browser

The URL you enter from your browser loads a fairly simple page (e.g.,  http://MySite/MyApplication/Index.html). This page contains the JavaScript classes needed to run the application. It also implements an AJAX style request handler. From this point on, your web page is never reloaded and all communication occur via AJAX style requests. These requests do all the work. They allow you to create a new browser session, display your main application, load views and dialogs, and interact with those views and dialogs.

WebApp Client to Server Requests

This request process occurs through web-service calls. The data is passed and returned in JSON format. This response/request cycle is sometime referred to making a “round trip to the server”. You can actually view each request in a browser’s debugger. If you are using FireFox and you have downloaded the Firebug debugger, you can activate the debugger and view the “console”, which lets you see each request/response.

These requests can be used for all kinds of purposes but some the standard requests are:

Before discussing these individual request actions, we will discuss what is common for all of these requests:

Most requests are sent to a view or a dialog and they look like this:

 

Of Note:

OnSyncWebApp is sent to your main cWebApp object. This can be used to handle any special customizations based on the web properties. This can be used to handle any special user rights considerations. This is sent before the view has been synchronized.

If a view’s AllowAccess returns False the request is canceled. This is security feature.

OnSyncView is sent to each view and dialog used in this request. This can be used to handle any special customizations based on the web properties. This can be used to handle any special user rights considerations. This is also used to define any custom dynamic constraints in your view’s DDO structure. Typically this involves defining your DDO OnConstrain methods based on values of web-properties.

After OnSyncView is called, Rebuild_Constraints is sent to your DDO structure. Therefore if constraint customizations occur you do not need to manually rebuild constraints.

The “process all request actions” step may be the calling of actions such as loading a view or hiding a view. These actions may cause other events to fire. A request action may also trigger an event directly (e.g. OnClick).

Normally you constraints can be customized as part of the rebuild_constraints process. This will call any custom code within your DDO OnConstrain events, which is usually all you need. If you change your constraints anywhere else, such within OnSyncView you will need to remember to send Rebuild_Constraints to your DDOs.

You should test the value returned by AppSynching inside any data dictionary events you implement that could be triggered during a find operation (e.g. OnPostFind, Refresh, OnNewCurrentRecord). The AppSynching function returns true while the framework is synchronizing web properties and the view's DDO structure, and returns false while processing all request actions. Normally you do not want to process DDO events when AppSynching returns true.

 

Action  – Loading a WebApp

This first time a client requests a WebApp, the WebApp itself must be loaded onto the client. Here is an outline of what happens:

 

Of Note:

OnChangeRights is sent during this load. This event will also be sent when a users right’s change – typically after a login. This is sent to every menu object and, based on user rights, can be used to enable or hide items, toolbars, menus or even the entire commandbar system.

OnLoad is sent when a web-object is loaded. This is sent for every web-object. It is usually only sent once during a session.

 

Action – Loading a View or a Dialog

The first time a view or dialog is requested the view’s object definition must be serialized and sent to the client. The client will use this information to show these controls on the browser. Once loaded, the client can hide and reshow these views without needing to request these definitions again.

Often when displaying a view, an existing view will be hidden and the new view will be displayed. In the case of modal dialogs a new dialog will be loaded on top of the old view or on top of another. In both cases, the old view and the new view or dialog must both be fully synchronized.  Here is an outline of what happens

 

Of Note:

If a view’s AllowAccess returns False the request is canceled. This is security feature.

OnHide is sent if the old view’s pbServerOnHide is True

OnShow is sent if the new view’s pbServerOnShow is True

OnLoad is sent when a web-object is loaded. This is sent for every web-object. It is usually only sent once during a session.

If there was on old view, that view will have already been synchronized as part of the regular request synchronization process.

 

Action – Showing a view or dialog that has already been loaded

 

Of Note:

OnHide is sent if the old view’s pbServerOnHide is True

OnShow is sent if the new view’s pbServerOnShow is True

If these views are already loaded both the old and new views will have already been synchronized as part of the regular request synchronization process

If pbServerOnHide and pbServerOnShow are false for their respective objects, there may be no server request at all.

 

Important Events

 

OnLoad

This is sent to every web-object when the object is loaded. If a view or dialog or WebApp has not yet been requested its object definition and every web object it contains must be serialized and sent to the client, where the client can display it. OnLoad is sent to each object as it is serialized. This load process usually only occurs once per session.

OnLoad is sent unconditionally – there is no pbServerOnLoad.

This is a good event to augment at the view level when you want to view to appear with a default record.

    Procedure OnLoad

        Send Find of OrderHea_DD FIRST_RECORD Index.1

    End_Procedure

 

This can also be useful to handle first time processing when loading a WebApp. For example you could augment OnLoad in your cWebApp object to perform an automatic login.

    Procedure OnLoad

        Boolean bOk

        Get UserLogin of ghoWebSessionManager "guest" "Guest" to bOk

    End_Procedure

 

OnShow

OnShow is sent to a view or dialog when it is being shown. This is sent when the view is first loaded and each time it is re-displayed. OnShow is only called if pbServerOnShow is True.

OnShow is useful with Modal Dialogs, which often require that you perform initializations each time the dialog is shown.

OnHide

OnHide is sent to a view or dialog when it is being hiddren. This is sent when another view is shown or when a Modal Dialog is closed. OnHide is only called if pbServerOnHide is True.

OnChangeRights

OnChangeRights is sent whenever there is a change in user rights. It is sent to the cWebApp object, the command bar object and all objects within the command bar.

When rights change, OnChangeRights is not sent to views. It is expected that you will use OnSyncView to handle any special view roles and rights requirements.

OnSyncWebApp

OnSyncWebApp is sent to the cWebApp object with each request. It is sent after the web-properties have all been synchronized but before any view DDOs have been synchronized. This can be used for special global initializations and is useful for setting any special rights or roles.

OnSyncView

OnSyncView is sent to each view that needs to be synchronized during a request. It is sent after the web-properties, DDOs and DEOs are synchronized.

This is an important event. You can use this to control user rights and to disable or hide controls within a view as needed. Remember to use WebGet and WebSet for this.

You can also use this to initialize custom constraints. If you change constraints you must remember to send Rebuild_Constraints to the DDO.

Here are two ways you might customize DDO constraints. This first method uses OnSyncView to WebGet three web-properties and to set these to regular DDO properties. When Rebuild_Constraints gets called, OnConstrain will be applied and the filter will be in place:

Object oCustomerGrid is a cWebView

    

    { WebProperty = True }

    Property String psFilter ""

    { WebProperty = True }

    Property String psFilterFrom ""

    { WebProperty = True }

    Property String psFilterTo ""

 

    Procedure OnSyncView

        String sFilter sFrom sTo

        WebGet psFilter of oCustomerGrid to sFilter

        WebGet psFilterFrom of oCustomerGrid to sFrom

        WebGet psFilterTo of oCustomerGrid to sTo

        Set psType of oCustomer_DD to sFilter

        Set psFrom of oCustomer_DD to sFrom

        Set psTo of oCustomer_DD to sTo

        Send Rebuild_Constraints of oCustomer_DD

    End_Procedure

 

    Object oCustomer_DD is a Customer_DataDictionary

        

        Property String psType

        Property String psFrom

        Property String psTo

        Procedure OnConstrain

            String sFilter sFrom sTo

            Forward Send OnConstrain

            

            Get psType to sFilter

            Get psFrom to sFrom

            Get psTo to sTo

            

            If (sFilter = "NUMBER") Begin

                Constrain Customer.Customer_Number Between sFrom and sTo

            End

            

            If (sFilter = "NAME") Begin

                Constrain Customer.Name Between sFrom and sTo

            End

            

        End_Procedure

        

    End_Object

 

...

 

This next method does this same thing just using web-properties. In this case there is no OnSyncView, because OnConstrain use web-properties and WebGet directly. Even with no OnSycView augmentation, Rebuild_Constraints will send OnConstrain, which will do the work for you.

Object oCustomerGrid is a cWebView

    

    { WebProperty = True }

    Property String psFilter ""

    { WebProperty = True }

    Property String psFilterFrom ""

    { WebProperty = True }

    Property String psFilterTo ""

    

    Object oCustomer_DD is a Customer_DataDictionary

        Procedure OnConstrain

            String sFilter sFrom sTo

            Forward Send OnConstrain

            

            WebGet psFilter of oCustomerGrid to sFilter

            WebGet psFilterFrom of oCustomerGrid to sFrom

            WebGet psFilterTo of oCustomerGrid to sTo

            

            If (sFilter = "NUMBER") Begin

                Constrain Customer.Customer_Number Between sFrom and sTo

            End

            

            If (sFilter = "NAME") Begin

                Constrain Customer.Name Between sFrom and sTo

            End

            

        End_Procedure

        

    End_Object

 

...

 

Previous Topic: Web Properties Methods and Events

Next Topic: Positioning and Layout of Controls

 

See Also

Developing Web Applications