v1.6.0

<bmx-report-designer>

The report designer: the authoring tool for the reports the report viewer shows. It edits the same JSON definition the viewer reads, in the browser, with no server and nothing to install - so an application can let its own users design their reports, and save the result wherever it keeps data.

14 properties · 3 events · 7 methods · 23 parts

Example

Everything runs in the browser. Drag a field onto a band, move and resize what is there, and edit the selection on the right. The toolbox adds charts, crosstabs, barcodes and QR codes, drawn from the sample rows as you place them. Preview runs the report in a report viewer; New report lays out a list, a grouped report, a summary or a form letter for the data's fields.
Show markup
<bmx-report-designer id="ex-rd" style="--bmx-report-designer-height: 40rem"></bmx-report-designer>

<div class="row" style="margin-block-start: 1rem">
  <span class="note" id="ex-rd-out">
    <strong>Everything runs in the browser.</strong> Drag a field onto a band, move and resize what is there, and
    edit the selection on the right. The toolbox adds charts, crosstabs, barcodes and QR codes, drawn from the
    sample rows as you place them. <strong>Preview</strong> runs the report in a report viewer;
    <strong>New report</strong> lays out a list, a grouped report, a summary or a form letter for the data's fields.
  </span>
</div>

<script type="module">
  await customElements.whenDefined('bmx-report-designer');

  const designer = document.getElementById('ex-rd');
  const out = document.getElementById('ex-rd-out');

  // Sample rows: the designer finds the fields in them for its field list,
  // and the preview runs the report over them.
  const customers = ['Acme Ltd', 'Bolt & Co', 'Cogworks', 'Delta Supplies', 'Evergreen Farms', 'Fulcrum Tools'];
  designer.data = Array.from({ length: 120 }, (_, i) => ({
    date: `2026-${String(1 + (i % 9)).padStart(2, '0')}-${String(1 + ((i * 7) % 28)).padStart(2, '0')}`,
    region: i % 3 ? 'North' : 'South',
    customer: customers[i % customers.length],
    quantity: 1 + ((i * 13) % 20),
    price: 20 + ((i * 37) % 180),
  }));

  // Start from a template laid out for those fields - or set `designer.report`
  // to a definition you saved earlier.
  await designer.newReport('grouped', 'Orders by region');

  // Every edit, undo and redo arrives here with the whole new definition.
  designer.addEventListener('bmxReportChange', event => {
    out.textContent = `bmxReportChange: ${event.detail.action}.`;
  });

  // Save: keep the JSON yourself instead of letting it download.
  designer.addEventListener('bmxReportSave', event => {
    event.preventDefault();
    out.textContent = `bmxReportSave: ${event.detail.json.length} characters of JSON ready to store.`;
  });
</script>
<bmx-report-designer data-url="/api/orders"></bmx-report-designer>
designer.report = savedDefinition;   // or leave it empty: the gallery opens
designer.data = sampleRows;          // fields for the field list and the preview
designer.addEventListener('bmxReportSave', event => {
  event.preventDefault();
  api.save(event.detail.json);
});

WHAT THE AUTHOR GETS

The report's bands down the page, drawn to scale with their items. Items are dragged in from the toolbox and the field list - a field dropped in a header becomes its caption, in the detail band its value, in a footer its total - then moved, resized, lined up and spaced, snapping to the grid and to each other's edges and centres. Bands are made taller or shorter by their lower edge. The properties panel edits whatever is selected: an item's content, format and style, a band and its group, or the report's page, parameters, calculated fields, filter, sort and named styles. Every expression field completes fields, parameters, variables and functions as it is typed, and checks itself; the expression builder lists everything with its help and shows the result on the first row of the data. Excel's functions that work on values are there as well, by their Excel names (NETWORKDAYS(start, end), PROPER(name), PMT(rate, n, amount)), with _ for a dot (WORKDAY_INTL). Undo and redo cover every edit. Preview runs the report in a bmx-report-viewer; JSON shows the definition and takes one pasted in.

KEYBOARD AND SCREEN READERS

Everything the mouse does has a keyboard route. The outline lists every band and item as buttons; the properties panel sets positions and sizes as numbers. On the design surface, Tab and Shift+Tab step through the items, the arrow keys move the selection a point (Shift: a grid step), Alt with the arrows resizes it, Delete removes it, Ctrl+C, X, V and D copy, cut, paste and duplicate, Ctrl+A selects the band's items, and Escape clears the selection - after which Tab leaves the surface. Each change is announced.

Properties

PropertyAttributeTypeDefaultDescription
data data readonly Record<string, unknown>[] | string [] Sample rows: an array of objects, or JSON text. They give the field list and the preview its data.
dataUrl data-url string — A URL to fetch the sample rows from, as a JSON array. Takes the place of data.
fields fields readonly BmxReportFieldSpec[] | string [] The fields to offer, when there is no data to find them in: names, or { name, type } with type number, text, date or boolean. JSON text works too.
fileName file-name string — The name the JSON is saved under. Defaults to the report's title.
gallery gallery boolean true Offers the template gallery, and opens it when there is no report.
gridSize grid-size number 4 The grid spacing in points. Items snap to it.
label label string — The designer's accessible name.
locale locale string — The locale for sample values and the preview. Defaults to the report's language.
mode mode 'design' | 'preview' | 'json' 'design' design, preview (the report run in a viewer) or json (the definition as text).
report report BmxReport | string | null null The report being designed: an object, or JSON text. The designer writes each edit back to it.
requestInit property only RequestInit — Options for the fetch - headers, credentials. Script only.
showGrid show-grid boolean true Draws the grid on the bands.
snap snap boolean true Items snap to the grid and to each other while they are dragged. Hold Alt to place freely.
zoom zoom number | string 'page-width' The design surface's scale: page-width fits the page to the surface; 1 is actual size, 1.5 is 150%.

Events

EventDetailDescription
bmxReportChange BmxReportChangeDetail Every change to the report: an edit, undo or redo, a template, or JSON applied.
bmxReportSave BmxReportSaveDetail Save was pressed. Cancel it to store the report yourself; otherwise the JSON downloads.
bmxSelectionChange BmxReportSelectionDetail The selection changed.

Methods

MethodSignatureDescription
downloadJson downloadJson(fileName?: string) => Promise<void> Saves the report as a JSON file.
getJson getJson() => Promise<string> The report as JSON text.
getReport getReport() => Promise<BmxReport> The report as it is now.
newReport newReport(template?: string, title?: string) => Promise<BmxReport> Replaces the report with one built from a template in the gallery: blank, list, grouped, summary, letter.
redo redo() => Promise<boolean> Redoes the last edit undone.
select select(ids: readonly string[]) => Promise<void> Selects items by id.
undo undo() => Promise<boolean> Undoes the last edit. Resolves to whether there was one.

Slots

SlotDescription
toolbar-end extra controls at the end of the toolbar.

CSS shadow parts

PartDescription
builder
button
card
completions
data-field
empty
field
field-error
gallery
insert-panel
json
main
mode
preview
problems
properties-panel
properties-title
status-bar
surface
template
tool
toolbar
zoom

CSS custom properties

PropertyDescription
--bmx-report-designer-desk The area around the page.
--bmx-report-designer-guide The lines drawn while an item snaps. @part toolbar - the row of controls. @part mode - the Design, Preview and JSON buttons. @part button - a button. @part zoom - the zoom list. @part main - the panels and the design surface. @part insert-panel - the toolbox, field list and outline. @part tool - a toolbox entry. @part data-field - a field in the field list. @part surface - the scrolling design surface. @part empty - what the surface shows when the report has no bands. @part properties-panel - the properties of the selection. @part properties-title - its heading. @part field - a labelled property. @part field-error - an expression's error under its field. @part completions - the suggestion list under an expression field. @part card - a group, sort key, field, parameter or condition in the properties. @part status-bar - the problems count, selection and zoom at the foot. @part problems - the list of problems. @part preview - the report viewer in Preview. @part json - the JSON view. @part builder - the expression builder dialog. @part gallery - the template gallery dialog. @part template - a template in it.
--bmx-report-designer-height How tall the designer is.
--bmx-report-designer-insert-width How wide the insert panel is.
--bmx-report-designer-properties-width How wide the properties panel is.
--bmx-report-designer-selection The outline and handles of the selection.