UI Definition in HTML and TypeScript: General Information

The structure of an MYOB Acumatica form in the Modern UI is represented by the following layers:

  • The presentation logic in a TypeScript (TS) file, which provides a definition of views with particular settings for them
  • The layout of UI elements displayed on the form in HTML

Learning Objectives

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

  • Define the presentation logic and layout of a form in the Modern UI
  • Use the built-in converter to convert a form from the Classic UI to the Modern UI

Applicable Scenarios

You define an MYOB Acumatica form in HTML and TypeScript in the following cases:

  • In a customization project, you have developed an MYOB Acumatica form for the Classic UI. Now you need to convert this form to the Modern UI to continue supporting this form in future versions of MYOB Acumatica.
  • You are developing a new MYOB Acumatica form.

Controls of the Modern UI

Controls are building blocks for the layout of an MYOB Acumatica form. Each control is composed of an HTML template and a TypeScript class.

Each control has the following attributes:

  • id: An identifier of the control
  • value: A property that can be changed both in the browser and on the server

  • config: A read-only property (that is, it cannot be changed in the browser) that defines the appearance and behavior of the control
  • Bindable attributes, which are shortcuts bound to the properties in the config attribute

You can change config directly in HTML. You can specify particular properties defined in config in one of the following ways:

  • Specify a set of properties by using config.bind, as the following code shows: config.bind="{imageSet: 'main', imageKey: 'Refresh'}"
  • Specify a single property, as the following code shows: config-allow-edit.bind="true"
Tip: If you specify the value for a single property, you need to transform the name of the property that is available in config. For example, suppose that the propertyName property is available in config. To specify a single property, you transform the name to config-property-name.

All controls can be divided into the following categories:

  • Simple controls (which are bindable to server fields)
  • Containers (which are vessels for other controls)
  • Compound controls (which usually are bindable to a view or have their own controller)
  • Abstract controls (which serve as a basis for other control types)

For simple controls, you typically do not specify their type, such as qp-checkbox, in HTML. Instead, you use the field tag in HTML. The server automatically defines the type of the field in the Modern UI. The PX*FieldAttribute attribute that is assigned to the field in the backend code creates a specific type, which is an inheritor of PXFieldState. This type affects the default control used by the client.

Note: You cannot use shortened versions of custom HTML tags, such as <qp-grid .../> or <qp-button .../>, because of HTML limitation, which prohibits shorten version of tags except for a limited number of tags. HTML allows use of shortened tags only for particular standard HTML tags.

MYOB Acumatica Form in the Modern UI

You can find the source code of the Modern UI of MYOB Acumatica forms in the FrontendSources/screen/src/screens folder of the MYOB Acumatica instance folder. This folder contains subfolders with two-letter names. Each subfolder contains the source code of the forms whose screen IDs start with these two letters. For each form, the subfolder contains a folder with the screen ID as the folder name, such as GL401000. This folder contains the HTML and TS files that have the screen ID as the file name, such as GL401000.ts and GL401000.html. For large forms with many data views, such as Sales Orders (SO301000), view definitions may be located in separate files with the views.ts name.

Note: You must use the import directive to refer to the view definitions from separate files, as shown in the following code.
import
{
	SOOrder,
	BlanketTaxZoneOverrideFilter
} from './views';

In the following cases, you can define the views and layout in extensions of the form:

  • For the areas of the form that are specific to particular features.
  • For the definitions of pop-up dialog boxes (which are also called smart panels in the Classic UI).
  • For the definitions of tabs. However, for tabs, you need to specify that the tab has an external definition and provide its ID by using the ref attribute of the qp-tab tag. For details, see Tab: Reference Information.

The Extensions folder contains TS and HTML files for extensions of the form. Each file name starts with the screen ID and ends with a postfix that indicates the purpose of the extension, such as GL401000_MultiCurrency.ts.

Below you can see an example of the hierarchy of the files and folders of the Modern UI.
Site
- FrontendSources/screen/src/screens
- - GL
- - - GL401000
- - - - Extensions (optional)
- - - - - GL401000_extension1.html
- - - - - GL401000_extension1.ts
- - - - - GL401000_extension2.html
- - - - - GL401000_extension2.ts
- - - - GL401000.html
- - - - GL401000.ts
- - - - views.ts (optional)

Screen Class in TypeScript

To define the views of an MYOB Acumatica form in TypeScript, in the TS file of the form, you define a screen class—a class for the form—as shown in the following code.

import { graphInfo, PXScreen} from "client-controls";
  
@graphInfo({graphType:'PX.Objects.GL.AccountHistoryEnq', primaryView:'Filter'})
export class GL401000 extends PXScreen {
}

The screen class must satisfy the following requirements:

  • It has the screen ID as the name of the class, such as GL401000.

  • It extends the PXScreen class.

  • It has the graphInfo decorator, in which you specify the graph and the primary view of the graph.
    Tip: You can also specify optional parameters of the graphInfo decorator and use other decorators. For the list of available decorators, see UI Definition in HTML and TypeScript: TypeScript Decorators.

In the screen class, you define a property for each data view, as shown in the following code.

import { graphInfo, PXScreen, createSingle } from "client-controls";
  
@graphInfo({graphType:'PX.Objects.GL.AccountHistoryEnq', primaryView:'Filter'})
export class GL401000 extends PXScreen {
  @viewInfo({containerName: 'Filter'})
  Filter = createSingle(GLHistoryEnqFilter);
}

This property must satisfy the following requirements:

  • It has the same name as the name of the data view.

  • If you need to display a form control, the property is initialized with the createSingle method, which takes as the input parameter an instance of the view class. (The view class is described below.)

  • If you need to display a table, the property is initialized with the createCollection method, which takes as the input parameter an instance of the view class. You can specify configuration parameters for the table by using the gridConfig decorator.

  • It has the viewInfo decorator with the specified container name. (This name is used as an object name during the configuration of particular functionality, such as workflows and import and export scenarios. If this value is not specified, the system displays the name of the data view as the object name. )

Tip: Multiple containers can be bound to the same graph's view. If you need to bind multiple container controls to the same graph's view and one of these controls corresponds to a table, you initialize the property in TypeScript by using the createCollection function.

View Classes in TypeScript

In the TS file of the form, for each view of the graph you define a view class—that is, a class for each view of the graph—as shown in the following code. The class extends the PXView class.

import { PXView } from "client-controls";
  
export class GLHistoryEnqFilter extends PXView {
}
In each view class, you specify the properties for all data fields of the data view that you want to be able to show or use in the UI, as shown below. You use the name of the data field as the property name.
Description: PXFieldState;
ShowCuryDetail: PXFieldState<PXFieldOptions.Hidden | 
  PXFieldOptions.CommitChanges>;
OrderDate: PXFieldState<PXFieldOptions.CommitChanges>;

For each property, you specify the type of the property, which can be one of the following:

  • PXFieldState
  • PXFieldState<list_of_options>, where you specify the options by using the PXFieldOptions enum. The options can be combined.
    Tip: The PXFieldOptions enum includes the following options:
    • Default: The field has default settings.
    • Readonly: The field is read-only.
    • Hidden: The field is hidden.
    • NoLabel: The field has no label. Instead of using this option, consider using the no-label class. For details about the class, see Form Layout: CSS Classes.
    • Multiline: The field is multiline. For details, see Form Layout: Configuring a Multiline Text Box.
    • CommitChanges: The field commits changes to the server.
    • Disabled: The field appears on the form but is unavailable.

You can also use decorators for fields. For the list of available decorators, see UI Definition in HTML and TypeScript: TypeScript Decorators.

For details about how to add a field from a joined data access class of the data view, see UI Definition in HTML and TypeScript: Joined Fields.

Action Definitions in TypeScript

The actions that are defined in the graph or in the workflow have corresponding commands displayed on the More menu of the form toolbar by default. You do not need to define them in the TS code of the MYOB Acumatica form. However, if you need to place a button for an action on the table toolbar or in a dialog box, you need to include the action in TS code by specifying the properties of the PXActionState type in the screen or view class. This action is automatically bound by name to an action in the graph; it is not displayed on the More menu of the form toolbar by default.

In the screen class, you specify the properties for all actions that should have buttons displayed in the dialog boxes, as the following code shows.

import { graphInfo, PXScreen, PXActionState} from "client-controls";
  
@graphInfo({graphType:'PX.Objects.GL.AccountHistoryEnq', primaryView:'Filter'})
export class GL401000 extends PXScreen {
    AddInvoiceOK: PXActionState;
}

In the view class for a table control, you specify the properties for all actions that should have buttons displayed on the table toolbar, as shown below.

import { gridConfig, PXView, PXActionState} from "client-controls";
  
@gridConfig({preset: GridPreset.Details})
export class SOLine extends PXView {
    AddInvBySite: PXActionState;
}

Layout in HTML

In the HTML file, you define the layout of the MYOB Acumatica form and the appearance of particular UI elements. You use the rules described in the following chapters:

UI Components of an MYOB Acumatica Form

The following diagram shows the UI components of an MYOB Acumatica form and the interactions between them.

Figure 1. UI components and their interactions