Box subscriptions implements the Observer pattern in Axional Studio Forms. This allows that a certain box in a form reacts in front of an event in the Form. This event can be a transaction in other box, or a selection of records, etc. Basically, when one of those events are fired, the observer box reloads its content.

1 Introduction

1.1 What is it?

Box subscription is the Axional functionality for related a Related box with one or more Related box.

Therefore, a Related box can have three ways:

  • Independent: Content is independent of external data.
  • Dependent on adapter: Use adapter variables to load content.
  • Dependent on one or more related box: Use subscription to load content.

1.2 What can I do?

With Box subscription , a Related box may show his content depending on the state of one or more related box. The possibilities are numerous. Some examples are the following:

  • SQL table box show data selected on other SQL table.
  • SQL table box show data selected on diferents SQL table.
  • SQL table box show data selected on the last SQL table selected.
  • SQL Maps show data depending one row select on SQL tree.
  • SQL JSOBJ show data depending one row clicked on SQL tree.

1.3 What do I need?

Box subscription requires the basic Axional Studio infrastructure, which includes:

  • Axional Studio Server, properly set up.
  • Dictionary database
  • A target database
The previous configuration is explained in detail under the Axional Studio/Setup block.

2 Architecture

2.1 How work it?

The aim of this section is understanding how subscription work. Firstly, it's important to know the concepts of subscription:

  • Observable box: Is the related box will be observed. This box emits events (click, select, ...)
  • Observable event: Is the event emitted by observable box.
  • Observer box: Is the related box that change his content depending one or more observable box events.

If one box have subscription, this box will be observ and his content will depend on observable box. When observable box emits an event, observer box is listening it and refresh his content with the record emitted by the observable box.

Loading...

In order more easily to understand box subscription, is better explain how works a Related box. That type of box is a component that displays its own data. Its data are a result of the SQL Statement execution. The statement is defined on the box and can have dynamic conditions. In the dynamic conditions its possible use next variables:

  • Typical statement variables (adapter columns, parent columns, variables, $0, ...)
  • Box subscription filter variables.

A box is dependent on other Related box when it has defined subscription. In subscription, an observer box subscribes to an observable box. Then that observer reacts to a particular event that the observable emits.

Hence, box subscription is the subscription from one box to one or more different box.

When an observer box is initially loaded, the system replaces the subscription variables used in the SQL Statement by the subscription condition of an INITIAL event (0). Subscription condition is parsed with the typical statement variables (adapter, parent, variables,...).

After that, observer box is observing to observable box configured on subscription. If one of the observable fires one event observed, observer box reload his content replacement the subscription variables used on SQL Stamentent by the condition of event emits. This condition is parsed with the record emits by the observable box on the event and the typical statement variables (adapter, parent, variables,...). If the SQL Statement has another variables not still initialized, it is replaced by the cond on the INITIAL event (0).

2.2 Dictionary tables

Subscription are defined into an observable box. The parent of all SQL boxes (wic_jrep_box_sql…) is a wic_jrep_box_celldata, for this reason, the subscription table (wic_jrep_box_subscription) has the same parent.

2.2.1 Model

Loading...

2.2.2 Subscription

On this object is possible configure the subscriptions to one or more related box.
There are a control into triggers to prevent duplicated subscriptions:
box_id, observable_box, observable_event, subscription_filter_code
wic_jrep_box_subscription
Label Description
subscription_id Subscription identifier
Observer box Is the observer box
Box observed box observed in a subscription. It column can be NULL when event_type is 0 (INIT
Event observed Event observed in a subscription

  • Values:
    • 0: Initial.
    • 1: Click.
    • 2: Select.
    • 3: Insert.
    • 4: Update.
    • 5: Delete.
    • 6: Transaction.
    • 7: Action.
Filter variable Variable with the filter to use on statement

  • Default: f
Observation expression Expression to ignore the subscription when one event is fired.

  • Format: UELSQL_EXPR
Filter condition Condition to replace by the variable used on observer box STATEMENT.

  • Format: SQLCOND_EXPR
Created by

  • Default: USER
Date created

  • Default: CURRENT
Modified by

  • Default: USER
Date updated

  • Default: CURRENT

3 Implementation

The following sections show how to create Box subscription step by step. It starts by simple subscription, in the first section, and keep on explaining more situations in further sections.

When using subscriptions on XSQL scripts, you can use the term ${filter?literal} or ${unescape(Ax.context.data.filter)} to obtain the condition:
Copy
<select>
    <columns>
        column_name1, column_name2, ...
    </columns>
    <from table='table_name'/>
    <where>
        ${filter?literal}
    </where>
</select>

<select>
    <columns>
        column_name1, column_name2, ...
    </columns>
    <from table='table_name'/>
    <where>
        ${unescape(Ax.context.data.filter)}
    </where>
</select>
When using in JS scripts, you can use Ax.context.data.filter to obtain the condition:
Copy
<script>
    var mCondition = unescape(Ax.context.data.filter);
</script>
Use the function unescape() to avoid problems with possible unicode characters.

3.1 Subscribes to one related box

Open your dictionary application and go to the object you want to add SQL subscription. Entered into Form, then entered into Layout, and go to the observer box (Box for adding a subscription to another).

In this object, there is a transactional SQL BOX to add the subscription, between Show condition (client) box and Boxes view box

The following steps have to be followed:

  • Insert one row on the Subscribes SQL TABLE box for the initial filter variable value:
    • Box observed: NULL
    • Event observed: INITIAL (0)
    • Filter variable: filter
    • Expression: NULL
    • Filter condition: 1=2
    The initial event has been configured to prevent exception when the observer box is loaded. The filter condition depends the objective pursued. If you want to show all the content at INITIAL uses 1=1 condition.
  • Insert another row on the subscribes SQL TABLE box to observer one related box:
    • Box observed: XXXX
    • Event observed: Click
    • Filter variable: filter
    • Expression: NULL
    • Filter condition: column_name = ${column_name}
    Not all the Related box and events can be observed. To see the available box and events go to the Annex section.
  • Add filter variable on the box Statement:
    Copy
    <select>
        <columns>
            column_name1, column_name2, ...
        </columns>
        <from table='table_name'/>
        <where>
            ${filter?literal}
        </where>
    </select>
    Use of "?literal" is needed to prevent exception on statement execution. Without it, the condition is enclosed in double quotes.

3.2 Subscribes to two related box

Open your dictionary application and go to the object you want to add SQL subscription. Entered into Form, then entered into Layout, and go to the observer box (Box for adding a subscription to another).

In this object, there is a transactional SQL BOX to add the subscription, between Show condition (client) box and Boxes view box

The following steps have to be followed:

  • Insert one row on the subscribes SQL TABLE box for the inital filter variable value:
    • Box observed: NULL
    • Event observed: INITIAL (0)
    • Filter variable: filter
    • Expression: NULL
    • Filter condition: 1=2
    The initial event has been configured to prevent exception when the observer box is loaded. The filter condition depends the objective pursued. If you want to show all the content at INITIAL uses 1=1 condition.
  • Insert another row on the subscribes SQL TABLE box to observe the related box:
    • Box observed: XXXX
    • Event observed: Select
    • Filter variable: filter
    • Expression: NULL
    • Filter condition: column_name = ${column_name}
    Not all the Related box and events can be observed. To see the available box and events go to the Annex section.
  • Insert another row on the subscribes SQL TABLE box to observer the second related box:
    • Box observed: XXXX
    • Event observed: Select
    • Filter variable: filter
    • Expression: NULL
    • Filter condition: column_name = ${column_name}
    Not all the Related box and events can be observed. To see the available box and events go to the Annex section.
  • Add filter variable on the box Statement:
    Copy
    <select>
        <columns>
            column_name1, column_name2, ...
        </columns>
        <from table='table_name'/>
        <where>
           ${filter?literal}
        </where>
    </select>
    Use of "?literal" is needed to prevent exception on statement execution. Without it, the condition is enclosed in double quotes.

3.3 Subscribes to two related boxes, combining the content of both

Open your dictionary application and go to the object you want add SQL subscription. Entered into Form, then entered into Layout, and go to the observer box (Box on add subscription to other).

In this object, there is a transactional SQL BOX to add the subscription, between Show condition (client) box and Boxes view box

The following steps have to be followed:

  • Insert one row on the subscribes SQL TABLE box for the inital filter variable value:
    • Box observed: NULL
    • Event observed: INITIAL (0)
    • Filter variable: filter
    • Expression: NULL
    • Filter condition: 1=2
    The initial event has been configured to prevent exception when the observer box is loaded. The filter condition depends the objective pursued. If you want to show all the content at INITIAL uses 1=1 condition.
  • Insert another row on the subscribes SQL TABLE box for the inital of second filter variable value:
    • Box observed: NULL
    • Event observed: INITIAL (0)
    • Filter variable: filter2
    • Expression: NULL
    • Filter condition: 1=2
    The initial event has been configured to prevent exception when the observer box is loaded. The filter condition depends the objective pursued. If you want to show all the content at INITIAL uses 1=1 condition.
  • Insert another row on the subscribes SQL TABLE box to observe the related box and related it to a first filter variable:
    • Box observed: XXXX
    • Event observed: Select
    • Filter variable: filter
    • Expression: NULL
    • Filter condition: column_name = ${column_name}
    Not all the Related box and events can be observed. To see the available box and events go to the Annex section.
  • Insert another row on the subscribes SQL TABLE box to observe the second related box and related it to a second filter variable:
    • Box observed: XXXX
    • Event observed: Select
    • Filter variable: filter2
    • Expression: NULL
    • Filter condition: column_name = ${column_name}
    Not all the Related box and events can be observed. To see the available box and events go to the Annex section.
  • Add two filter variable on the box Statement:
    Copy
    <select>
        <columns>
            column_name1, column_name2, ...
        </columns>
        <from table='table_name'/>
        <where>
           (${filter?literal}) OR (${filter2?literal})
        </where>
    </select>
    Use of "?literal" is needed to prevent exception on statement execution. Without it, the condition is enclosed in double quotes.

4 Samples

4.1 Subscribe SQL Table to two SQL tables

In order to show last box selection, we configured subscription as follows:

Box observed Mnemonic Event observed Filter variable Expression Filter condition
INITIAL filter1 1=2
100122 SQLTABLE1 SELECT filter1 id=${id}
100122 SQLTABLE2 SELECT filter1 id=${id}

The statement of SQLTABLE3 is next:

Copy
<select>
    <columns>
        studio_employees.*
    </columns>
    <from table='studio_employees'/>
    <where>
         ${filter1?literal}
    </where>
</select>

The observer box result is the selection of the second box because it was the last one was selected, as illustrated here below:

4.2 Subscribe SQL Table to two SQL tables combining the result of both

In order to combine the selection of two SQL Box, we configured subscription as follows:

Box observed Mnemonic Event observed Filter variable Expression Filter condition
INITIAL filter1 1=2
100122 SQLTABLE1 SELECT filter1 id=${id}
INITIAL filter2 1=2
100122 SQLTABLE2 SELECT filter2 id=${id}

The statement of SQLTABLE3 is next:

Copy
<select>
    <columns>
        studio_employees.*
    </columns>
    <from table='studio_employees'/>
    <where>
        (${filter1?literal} OR ${filter2?literal})
    </where>
</select>

Result:

5 Annex

5.1 How is filter cond parsed into filter variable?

It is important know how the system set the filter variable subscription. When observable box emits an event with one record, variable is set with the filter condition parsed.

Imagine one box with next subscription:

Box observed Mnemonic Event observed Filter variable Expression Filter condition
100122 SQLTABLE1 Click filter1 parentid=${parentid} AND order=${order}

If SQLTABLE1 emits Click event with a record, variable filter1 is set as below:

Copy
(parentid=1 AND order=1)

However, SELECT event can emit more than one record. ¿How the system works on this case?

Imagine one box with next subscription:

Box observed Mnemonic Event observed Filter variable Expression Filter condition
100122 SQLTABLE1 SELECT filter1 parentid=${parentid} AND order=${order}

If SQLTABLE1 emits SELECT event with three records, variable filter1 is set as below:

Copy
((parentid=1 AND order=1) OR (parentid=1 AND order=2) OR (parentid=1 AND order=3))

5.2 Related boxes and evets can be subscribed.

Related boxes and events can be subscribed.
Related box click select action insert update delete transaction
SQL JS-OBJ              
SQL Map              
SQL Map Edit              
SQL OBJ-Cart              
SQL Table              
SQL Tree              

5.3 Javascript functions

The System provides to users two functions for emits observable events at anytime. The functions are executeClickObservableEvent and executeSelectObservableEvent.

executeClickObservableEvent (p_boxid, p_record)

Fires click event on an observable box. (Observable box has to support it event)

Settings Parameters:

  • p_boxid: string or number

    Observable box Id or memotecnic

  • p_record

    JSON with the record used to refresh the observer box.

Example:

Copy
executeClickObservableEvent ("BOX_SQLTABLE", { id:1 })
executeSelectObservableEvent (p_boxid, p_records)

Fires select event on an observable box. (Observable box has to support it event)

Settings Parameters:

  • p_boxid: string or number

    Observable box Id or memotecnic

  • p_records

    Array JSON with the records used to refresh the observer box.

Example:

Copy
executeSelectObservableEvent ("BOX_SQLTABLE", [{ id:1 },{ id:2 },{ id:3 },{ id:4 }])