View Builder
Instead of maintaining UI5 views as XML files, you assemble them in JavaScript — with a fluent builder that produces the XML in the background. The output is always a <mvc:View> XML string that goes to the frontend.
The simplest case
const z2ui5_cl_xml_view = require("../z2ui5/02/z2ui5_cl_xml_view");
const view = z2ui5_cl_xml_view.factory()
.Shell()
.Page({ title: "Hello" })
.Input({ value: "world" });
client.view_display(view.stringify());factory() returns a new view. Each method creates a UI5 control under the current node and returns the new node — that's how you naturally chain the tree:
view
.Page() // ← new node
.Input() // ← child of Page, new node
.Button(); // ← child of Page (siblings via auto-insertion)Most builder methods set the target to the just-created control as a container. When you explicitly need an aggregation slot (e.g. content, items, cells), there are methods with a lowercase initial:
view
.SimpleForm({ editable: true })
.content() // ← opens the <SimpleForm.content> aggregation
.Label({ text: "Name" })
.Input({ value: "..." });Important aggregation methods
| Method | Aggregation slot |
|---|---|
.content() | <…:content> (Page, SimpleForm, Panel, …) |
.items() | <…:items> (Table, List, ComboBox, …) |
.columns() | <…:columns> (Table) |
.cells() | <…:cells> (ColumnListItem) |
.headerContent() | Page toolbar |
.footer() | Page footer |
.endButton() | Dialog |
They are lowercase to distinguish them from the control methods (PascalCase).
Common controls
view.Page({ title: "..." });
view.Title({ text: "..." });
view.Label({ text: "..." });
view.Input({ value: "..." });
view.Button({ text: "...", press: client._event("EVT") });
view.Text({ text: "..." });
view.CheckBox({ selected: ..., text: "..." });
view.ComboBox({ selectedKey: ..., items: ... });
view.DatePicker({ value: ... });
view.DateTimePicker({ value: ... });
view.TimePicker({ value: ... });
view.Switch({ state: ... });
view.Table({ items: ... }).columns().Column().Text({ text: "Col" });
view.List({ items: ... }).StandardListItem({ title: "...", description: "..." });
view.SimpleForm({ editable: true });
view.Grid({ defaultSpan: "L6 M12 S12" });
view.HBox({ ... });
view.VBox({ ... });
view.MessageStrip({ text: "...", type: "Information" });
view.IconTabBar({ ... });
view.Wizard({ ... });Practically everything UI5 provides in sap.m / sap.ui.layout / sap.tnt is covered — methods map 1:1 to control names, properties to attributes. Boolean values are converted automatically to "true"/"false".
Values: raw, bound, or expression
view.Input({ value: "Hello" }); // literal string
view.Input({ value: client._bind_edit(this.name) }); // two-way bind: {/XX/name}
view.Input({ value: client._bind(this.name) }); // one-way bind: {/name}
view.Input({ value: `{= ${client._bind(this.name)} }` }); // expression binding
view.Input({ value: `{path: '/name', formatter: '.fmt'}` });// classical bindingWhatever you pass as a string lands 1:1 in the XML attribute. The bind helpers are pure string builders.
Custom controls (z2ui5 namespace)
Via view._z2ui5() you get the custom control decorator (see z2ui5_cl_xml_view_cc.js):
view.Page()
._z2ui5().geolocation({
finished: client._event("GEO_DONE"),
longitude: client._bind_edit(this.lng),
latitude: client._bind_edit(this.lat),
});Available custom controls (selection):
camera_picture,camera_selector— camera accesschartjs— Chart.js integrationfile_uploader— file uploadgeolocation— GPSbwip_js— barcode generatorinfo_frontend— UI5 version, device infoscrolling,timer,websocket,storagespreadsheet_export— Excel exportmultiinput_ext,smartmultiinput_ext— extended MultiInputs
All docs: srv/z2ui5/02/z2ui5_cl_xml_view_cc.js.
Embedding static XML
If you already have a view as XML (e.g. exported from a designer), simply bypass the builder:
const fs = require("fs");
const path = require("path");
const xml = fs.readFileSync(path.join(__dirname, "MyView.view.xml"), "utf8");
client.view_display(xml);The roundtrip works exactly the same way — the frontend renderer doesn't care how the XML was produced.
→ Example: Static XML View.
Factories for special views
z2ui5_cl_xml_view.factory(); // normal view (with Shell+Page)
z2ui5_cl_xml_view.factory_popup(); // view for dialog/popupPopups go through client.popup_display(view.stringify()) instead of view_display(...). → More in Popups & Toasts.
Two nested views (master-detail)
A pattern for classic master-detail layouts:
client.view_display(masterView.stringify());
client.nest_view_display(detailView.stringify(), "containerId", "addItem");nest_view_display injects a second view via JS insert into a specific container of the main view. There are two nesting levels (nest_view_display, nest2_view_display) for deeper layouts.
→ Continue with Data Binding.