Image Properties Plugin
- Features
- image
- Basic Usage
- Minimal Configuration
- With Predefined Classes
- Disable Double-Click
- Custom Dialog Width
- Open Programmatically
- Without Image Editor
- Prevent Selection After Close
- Listen to Dialog Events
- Complete Configuration Example
- Plugin Initialization
- Double-Click Behavior
- Dialog Structure
- Form State Management
- Value Reading
- Value Writing
- Aspect Ratio Lock
- Margin Lock
- Image Source Change
- Image Editor Integration
- File Browser Integration
- Delete Image
- Selection After Close
- openImageProperties
- openOnDblClick
- updateImageProperties.imageproperties
- Material-UI Dialog Focus Issue
- Edge Cases
- Notes
- Classes
- Interfaces
Provides an image properties dialog for editing image attributes and styles. This plugin opens a comprehensive dialog when users double-click on images, allowing them to modify source, dimensions, margins, alignment, links, and other properties.
Features
- Image properties dialog with tabbed interface
- Edit image source (URL)
- Edit image dimensions with aspect ratio locking
- Edit margins with synchronized margins option
- Set border radius
- Configure image link and link behavior
- Edit image title and alt text
- Assign CSS classes from predefined list
- Set custom styles
- Edit element ID
- Configure image alignment
- Live preview of changes
- Integration with image editor for cropping/resizing
- File browser integration for changing image source
- Double-click to open dialog
- Preserve aspect ratio option
- Delete image from dialog
image
Type: ImagePropertiesOptions
Configuration object for image properties dialog.
image.dialogWidth
Type: number
Default: 600
Sets the width of the image properties dialog in pixels.
Example:
const editor = Jodit.make('#editor', {
image: {
dialogWidth: 800
}
});
image.openOnDblClick
Type: boolean
Default: true
Opens the image properties dialog when user double-clicks on an image.
Example:
const editor = Jodit.make('#editor', {
image: {
openOnDblClick: true
}
});
image.editSrc
Type: boolean
Default: true
Shows the image source URL input field in the dialog.
Example:
const editor = Jodit.make('#editor', {
image: {
editSrc: true
}
});
image.useImageEditor
Type: boolean
Default: true
Shows the crop/resize button that opens the image editor.
Example:
const editor = Jodit.make('#editor', {
image: {
useImageEditor: true
}
});
image.editTitle
Type: boolean
Default: true
Shows the image title input field.
Example:
const editor = Jodit.make('#editor', {
image: {
editTitle: true
}
});
image.editAlt
Type: boolean
Default: true
Shows the alternative text (alt) input field for accessibility.
Example:
const editor = Jodit.make('#editor', {
image: {
editAlt: true
}
});
image.editLink
Type: boolean
Default: true
Shows image link options including URL and "open in new tab" checkbox.
Example:
const editor = Jodit.make('#editor', {
image: {
editLink: true
}
});
image.editSize
Type: boolean
Default: true
Shows width and height input fields with aspect ratio lock option.
Example:
const editor = Jodit.make('#editor', {
image: {
editSize: true
}
});
image.editBorderRadius
Type: boolean
Default: true
Shows border radius input field.
Example:
const editor = Jodit.make('#editor', {
image: {
editBorderRadius: true
}
});
image.editMargins
Type: boolean
Default: true
Shows margin input fields (top, right, bottom, left) with margin lock option.
Example:
const editor = Jodit.make('#editor', {
image: {
editMargins: true
}
});
image.editClass
Type: boolean
Default: true
Shows CSS class name input/selector.
Example:
const editor = Jodit.make('#editor', {
image: {
editClass: true
}
});
image.availableClasses
Type: [string, string][] | string[]
Default: []
Pre-defined list of CSS classes available for selection. Can be provided as simple string array or as array of tuples [className, humanLabel]
for custom labels.
Example:
// Simple string array
const editor = Jodit.make('#editor', {
image: {
availableClasses: [
'img-responsive',
'img-thumbnail',
'img-rounded'
]
}
});
// With human-readable labels
const editor = Jodit.make('#editor', {
image: {
availableClasses: [
['img-small', 'Small (300px)'],
['img-medium', 'Medium (600px)'],
['img-large', 'Large (900px)'],
['img-full', 'Full Width']
]
}
});
image.editStyle
Type: boolean
Default: true
Shows custom CSS style input field.
Example:
const editor = Jodit.make('#editor', {
image: {
editStyle: true
}
});
image.editId
Type: boolean
Default: true
Shows element ID input field.
Example:
const editor = Jodit.make('#editor', {
image: {
editId: true
}
});
image.editAlign
Type: boolean
Default: true
Shows alignment selector (left, center, right, etc.).
Example:
const editor = Jodit.make('#editor', {
image: {
editAlign: true
}
});
image.showPreview
Type: boolean
Default: true
Shows live preview of the image in the dialog.
Example:
const editor = Jodit.make('#editor', {
image: {
showPreview: true
}
});
image.selectImageAfterClose
Type: boolean
Default: true
Automatically selects the image after closing the properties dialog.
Example:
const editor = Jodit.make('#editor', {
image: {
selectImageAfterClose: true
}
});
Basic Usage
The plugin is enabled by default:
const editor = Jodit.make('#editor');
editor.value = '<p><img src="photo.jpg" alt="Photo"></p>';
// Double-click on image to open properties dialog
Minimal Configuration
Show only essential fields:
const editor = Jodit.make('#editor', {
image: {
editSrc: true,
editAlt: true,
editSize: true,
editTitle: false,
editLink: false,
editBorderRadius: false,
editMargins: false,
editClass: false,
editStyle: false,
editId: false,
editAlign: false,
useImageEditor: false
}
});
With Predefined Classes
const editor = Jodit.make('#editor', {
image: {
availableClasses: [
['responsive', 'Responsive Image'],
['thumbnail', 'Thumbnail'],
['rounded', 'Rounded Corners'],
['shadow', 'With Shadow']
]
}
});
Disable Double-Click
Require manual opening instead of double-click:
const editor = Jodit.make('#editor', {
image: {
openOnDblClick: false
}
});
// Open programmatically
const img = editor.editor.querySelector('img');
if (img) {
editor.e.fire('openImageProperties', img);
}
Custom Dialog Width
const editor = Jodit.make('#editor', {
image: {
dialogWidth: 900
}
});
Open Programmatically
const editor = Jodit.make('#editor');
// Insert image
editor.s.insertImage('photo.jpg');
// Get the image element
const img = editor.editor.querySelector('img');
// Open properties dialog
editor.e.fire('openImageProperties', img);
Without Image Editor
Disable crop/resize functionality:
const editor = Jodit.make('#editor', {
image: {
useImageEditor: false
}
});
Prevent Selection After Close
const editor = Jodit.make('#editor', {
image: {
selectImageAfterClose: false
}
});
Listen to Dialog Events
const editor = Jodit.make('#editor');
// Listen for double-click event
editor.e.on('openOnDblClick', (image) => {
console.log('Opening properties for:', image.src);
// Return false to prevent opening
// return false;
});
// Listen for image property updates
editor.e.on('updateImageProperties.imageproperties', (image) => {
console.log('Image properties updated:', image);
});
Complete Configuration Example
const editor = Jodit.make('#editor', {
image: {
dialogWidth: 700,
openOnDblClick: true,
editSrc: true,
useImageEditor: true,
editTitle: true,
editAlt: true,
editLink: true,
editSize: true,
editBorderRadius: true,
editMargins: true,
editClass: true,
availableClasses: [
['img-fluid', 'Fluid (100% width)'],
['img-50', '50% width'],
['img-rounded', 'Rounded Corners'],
['img-circle', 'Circle'],
['img-shadow', 'Drop Shadow']
],
editStyle: true,
editId: true,
editAlign: true,
showPreview: true,
selectImageAfterClose: true
}
});
Plugin Initialization
- Event Binding: Attaches
dblclick
event handler to editor - State Management: Initializes internal state for form values
- Dialog Creation: Creates cached dialog with form and buttons
- Tab State: Manages active tab ('Image' or 'Advanced')
Double-Click Behavior
When user double-clicks on an image:
- Event Capture:
dblclick
event oneditor.editor
element - Target Validation: Checks if target is
<img>
element - Option Check: Verifies
openOnDblClick
istrue
- Event Hook: Fires
openOnDblClick
event (can returnfalse
to cancel) - State Setup: Clones image and stores as
sourceImage
andimage
- Dialog Open: Opens properties dialog
Dialog Structure
The dialog consists of:
- Header: "Image properties" title
- Content: Tabbed form with two tabs:
- Image Tab: Source, dimensions, alignment, link, alt, title
- Advanced Tab: Margins, border radius, class, ID, style
- Footer: Three buttons:
- Cancel: Closes dialog without changes
- Delete: Removes image from editor
- Apply: Applies changes to image
Form State Management
The plugin maintains state in ImagePropertiesState
:
{
image: HTMLImageElement, // Working copy
sourceImage: HTMLImageElement, // Original image in editor
ratio: number, // Natural width / height
sizeIsLocked: boolean, // Aspect ratio lock
marginIsLocked: boolean, // Margin sync lock
values: {
style: string,
imageSrc: string,
borderRadius: number,
imageTitle: string,
imageAlt: string,
imageLink: string,
imageLinkOpenInNewTab: boolean,
imageWidth: number | string,
imageHeight: number | string,
marginTop: number | string,
marginRight: number | string,
marginBottom: number | string,
marginLeft: number | string,
classes: string,
id: string,
align: ImageHAlign
}
}
Value Reading
When dialog opens:
- Lock Dialog: Disables all inputs and buttons
- Read Values: Calls
readValuesFromImage()
:- Extracts all properties from the image element
- Parses styles, attributes, dimensions
- Populates form state
- Image Decode: Waits for
image.decode()
to complete - Aspect Ratio: Calculates and applies aspect ratio if locked
- Unlock Dialog: Enables inputs and buttons
Value Writing
When user clicks Apply:
- Apply Changes: Calls
applyValuesToImage()
- Updates image attributes (src, alt, title, id)
- Sets dimensions
- Applies margins
- Sets border radius
- Updates or creates link wrapper
- Sets alignment
- Applies custom styles
- Sets CSS classes
- Synchronize: Calls
editor.synchronizeValues()
- Close Dialog: Closes the dialog
Aspect Ratio Lock
When sizeIsLocked
is true:
- Width Change: Automatically adjusts height:
height = width / ratio
- Height Change: Automatically adjusts width:
width = height * ratio
- Watch Decorator: Uses
@watch('state.image')
to monitor changes - Live Update: Changes apply in real-time to preview
Margin Lock
When marginIsLocked
is true:
- All four margin fields are synchronized
- Changing one updates all others to match
Image Source Change
When image source URL changes:
- Update Working Copy: Sets
image.src
to new URL - Lock Dialog: Disables controls during load
- Image Decode: Waits for new image to load
- Recalculate Dimensions: If aspect ratio locked, updates dimensions
- Fire Event: Triggers
updateImageProperties.imageproperties
- Unlock Dialog: Re-enables controls
Image Editor Integration
When crop/resize button clicked:
- Opens: Separate image editor dialog (if
useImageEditor
is true) - Allows: Cropping, resizing, rotating
- Updates: Image source after editing
File Browser Integration
When file browser button clicked:
- Opens: File selector popup
- Allows: Selection from server files
- Updates: Image source with selected file URL
Delete Image
When delete button clicked:
- Remove: Calls
editor.s.removeNode(sourceImage)
- Close: Closes dialog
Selection After Close
If selectImageAfterClose
is true
:
- Check: Verifies image still exists in document
- Select: Calls
editor.s.select(sourceImage)
openImageProperties
Fired to programmatically open the image properties dialog.
Handler signature:
(image: HTMLImageElement) => void
Example:
const img = editor.editor.querySelector('img');
editor.e.fire('openImageProperties', img);
openOnDblClick
Fired before opening dialog on double-click. Return false
to cancel.
Handler signature:
(image: HTMLImageElement) => false | void
Example:
editor.e.on('openOnDblClick', (image) => {
if (image.hasAttribute('data-locked')) {
alert('This image is locked');
return false; // Prevent opening
}
});
updateImageProperties.imageproperties
Fired after image properties are updated (e.g., after changing source).
Handler signature:
(image: HTMLImageElement) => void
Example:
editor.e.on('updateImageProperties.imageproperties', (image) => {
console.log('Image updated:', image.src);
});
Material-UI Dialog Focus Issue
When using Jodit inside a Material-UI (MUI) modal/dialog, the image properties dialog may not allow focusing input fields. This occurs because MUI's Modal
component enforces focus within itself.
Solution:
Enable the disableEnforceFocus
prop on the MUI Modal/Dialog:
<Dialog
open={open}
disableEnforceFocus={true} // Allow focus outside
>
<div id="editor"></div>
</Dialog>
Reference: GitHub Issue #879
Edge Cases
-
Image Outside Editor: Plugin only handles images inside
editor.editor
element -
Readonly Mode: Dialog doesn't open in readonly mode, but image is still selected
-
No Double-Click: If
openOnDblClick
isfalse
, double-clicking only selects the image -
Missing Image: If source image is removed from DOM before closing dialog, selection is skipped
-
Dialog Dimensions: Dialog has
minWidth: min(400, screen.width)
andminHeight: 590
-
Image Decode Error: If new image fails to load, error is shown in dialog
-
Aspect Ratio: Natural dimensions are used for ratio calculation, not display dimensions
-
State Isolation: Each dialog opening uses fresh state cloned from the source image
-
Form Validation: Form validates before allowing submission
-
Event Namespacing: All events use
.imageproperties
namespace for clean removal
Notes
- The plugin uses
@cache
decorator to create dialog and buttons only once - Dialog is modal and can be maximized to fullsize
- Form includes live preview that updates as properties change
- Changes are only applied when user clicks Apply button
- Cancel button discards all changes
- The plugin properly cleans up dialog, form, and buttons on destruction
- State is reactive - changing form values automatically updates preview
- Image is cloned before editing to allow cancellation without affecting original
- The dialog is reusable - same dialog instance for all images
- Tab state persists across different image edits (last used tab is remembered)
- Dialog positioning is automatic based on available screen space
- All event listeners use namespaced events (
.imageproperties
) for proper cleanup - The plugin integrates with Jodit's dialog system for consistent UI
- Available classes can have human-readable labels for better UX
- The dialog supports fullsize mode via fullsize button in header
Classes
Interfaces
EditValues
EditValues: Object
Type declaration
Name | Type |
---|---|
style |
string |
imageSrc |
string |
borderRadius |
number |
imageTitle |
string |
imageAlt |
string |
imageLink |
string |
imageLinkOpenInNewTab |
boolean |
imageWidth |
number | string |
imageHeight |
number | string |
marginTop |
number | string |
marginRight |
number | string |
marginBottom |
number | string |
marginLeft |
number | string |
classes |
string |
id |
string |
align |
ImageHAlign |
Defined in
jodit/src/plugins/image-properties/interface.d.ts:13