Skip to main content

Events

Editor42 fires events throughout the editor lifecycle, letting you react to user actions, content changes, UI updates, and more. Use editor.on() to subscribe and editor.off() to unsubscribe.

editor42.init({
selector: '#myeditor',
setup: (editor) => {
editor.on('init', () => {
console.log('Editor is ready');
});

editor.on('change', (e) => {
console.log('Content changed', e.level);
});
}
});

Every event callback receives an event object. Custom editor events include a preventDefault() method that some events check to cancel default behavior.

Lifecycle​

EventPayloadDescription
init{}Editor initialization completes.
remove{}Editor is removed from the page.
detach{}Editor is detached.
PreInit{}Before editor initialization.
PostRender{}After editor renders.
ScriptsLoaded{}All scripts are loaded.
SkinLoaded{}Editor skin is loaded.
SkinLoadError{ message: string }Skin load failure.
PluginLoadError{ message: string }Plugin load failure.
ModelLoadError{ message: string }Model load failure.
IconsLoadError{ message: string }Icon pack load failure.
ThemeLoadError{ message: string }Theme load failure.
LanguageLoadError{ message: string }Language pack load failure.

Focus​

EventPayloadDescription
focus{ blurredEditor: Editor | null }Editor receives DOM focus.
blur{ focusedEditor: Editor | null }Editor loses DOM focus.
activate{ relatedTarget: Editor | null }Editor gains focus in a multi-editor setup.
deactivate{ relatedTarget: Editor }Editor loses focus in a multi-editor setup.

Content​

EventPayloadDescription
BeforeGetContent{ selection?: boolean }Before content is retrieved.
GetContent{ content: string; selection?: boolean }Content is retrieved.
BeforeSetContent{ content: string; selection?: boolean }Before content is set.
SetContent{ content: string }After content is set. content is deprecated.
SaveContent{ content: string; save: boolean }Content is saved.
RawSaveContent{ content: string; save: boolean }Raw save content event.
LoadContent{ load: boolean; element: HTMLElement }Content is loaded into the editor.
NewBlock{ newBlock: Element }A new block element is created (e.g., pressing Enter).

Selection & Node​

EventPayloadDescription
NodeChange{ element: Element; parents: Node[]; selectionChange?: boolean; initial?: boolean }Cursor moves or DOM changes.
SelectionChange{}Selection changes.
GetSelectionRange{ range: Range }Getting selection range.
SetSelectionRange{ range: Range; forward: boolean | undefined }Selection range is set.
AfterSetSelectionRange{ range: Range; forward: boolean | undefined }After selection range is set.
ObjectSelected{ target: Node; targetClone?: Node }An object (image, table, etc.) is selected.
BeforeObjectSelected{ target: Node; targetClone?: Node }Before an object is selected.

Commands​

EventPayloadDescription
BeforeExecCommand{ command: string; ui: boolean; value?: any }Before a command executes.
ExecCommand{ command: string; ui: boolean; value?: any }After a command executes.

Formatting​

EventPayloadDescription
FormatApply{ format: string; vars?: FormatVars; node?: Node | RangeLikeObject | null }A format is applied.
FormatRemove{ format: string; vars?: FormatVars; node?: Node | RangeLikeObject | null }A format is removed.
PreviewFormats{}Before format previews.
AfterPreviewFormats{}After format previews.

Undo/Redo​

EventPayloadDescription
BeforeAddUndo{ level: UndoLevel; lastLevel: UndoLevel | undefined; originalEvent: Event | undefined }Before an undo level is added.
AddUndo{ level: UndoLevel; lastLevel: UndoLevel | undefined; originalEvent: Event | undefined }Undo level is added.
Undo{ level: UndoLevel }Undo is performed.
Redo{ level: UndoLevel }Redo is performed.
ClearUndos{}Undo history is cleared.
TypingUndo{}Typing undo level.
change{ level: UndoLevel; lastLevel: UndoLevel | undefined }Content changes.

UI & Resize​

EventPayloadDescription
ScrollIntoView{ elm: HTMLElement; alignToTop: boolean | undefined }Scrolling element into view.
AfterScrollIntoView{ elm: HTMLElement; alignToTop: boolean | undefined }After scroll into view.
ObjectResizeStart{ target: HTMLElement; width: number; height: number; origin: string }Object resize starts.
ObjectResized{ target: HTMLElement; width: number; height: number; origin: string }Object is resized.
ShowCaret{ target: Node; direction: number; before: boolean }Caret is shown.
SwitchMode{ mode: string }Editor mode changes (e.g., "design" or "readonly").
ProgressState{ state: boolean; time?: number }Progress state changes.
AfterProgressState{ state: boolean }After progress state.
PlaceholderToggle{ state: boolean }Placeholder visibility changes.
ScrollWindownative EventWindow scroll.
ResizeWindowUIEventWindow resize.
resizeUIEventEditor resize.
scrollUIEventEditor scroll.

Window & Dialog​

EventPayloadDescription
OpenWindow{ dialog: InstanceApi }A dialog is opened.
CloseWindow{ dialog: InstanceApi }A dialog is closed.
BeforeOpenNotification{ notification: NotificationSpec }Before a notification opens.
OpenNotification{ notification: NotificationApi }A notification opens.

Input & Touch​

EventPayloadDescription
inputInputEventInput occurs.
beforeinputInputEventBefore input occurs.
tapTouchEventTouch tap.
longpressTouchEventLong press.
longpresscancel{}Long press is cancelled.

Paste​

EventPayloadDescription
PastePlainTextToggle{ state: boolean }Paste-as-text mode toggles.
PastePreProcess{ content: string; readonly internal: boolean }Before paste content is processed.
PastePostProcess{ node: HTMLElement; readonly internal: boolean }After paste content is processed.

Autocomplete​

EventPayloadDescription
AutocompleterStartAutocompleterEventArgsAutocomplete starts.
AutocompleterUpdateAutocompleterEventArgsAutocomplete updates.
AutocompleterEnd{}Autocomplete ends.

Table​

These events are provided by the Table plugin.

EventPayloadDescription
TableModified{ table: HTMLTableElement; structure: boolean; style: boolean }A table is modified.
NewRow{ node: HTMLTableRowElement }A new table row is created.
NewCell{ node: HTMLTableCellElement }A new table cell is created.

DOM​

EventPayloadDescription
SetAttribSetAttribEventAn attribute is set on an element.
PreProcess{ node: Element } (extends ParserArgs)During pre-processing.
PostProcess{ content: string } (extends ParserArgs)During post-processing.

Visibility​

EventPayloadDescription
show{}Editor is shown.
hide{}Editor is hidden.
dirty{}Editor becomes dirty (content modified since last save).

EditorManager Events​

These events are fired on the global editor42 object rather than on individual editor instances. Use editor42.on() to subscribe.

EventPayloadDescription
AddEditor{ editor: Editor }An editor instance is added.
RemoveEditor{ editor: Editor }An editor instance is removed.
BeforeUnload{ returnValue: any }Before page unload.
editor42.on('AddEditor', (e) => {
console.log('New editor added:', e.editor.id);
});

Examples​

Reacting to content changes​

editor42.init({
selector: '#myeditor',
setup: (editor) => {
editor.on('change', (e) => {
// Auto-save or update a preview
const content = editor.getContent();
fetch('/api/drafts', {
method: 'POST',
body: JSON.stringify({ content }),
headers: { 'Content-Type': 'application/json' }
});
});
}
});

Intercepting paste​

editor42.init({
selector: '#myeditor',
setup: (editor) => {
editor.on('PastePreProcess', (e) => {
// Strip all images from pasted content
e.content = e.content.replace(/<img[^>]*>/gi, '');
});
}
});

Tracking format changes​

editor42.init({
selector: '#myeditor',
setup: (editor) => {
editor.on('FormatApply', (e) => {
console.log('Format applied:', e.format);
});

editor.on('FormatRemove', (e) => {
console.log('Format removed:', e.format);
});
}
});

Responding to node selection​

editor42.init({
selector: '#myeditor',
setup: (editor) => {
editor.on('NodeChange', (e) => {
// Update external UI based on the current node
const isInTable = e.parents.some(
(node) => node.nodeName === 'TABLE'
);
document.getElementById('table-tools').hidden = !isInTable;
});
}
});

Handling load errors​

editor42.init({
selector: '#myeditor',
setup: (editor) => {
const errorEvents = [
'SkinLoadError',
'PluginLoadError',
'ThemeLoadError',
'LanguageLoadError',
'IconsLoadError',
'ModelLoadError'
];

errorEvents.forEach((event) => {
editor.on(event, (e) => {
console.error(`${event}: ${e.message}`);
});
});
}
});