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
| Event | Payload | Description |
|---|---|---|
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
| Event | Payload | Description |
|---|---|---|
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
| Event | Payload | Description |
|---|---|---|
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
| Event | Payload | Description |
|---|---|---|
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
| Event | Payload | Description |
|---|---|---|
BeforeExecCommand | { command: string; ui: boolean; value?: any } | Before a command executes. |
ExecCommand | { command: string; ui: boolean; value?: any } | After a command executes. |
Formatting
| Event | Payload | Description |
|---|---|---|
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
| Event | Payload | Description |
|---|---|---|
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
| Event | Payload | Description |
|---|---|---|
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. |
ScrollWindow | native Event | Window scroll. |
ResizeWindow | UIEvent | Window resize. |
resize | UIEvent | Editor resize. |
scroll | UIEvent | Editor scroll. |
Window & Dialog
| Event | Payload | Description |
|---|---|---|
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
| Event | Payload | Description |
|---|---|---|
input | InputEvent | Input occurs. |
beforeinput | InputEvent | Before input occurs. |
tap | TouchEvent | Touch tap. |
longpress | TouchEvent | Long press. |
longpresscancel | {} | Long press is cancelled. |
Paste
| Event | Payload | Description |
|---|---|---|
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
| Event | Payload | Description |
|---|---|---|
AutocompleterStart | AutocompleterEventArgs | Autocomplete starts. |
AutocompleterUpdate | AutocompleterEventArgs | Autocomplete updates. |
AutocompleterEnd | {} | Autocomplete ends. |
Table
These events are provided by the Table plugin.
| Event | Payload | Description |
|---|---|---|
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
| Event | Payload | Description |
|---|---|---|
SetAttrib | SetAttribEvent | An attribute is set on an element. |
PreProcess | { node: Element } (extends ParserArgs) | During pre-processing. |
PostProcess | { content: string } (extends ParserArgs) | During post-processing. |
Visibility
| Event | Payload | Description |
|---|---|---|
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.
| Event | Payload | Description |
|---|---|---|
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}`);
});
});
}
});