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 an 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 with and without parameters
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 parts of the forms with a common UI 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.
Reuse of 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:
- 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. Attention:In the Modern UI, each MYOB Acumatica form must use its own graph type.
@graphInfo({ graphType: "PX.SiteMap.Graph.PortalMapMaint" primaryView: "SiteMap", }) export class SM200521 extends SM200520 {}
You can use an exact copy of the original class or modify the UI definition inherited from the base class.
- 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>
Creation of a Reusable UI Definition
To create a reusable UI definition that contains the parts of a form that you want to reuse, you perform the following general steps:
- 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 { }
- 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; } }
- In the HTML file with the same name as the TS file, you define the reusable HTML code,
as shown in the following example.
<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.
You can also define the parameters of a reusable UI definition in the qp-include-parameters tag. For details, see Reusing of UI Definitions: Reusable UI Definitions with Parameters.
Use of a Reusable UI Definition
To use a reusable UI definition on a form, you do the following:
- In the TypeScript file of the form in 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 { }
- In the HTML code of the form in which you need to insert the reusable UI definition, you
add the qp-include tag with a reference to this reusable UI definition,
as shown in the following code.
<template> <qp-include url="../../barcodeProcessing/BarcodeProcessingScreen.html"> </qp-include> </template>
The following code shows an example of the insertion of a reusable UI definition with parameters. (For details, see Reusing of UI Definitions: Reusable UI Definitions with Parameters.)
<div slot="B"> <qp-include url="../../../common/forms/form-address/form-address.html" id="formA" address-view="AddressCurrent"> </qp-include> </div>
- You adjust the TypeScript and HTML code of the form as described in the following section.
Adjusting of 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 elements to adjust the definition of the form. You do the following:
- In the TypeScript code of the form, you define the elements that you need to modify or
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); }
You can find examples of TypeScript code adjustments in UI Adjustments in HTML and TypeScript: TypeScript Examples.
- You adjust the layout of the reusable UI definition as follows:
- You add one of the tags that you need to modify after or inside the
qp-include tag.Important:If the tags adjust the layout of the reusable UI definition and are defined after the qp-include tag, these tags must be located in the top-level template tag of the HTML file.
- You specify the attribute that indicates the type of modification, which can be one
of the following:
- before: Puts an element before the element referenced in this attribute.
- after: Puts an element after the element referenced in this attribute.
- append: Puts an element after all child elements of the element referenced in this attribute.
- prepend: Puts an element before all child elements of the element referenced in this attribute.
- modify: Modifies values of the attributes of the element referenced in this attribute.
- remove: Removes the element referenced in this attribute.
- replace: Replaces the element referenced in this attribute.
- As the value of the attribute, you specify a CSS selector that defines the element
relative to which you need to place the new element, such as #main or
#secondary [name='OriginalFieldName']".Tip:You can use the following approaches when specifying the CSS selector:
- Specifying the exact location of the element, such as the ID of the fieldset
and the name of the field.
If no element that satisfies the CSS selector is found, the build process fails. For example, suppose that you want to place a box right after the specific box in the specific fieldset of a form. You specify the exact location of the new field in the CSS selector, including the ID of the fieldset and the name of the field. If in a future version of MYOB Acumatica, the field relative to which the new field is placed is moved to another fieldset, the build process will fail for this CSS selector.
- Specifying only the name of the field.
If more than one item satisfies the specified CSS selector, the build process fails. For example, suppose that you want to place a new box right after the specific box and it does not matter to you where this specific box is located on the form. You specify only the name of the field in the CSS selector. If in a future version of MYOB Acumatica, the field is moved to another fieldset, the build process will be successful for this CSS selector.
- Specifying the exact location of the element, such as the ID of the fieldset
and the name of the field.
You add as many adjustments as you need. You can find examples of layout adjustments in UI Adjustments in HTML and TypeScript: HTML Examples.
- You add one of the tags that you need to modify after or inside the
qp-include tag.
Predefined Reusable UI Definitions
A number of predefined reusable UI definitions are available in the following locations:
- The FrontendSources/screen/src/screens/common folder of the MYOB Acumatica instance
- The common folder for particular functionality, such as the FrontendSources/screen/src/screens/IN/common folder of the MYOB Acumatica instance for inventory functionality
You can use these reusable UI definitions in your UI customization projects.