N NezamDocumentation

Apps, forms, and controls#

Business Language includes UI declarations for apps, forms, controls, and source-driven layout. These declarations describe the user interface without embedding configurable business policy in UI code.

Apps#

Apps can be written with a header block followed by the member body, or with inline header properties inside the body.

bl
app BackOffice {
  title: "Back Office";

  form vendors: VendorForm {
    layout: "wide";
  }

  toolbar: {
    save: "Save" -> save_vendor icon: "save";
  }

  command_palettes: {
    vendors: "Open vendors" -> open_vendors;
  }

  navigation: {
    vendors: {
      form: vendors;
      label: "Vendors";
    }
  }

  ui: {
    layout: "desktop";
  }

  startup: vendors;
}

Apps can declare mounted forms, state, toolbar sections, command palettes, navigation, UI config, and startup form references.

bl
app BackOffice {
  title: "Back Office";
} {
  state {
    selected_vendor_id: VendorId;
  }

  form vendors: VendorForm {
    layout: two_column;
  }

  toolbar: main:
    "Save" -> save_vendor icon: "save";

  command_palettes: global:
    "Open vendors" -> open_vendors shortcut: "Ctrl+K";

  navigation: {
    vendors {
      form: vendors;
      label: "Vendors";
    }
  }

  ui: {
    layout: desktop;
  }

  startup: vendors;
}

Mounted form layout presets include vertical, horizontal, two_column, and grid. App state declarations are typed members and may also appear directly in the app body.

Forms#

Forms also support optional header properties before the member body.

bl
form VendorForm readonly : BaseForm {
  title: "Vendor";

  state {
    selected_vendor_id: VendorId;
  }

  body: {
    required vendor_name: Text from vendor.vendor_name {
      label: "Vendor name";
      on change {
        validate_vendor();
      }
    }

    section address {
      city: Text {
        label: "City";
      }
    }
  }

  toolbar {
    save: PrimaryButton() {
      text: "Save";
      on click {
        save_vendor();
      }
    }
  }

  layout: {
    columns: 2;
  };
}

Form fields support required, optional, readonly, disabled, and hidden. Field bodies can contain properties, nested property blocks, and event handlers.

bl
form VendorForm {
  title: "Vendor";
} {
  selected_vendor_id: VendorId;

  body: {
    @label("Vendor")
    readonly vendor_name: Text from vendor.vendor_name {
      label: "Vendor name";
      display format {
        uppercase: true;
      }
    }
  }
}

Form fields can specify a control type and source with from, a control type without from, or a source without an explicit control type.

bl
form SourceBackedForm {
  body: {
    customer_grid: DataGrid from CustomerMaster;
    customer_group: from CustomerMaster;
    customer_name: TextInput from CustomerMaster.customer_name;
  }
}

Buttons and menus#

Forms can declare reusable button templates and button instances. Button members include properties, event handlers, and nested menus.

bl
form VendorForm {
  button ActionButton<T>(label: string) {
    text: label;
    on click {
      run_action();
    }
  }

  toolbar {
    save: PrimaryButton() {
      text: "Save";
      menu {
        option save_and_close {
          text: "Save and close";
          on click {
            save_and_close();
          }
        }

        separator;
      }
    }
  }
}

Controls#

Controls may use a header block for presentation metadata.

bl
control AddressBlock {
  label: "Address";

  on change {
    validate_address();
  }

  children: {
    control StreetInput {
      placeholder: "Street";
    }
  }
}

Controls contain properties, event handlers, and child controls.

bl
control AddressBlock {
  title: "Address";
} {
  label: "Address";
  on change {
    validate_address();
  }

  children: {
    control StreetInput {
      placeholder: "Street";
    }
  }
}

Source UI layout#

Source UI layout blocks are useful for table or source-driven UI composition. In BL source, use them as the value of a ui: member on a table or class.

For the full syntax, see Source UI layouts.

bl
{
  group "Main" {
    title: "General";

    row {
      field vendor_name;
      field email;
    }

    insert row after field vendor_name {
      field phone;
    }

    hide field email with field phone;
  }
}

Layout groups can contain properties, rows, row operations, and field operations.

Source: packages/business/language/apps-forms-controls.md