A powerful aspect of the QuickApp framework is that interactions with one widget can
affect the state of other widgets as well as the data that those widgets display. The
dynamic environment established by the QuickApp manages the state of all of the widgets and
is responsible for updating any widgets that reference a dynamic variable which has
changed.
In Associate a query with a widget, you saw that selecting a department
description from the drop-down widget automatically changed the department number
that was displayed by the text widget. You could take this one step further, and
instead of just displaying the department number in a text widget, you could use
that value in a 1010data query associated with a grid widget that shows summarized
sales data for items in the selected department.
To interact with other widgets:
-
Add a grid widget that uses the dynamic variable modified by the drop-down
widget.
<dynamic selection="19" product_master="pub.doc.retail.product"
sales_detail="pub.doc.retail.salesdetail">
<widget class_="dropdown" base_="{@product_master}"
inputwidth_="250" value_="@selection"
label_="Department:" labelwidth_="75">
<tabu label="Tabulation on Product Master" breaks="deptdesc">
<break col="deptdesc" sort="up"/>
<tcol source="dept" name="dept" fun="first"
label="First`Department"/>
</tabu>
<colord cols="dept,deptdesc"/>
</widget>
<widget class_="text" text_="Current selection: {@selection}"/>
<widget class_="grid" base_="{@sales_detail}">
<link table2="{@product_master}" col="sku" col2="sku"
suffix="_prod" type="select">
<sel value="dept={@selection}"/>
</link>
<tabu label="Tabulation on Sales Detail" breaks="groupdesc_prod">
<tcol source="xsales" fun="sum" name="tot_sales"
label="Sum of`Extended Sales" format="type:currency"/>
</tabu>
<sort col="tot_sales" dir="down"/>
<sel value="(groupdesc_prod <> '')"/>
</widget>
</dynamic>
A grid widget has been added that operates on the table
pub.doc.retail.salesdetail, which is specified via
the base_
attribute using the dynamic variable
sales_detail
. This variable is declared in the opening
<dynamic>
tag.
The query associated with this grid widget first performs a
<link>
operation and links to the table specified by
the dynamic variable
product_master
. Inside the
<link>
operation, a
<sel>
operation selects those rows in the
Product Master
table where the department is equal to the value of the dynamic variable
selection
(using the
{@selection}
notation).
Note: In the opening <dynamic>
tag, the
dynamic variable selection
is set to a valid department
number (19
). If this dynamic variable is set to the
empty string, the QuickApp will produce an error when it runs because,
after the dynamic variables have been substituted, the code
<sel value="dept={@selection}"/>
will expand to
<sel value="dept="/>
, which is not valid Macro
Language code. By initializing the variable to 19
, the
code will expand to <sel value="dept=19"/>
, which is
valid.
After the link, the query performs a tabulation to calculate the sum of sales
for each group in the groupdesc
column. It then sorts the
totals in descending order and filters out any rows in the
groupdesc
column that do not have a value (or, more
specifically, selects those rows in the groupdesc
column
that are not equal to the empty string).
-
Click Apply.
When the QuickApp first runs, the text widget displays
19, which is the initial value of the dynamic
variable selection
. The input field of the drop-down widget
displays BEVERAGE, which is the corresponding
department description. In addition, the grid widget shows the sum of sales
for each of the group descriptions in that department.
When you make a different selection in the drop-down widget, the value of
the dynamic variable selection
changes. When that variable changes,
any widgets that reference that variable are automatically updated. In this example,
both the text widget and the grid widgets are updated, since they both reference
selection
.
-
Select a different value in the drop-down widget (e.g., DAIRY
DELI).
When the new value is selected in the drop-down widget, the value of
selection
is changed to the corresponding department
number. When that variable changes, the text widget is updated to show the
new value, and the grid widget is updated to display the results of the
query run with the new department. In this example, the text widget displays
the department number 20, which corresponds to the
DAIRY DELI department description, and the grid
widget shows the sum of sales for each of the group descriptions in that
department.
Text widgets, like the one in this example, can be useful for debugging
purposes as they provide a way to see the values of dynamic variables as you develop
your QuickApp. However, you may not want to include them in the final version of
your QuickApp. Obviously, you could delete them to remove them from your QuickApp,
but a useful alternative is to use the <ignore>
element to omit
them from the rendered QuickApp. Then, if you need them in the future, all you have
to do is remove the <ignore>
tags.
-
Add an opening and closing
<ignore>
tag around the text
widget.
<dynamic selection="19" product_master="pub.doc.retail.product"
sales_detail="pub.doc.retail.salesdetail">
<widget class_="dropdown" base_="{@product_master}"
inputwidth_="250" value_="@selection"
label_="Department:" labelwidth_="75">
<tabu label="Tabulation on Product Master" breaks="deptdesc">
<break col="deptdesc" sort="up"/>
<tcol source="dept" name="dept" fun="first"
label="First`Department"/>
</tabu>
<colord cols="dept,deptdesc"/>
</widget>
<ignore>
<widget class_="text" text_="Current selection: {@selection}"/>
</ignore>
<widget class_="grid" base_="{@sales_detail}">
<link table2="{@product_master}" col="sku" col2="sku"
suffix="_prod" type="select">
<sel value="dept={@selection}"/>
</link>
<tabu label="Tabulation on Sales Detail" breaks="groupdesc_prod">
<tcol source="xsales" fun="sum" name="tot_sales"
label="Sum of`Extended Sales" format="type:currency"/>
</tabu>
<sort col="tot_sales" dir="down"/>
<sel value="(groupdesc_prod <> '')"/>
</widget>
</dynamic>
-
Click Apply.
The text widget is not rendered in the QuickApp.
Now that the user can select which department to use for the query, you
might want to give them the choice of which column to group by in the tabulation.
Instead of a list of all possible columns, you might want to restrict the choices to
either the column containing the group description or the column containing the
brand. You can add another drop-down widget that uses a <table>
element to provide an inline table to populate the drop-down menu with these
specific items.
-
Add a drop-down widget that allows the user to select the column containing the
group description (
groupdesc_prod
) or the brand
(brand_prod
).
<dynamic selection="19" product_master="pub.doc.retail.product"
sales_detail="pub.doc.retail.salesdetail" aggregate_by="groupdesc_prod">
<widget class_="dropdown" base_="{@product_master}"
inputwidth_="250" value_="@selection"
label_="Department:" labelwidth_="75">
<tabu label="Tabulation on Product Master" breaks="deptdesc">
<break col="deptdesc" sort="up"/>
<tcol source="dept" name="dept" fun="first"
label="First`Department"/>
</tabu>
<colord cols="dept,deptdesc"/>
</widget>
<widget class_="dropdown" value_="@aggregate_by"
label_="Aggregate by:" labelwidth_="75" inputwidth_="250">
<table>groupdesc_prod,Group;brand_prod,Brand
</table>
</widget>
<ignore>
<widget class_="text" text_="Current selection: {@selection}"/>
</ignore>
<widget class_="grid" base_="{@sales_detail}">
<link table2="{@product_master}" col="sku" col2="sku"
suffix="_prod" type="select">
<sel value="dept={@selection}"/>
</link>
<tabu label="Tabulation on Sales Detail" breaks="{@aggregate_by}">
<tcol source="xsales" fun="sum" name="tot_sales"
label="Sum of`Extended Sales" format="type:currency"/>
</tabu>
<sort col="tot_sales" dir="down"/>
<sel value="({@aggregate_by} <> '')"/>
</widget>
</dynamic>
A drop-down widget has been added to the QuickApp right after the drop-down
used to select the department. The new drop-down widget uses the dynamic
variable aggregate_by
to store the selection (as specified
by the value_
attribute). The dynamic variable
aggregate_by
is declared in the
<dynamic>
and is set to the value
groupdesc_prod
. In addition, the references to
groupdesc_prod
in the query associated with the grid
widget have been changed to refer to the value of the
aggregate_by
dynamic variable (using the
{@aggregate_by}
syntax).
The query associated with the new drop-down widget consists of a single
<table>
operation that creates a two-column table.
The first column contains the values that the dynamic variable
aggregate_by
will be set to when a selection is made
from the drop-down menu, and the second column contains the corresponding
labels that will be displayed in the drop-down menu.
-
Click Apply.
The Aggregate by drop-down widget appears to the right
of the Department drop-down widget.
-
Select Brand from the Aggregate
by drop-down menu.
When the selection is made in the Aggregate by
drop-down menu, the value of the dynamic variable
aggregate_by
is changed to brand_prod
.
The QuickApp then automatically checks to see which widgets reference that
dynamic variable and updates them accordingly. Since the grid widget uses
aggregate_by
, the query associated with it is executed,
and the grid widget is updated with the new results.
Cumulative QuickApp code
The Macro Language code for the QuickApp up to this point is:
<dynamic selection="19" product_master="pub.doc.retail.product"
sales_detail="pub.doc.retail.salesdetail" aggregate_by="groupdesc_prod">
<widget class_="dropdown" base_="{@product_master}"
inputwidth_="250" value_="@selection"
label_="Department:" labelwidth_="75">
<tabu label="Tabulation on Product Master" breaks="deptdesc">
<break col="deptdesc" sort="up"/>
<tcol source="dept" name="dept" fun="first"
label="First`Department"/>
</tabu>
<colord cols="dept,deptdesc"/>
</widget>
<widget class_="dropdown" value_="@aggregate_by"
label_="Aggregate by:" labelwidth_="75" inputwidth_="250">
<table>groupdesc_prod,Group;brand_prod,Brand
</table>
</widget>
<ignore>
<widget class_="text" text_="Current selection: {@selection}"/>
</ignore>
<widget class_="grid" base_="{@sales_detail}">
<link table2="{@product_master}" col="sku" col2="sku"
suffix="_prod" type="select">
<sel value="dept={@selection}"/>
</link>
<tabu label="Tabulation on Sales Detail" breaks="{@aggregate_by}">
<tcol source="xsales" fun="sum" name="tot_sales"
label="Sum of`Extended Sales" format="type:currency"/>
</tabu>
<sort col="tot_sales" dir="down"/>
<sel value="({@aggregate_by} <> '')"/>
</widget>
</dynamic>