Interact with other widgets

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:

  1. 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).

  2. 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.

  1. 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.

  1. 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>
    
  2. 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.

  1. 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.

  2. Click Apply.

    The Aggregate by drop-down widget appears to the right of the Department drop-down widget.

  3. 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>