Reusing of UI Definitions: General Information

You can reuse a UI definition in TypeScript and HTML as follows:

  • To reuse a TypeScript declaration, you extend a screen class or a class that derives from a screen class.
  • To reuse a HTML declaration or any part of it, you use the qp-include tag.

Learning Objectives

In this chapter, you will learn how to do the following:

  • Reuse the whole UI definition of an MYOB Acumatica form for another form
  • Create and use a reusable UI definition
  • Add, remove, or replace parts of form layout in a reusable UI definition

Applicable Scenarios

You reuse a UI definition in the following cases:

  • You need to implement two almost-identical MYOB Acumatica forms, such as Site Map (SM200520) and Portal Map (SM200521). You reuse the UI definition of one form to define the other form.
  • You need to implement multiple MYOB Acumatica forms that have similar UI definitions, such as Scan and Receive (IN301020), Scan and Issue (IN302020), Scan and Transfer (IN304020), and Scan and Count (IN305020). You implement a reusable UI definition for the common UI parts of the forms and adjust the definition for each form.
  • You need to use identical parts of a form—such as sections, tabs, or dialog boxes—on multiple forms.

Reusing the Whole UI Definition of a Form

To reuse the UI definition of a form, you need to reuse both the TypeScript declaration and the HTML code by performing the following general steps:

  1. In the TypeScript file for the new form, you extend the existing screen class, as shown in the following example. You must specify the graph type and the primary view of the new form in the graphInfo decorator.
    @graphInfo({
      graphType: "PX.SiteMap.Graph.PortalMapMaint"
      primaryView: "SiteMap",
    })
    export class SM200521 extends SM200520 {}

    You can use the exact copy of the original class or modify the UI definition inherited from the base class.

  2. In the HTML file for the new form, you insert the HTML code of the existing form by using the qp-include tag.
    <template>
      <qp-include url="../SM200520/SM200520.html">
    </template>

Creating a Reusable UI Definition

To create a reusable UI definition that contains parts of a form that you want to reuse, you perform the following general steps:

  1. In a TS file, you declare an abstract class that extends the PXScreen class, as shown in the following code.
    export abstract class BarcodeProcessingScreen extends PXScreen {
    }
  2. In the abstract class, you define the views and the logic that will be reused, as the following example shows.
    import { ScanInfo, ScanLogs } from "./views";
    
    export abstract class BarcodeProcessingScreen extends PXScreen {
        @viewInfo({ containerName: "Scan Information" })
        Info = createSingle(ScanInfo);
     
        @viewInfo({ containerName: "Scan Logs" })
        Logs = createCollection(ScanLogs);
     
        @handleEvent(CustomEventType.GetRowCss, { view: 'Logs' })
        getLogsRowCss(args: RowCssHandlerArgs) {
            if (args?.selector?.row?.MessageType.value === 'ERR') {
                return 'excessedLine startedLine';
            }
            else if (args?.selector?.row?.MessageType.value === 'WRN') {
                return 'startedLine';
            }
     
            return undefined;
        }
    }
  3. In the HTML file with the same name as the TS file, you define the reusable HTML code, such as the following code.
    <template>
    	<require from="screens/barcodeProcessing/styles.css"></require>
    
    	<qp-template id="HeaderView_formHeader" name="7-10-7" wg-container 
    	    class="equal-height">
    		<qp-fieldset id="main" view.bind="HeaderView" slot="A">
    			<field name="Barcode"
    				control-type="qp-barcode-input"
    				config-sound-control.bind="Info.MessageSoundFile"
    				config-submit-command.bind="Scan">
    			</field>
    		</qp-fieldset>
    
    		<qp-fieldset id="secondary" view.bind="HeaderView" slot="B" 
    		    class="no-label">
    			<field name="Message" config-rows.bind="3"></field>
    		</qp-fieldset>
    
    		<qp-fieldset id="third" view.bind="HeaderView" slot="C" 
                     class="no-label">
    			<field name="ProcessingSucceeded"
    				config.bind="{
    					label: '',
    					renderStyle: 'button',
    					checkImages: { normal: 'main@Success' },
    					uncheckImages: { normal: 'main@Fail' }
    				}"
    				config-class.bind="'ProcessingStatusIcon'">
    			</field>
    		</qp-fieldset>
    
    		<qp-fieldset id="info" view.bind="Info">
    			<field name="MessageSoundFile" show.bind="false"></field>
    		</qp-fieldset>
    	</qp-template>
    
    	<qp-tabbar id="mainTab">
    		<qp-tab id="tabLogs" caption="Scan Log">
    			<qp-grid id="gridLogs" wg-container="grid4" view.bind="Logs">
    			</qp-grid>
    		</qp-tab>
    	</qp-tabbar>
    </template>

    This code implements a Summary area with three columns and a tab bar with a single tab.

Using a Reusable UI Definition

To use a reusable UI definition on a form, you do the following:

  1. In the TypeScript file of the form to which you need to insert the reusable UI definition, you declare the screen class that extends the abstract class of the reusable UI definition, as shown in the following code.
    import { BarcodeProcessingScreen } 
      from "../../barcodeProcessing/BarcodeProcessingScreen";
      
    export class IN202520 extends BarcodeProcessingScreen {
    }
  2. In the HTML code of the form in which you need to insert the reusable UI definition, you add the qp-include tag with the reference to this reusable UI definition, as shown in the following code.
    <template>
      <qp-include
        url="../../barcodeProcessing/BarcodeProcessingScreen.html">
      </qp-include>
    </template>

    You can also use a reusable UI definition in a part of the form. The following code shows an example of reusing the Address section that is defined in a separate file.

    <div slot="B">
      <qp-include url="../../../common/forms/form-address/form-address.html"
        id="formA"
        address-view="AddressCurrent">
      </qp-include>
    </div>
  3. You adjust the TypeScript and HTML code of the form as described in the following section.

Adjusting the Reusable UI Definition

After you have inserted a reusable UI definition in the UI definition of a form, you may need to add, remove, or replace particular UI elements to adjust the UI definition of the form. You do the following:

  1. In the TypeScript code of the form, you define the elements that are not included in the reusable UI definition, such as in the following code.
    export class IN202520 extends BarcodeProcessingScreen {
      @viewInfo({ containerName: "Scan Header"  })
      HeaderView = createSingle(ScanHeader);
    }
  2. You adjust the layout of the reusable UI definition as follows:
    1. You add one of the tags that you need to modify after the qp-include tag.
      Important:
      All tags that adjust the layout of the reusable UI definition must be located in the top-level template tag of the HTML file.
    2. You specify the attribute that indicates the type of modification, which can be one of the following:
      • before
      • after
      • append
      • prepend
      • modify
      • remove
      • replace
    3. As the value of the attribute, you specify # followed by the ID of the tag you are modifying, such as #main.

    You add as many adjustments as you need. You can find examples of layout adjustments in Reusing of UI Definitions: Layout Adjustment Examples.