<bmx-json-editor>
One JSON document, three ways to work on it, and a fourth to see what changed: a tree (expand, edit values in place, rename keys, add, duplicate, move and delete, change a value's type), the text (the library's code editor with JSON highlighting, folding, search and underlined mistakes), a table of any array of objects (sortable, editable cells), and the changes against another version of the document.
21 properties · 3 events · 12 methods · 12 parts
Example
No changes yet.
Show markup
<bmx-json-editor id="ex-je" label="Service settings" name="settings" array-key="name" description="Checked against the service's JSON Schema as you edit. Try a negative timeout, or switch to Table on the regions."></bmx-json-editor>
<p class="note" id="ex-je-out" role="status" style="margin: 12px 0 0">No changes yet.</p>
<script type="module">
await customElements.whenDefined('bmx-json-editor');
const editor = document.getElementById('ex-je');
const out = document.getElementById('ex-je-out');
const published = {
service: 'billing-api',
version: '4.2.0',
timeoutSeconds: 30,
retries: { attempts: 3, backoff: 'exponential' },
regions: [
{ name: 'eu-west', replicas: 3, primary: true },
{ name: 'us-east', replicas: 2, primary: false },
],
};
editor.schema = {
type: 'object',
required: ['service', 'version', 'timeoutSeconds', 'regions'],
additionalProperties: false,
properties: {
service: { type: 'string', pattern: '^[a-z][a-z0-9-]*$', description: 'Lower case, letters, digits and hyphens.' },
version: { type: 'string', pattern: '^\\d+\\.\\d+\\.\\d+$', description: 'Semantic version.' },
timeoutSeconds: { type: 'integer', minimum: 1, maximum: 300, default: 30 },
retries: {
type: 'object',
properties: { attempts: { type: 'integer', minimum: 0, maximum: 10 }, backoff: { enum: ['none', 'linear', 'exponential'] } },
},
regions: {
type: 'array',
minItems: 1,
items: {
type: 'object',
required: ['name', 'replicas'],
properties: { name: { enum: ['eu-west', 'eu-central', 'us-east', 'us-west', 'ap-south'] }, replicas: { type: 'integer', minimum: 1, default: 2 }, primary: { type: 'boolean', default: false } },
},
},
},
};
editor.value = structuredClone(published);
editor.compareWith = published;
editor.addEventListener('bmxChange', event => {
const { problems } = event.detail;
out.textContent = problems.length ? `${problems.length} problem(s): ${problems[0].message}` : 'Valid - ready to publish.';
});
</script>
<bmx-json-editor label="Settings" name="settings"
value='{"name":"Acme","retries":3,"regions":["eu-west","us-east"]}'></bmx-json-editor>
Give it a JSON Schema (schema, 2020-12 or draft-07) and the document is
checked as it is edited: broken rules are marked on their rows and lines and
listed in a problems panel that takes you to each; the schema's titles and
descriptions show beside keys, enum values become choices, and new members
start from the schema's defaults. Nothing is fetched - $ref within the
schema is followed, other documents are not.
Search finds keys and values (case and accents ignored) and narrows the tree
to them; "Go to path" takes orders[3].total or /orders/3/total. The tree
draws only the rows in view, so a document of hundreds of thousands of
values opens and scrolls quickly. Every edit can be refused by cancelling
bmxEdit, and undone (Ctrl+Z) and redone (Ctrl+Y).
value takes a JavaScript value, or JSON text (as an attribute must); the
element writes back the same kind it was given. In a form, name receives
the document as text.
Tree keyboard: arrows move and open/close, Home/End, Page Up/Down, Enter edits the value (or opens a container), F2 renames, Space flips true/false, Delete deletes, Insert adds after, Alt+Up/Down move, Ctrl+D duplicates, Ctrl+C copies the value, Shift+F10 or the context-menu key opens actions.
Properties
| Property | Attribute | Type | Default | Description |
|---|---|---|---|---|
arrayKey |
array-key |
string |
— | A property that identifies array items (such as id), so changes match items by it rather than by place. |
compareWith |
property only | unknown |
— | Another version of the document (value or JSON text) for the Changes view and the marks in the tree. |
description |
description |
string |
— | Help text below the editor. |
disabled |
disabled |
boolean |
false |
Disable the editor. |
errorText |
error-text |
string |
— | An error supplied by the page. |
expandDepth |
expand-depth |
number |
2 |
How many levels of the tree start open. |
hideLabel |
hide-label |
boolean |
false |
Hide the label visually while keeping it as the accessible name. |
hideStatus |
hide-status |
boolean |
false |
Hide the status bar. |
hideToolbar |
hide-toolbar |
boolean |
false |
Hide the toolbar. |
indent |
indent |
number |
2 |
Spaces per level in the text (0 writes one line). |
label |
label |
string |
— | The field's label: names the whole control. |
name |
name |
string |
— | The field's name in a form: it receives the document as text. |
readonly |
readonly |
boolean |
false |
Allow reading, searching and copying, but not changing. |
schema |
schema |
BmxJsonSchema | string |
— | A JSON Schema (object or JSON text) the document is checked against. |
schemaMessages |
schema-messages |
Record<string, string> | string |
— | Schema messages in place of the English ones, by keyword (required, type, ...), as an object or JSON. |
search |
search |
string |
'' |
What the search box holds. Two-way. |
sortKeys |
sort-keys |
boolean |
false |
Sort object keys when writing the text. |
strings |
strings |
Partial<BmxJsonEditorStrings> | string |
— | Words to show instead of the English ones, as an object or JSON. |
value |
property only | unknown |
{} |
The document: any JavaScript value that is JSON, or JSON text. Two-way: written back in the kind it was given. |
view |
view |
BmxJsonEditorView |
'tree' |
The view shown. Two-way. |
views |
views |
BmxJsonEditorView[] | string |
— | The views offered, as an array, JSON or a comma list. Default: tree, text, table, and changes when compare-with is set. |
Events
| Event | Detail | Description |
|---|---|---|
bmxChange |
BmxJsonChangeDetail |
Fired after the document changes. |
bmxEdit |
BmxJsonEditDetail |
Fired before an edit. Cancel it to refuse the edit. |
bmxSelect |
BmxJsonSelectDetail |
Fired when the selected row changes. |
Methods
| Method | Signature | Description |
|---|---|---|
collapseAll |
collapseAll() => Promise<void> |
Closes every container but the root. |
expandAll |
expandAll(depth?: number) => Promise<void> |
Opens every container (up to 5,000), or down to depth levels. |
getChanges |
getChanges() => Promise<BmxJsonChange[]> |
The changes from compare-with to the current document. |
getSelection |
getSelection() => Promise<BmxJsonSelectDetail> |
The selected place and its value. |
getText |
getText(indent?: number) => Promise<string> |
The document as text; indent defaults to the element's. |
getValue |
getValue() => Promise<BmxJsonValue> |
The document as a value (the last one that could be read, if the text has a mistake). |
redo |
redo() => Promise<boolean> |
Redoes the last undone edit. |
select |
select(path: BmxJsonPath | string) => Promise<boolean> |
Selects a place - a path array, a JSON Pointer or orders[3].total - opening its ancestors and scrolling to it. Returns false when there is nothing there. |
setFocus |
setFocus() => Promise<void> |
Moves focus into the current view. |
setValue |
setValue(value: unknown, options?: { keepHistory?: boolean; }) => Promise<void> |
Replaces the document. keepHistory lets the reader undo back to the previous one. |
undo |
undo() => Promise<boolean> |
Undoes the last edit. |
validate |
validate() => Promise<BmxJsonSchemaProblem[]> |
Schema problems in the current document. |
Slots
| Slot | Description |
|---|---|
description |
Rich help text, in place of the description property. |
label |
Rich label content, in place of the label property. |
CSS shadow parts
| Part | Description |
|---|---|
changes |
The list of changes. |
description |
The help text under the field. |
key |
A key in a row. |
label |
The label element. |
menu |
The actions menu. |
problems |
The problems panel. |
row |
A tree row; also row-selected, row-problem, row-added, row-changed. |
status |
The bar under the views. |
table |
The table view. |
toolbar |
The bar of views, search and commands. |
tree |
The tree. |
value |
A value in a row. |
CSS custom properties
| Property | Description |
|---|---|
--bmx-json-editor-background |
The views' background. |
--bmx-json-editor-height |
The height of the views' scrolling area. |
--bmx-json-editor-indent |
How far each level of the tree is indented. |
--bmx-json-editor-key-color |
Keys in the tree. |
--bmx-json-editor-label-font-size |
The label's font size. |
--bmx-json-editor-literal-color |
true, false and null. |
--bmx-json-editor-number-color |
Number values. |
--bmx-json-editor-radius |
Corner radius of the frame. |
--bmx-json-editor-row-height |
The height of one tree or table row. |
--bmx-json-editor-selected-background |
The selected row. |
--bmx-json-editor-string-color |
String values. |
--bmx-json-editor-support-font-size |
Font size of the description and error message. |