Skip to main content

J2CommerceImage Form Field

J2CommerceImageField is a lightweight inline image picker for J2Commerce admin forms. It renders a row of fixed-size thumbnails with an Add Image button that opens a Bootstrap 5 modal containing an Uppy upload zone and a server-side image browser. Unlike MultiImageUploaderField, which is a full-featured drag-and-drop gallery widget with sort handles, alt-text editing, and an image editor, J2CommerceImageField stays compact — it is suited for single-image fields (product thumbnail, brand logo) or small multi-image sets where the form needs to remain uncluttered.

Architecture​

Key Classes​

ClassFilePurpose
J2CommerceImageFieldadministrator/components/com_j2commerce/src/Field/J2CommerceImageField.phpPHP form field — resolves attributes, normalizes value, renders layout
MultiImageUploaderFieldadministrator/components/com_j2commerce/src/Field/MultiImageUploaderField.phpProvides loadAssetsStatic() — shared Uppy bundle
J2CommerceImagePickermedia/com_j2commerce/js/admin/j2commerceimage.jsVanilla JS class — modal, browser grid, Uppy init, thumbnail strip

XML Attributes​

Declare these attributes directly on the <field> element in your form XML.

AttributeTypeDefaultDescription
multipleboolfalseAllow selecting more than one image. Single mode stores a plain string; multiple mode stores a JSON array.
maxint0Maximum images selectable when multiple="true". 0 means unlimited. The choose button is hidden automatically once the cap is reached.
thumbnail_heightint80Height (and width) of the inline thumbnail squares in pixels. Sets the --j2img-thumb-size CSS custom property on the wrapper.
directorystringimagesDefault directory opened in the image browser. Also sets the Uppy upload destination. Persisted per field via sessionStorage.
max_file_sizeint0Maximum upload size in MB. 0 falls back to the component setting image_max_file_size (default 10 MB).
client_compressionboolcomponent settingWhen true, the Uppy Compressor plugin converts uploads to WebP at 80% quality before sending. Falls back to image_client_compression.
auto_thumbnailboolcomponent settingWhen true, the server generates a thumbnail after upload. Falls back to image_auto_thumbnail.
acceptstringimage/*MIME type restriction passed to Uppy's allowedFileTypes. Use a comma-separated list for multiple types, e.g. image/jpeg,image/png.
preview_stylestringsquaresquare renders thumbnails with object-fit: cover (fills the box). contain uses object-fit: contain (shows the full image with letterboxing).

Standard Joomla FormField attributes (label, description, required, disabled, readonly, filter, class, default) also apply.

Value Format​

The field stores its value as a single hidden <input type="hidden">. The format differs between modes.

Single mode (multiple="false", the default):

images/products/my-product.jpg

The value is a plain relative path string. An empty field stores an empty string.

Multiple mode (multiple="true"):

["images/products/front.jpg","images/products/back.jpg"]

The value is a JSON-encoded array of path strings. An empty field stores [].

When reading the value in PHP, check the mode and decode accordingly:

// File: your-plugin-or-model.php

$rawValue = $form->getValue('my_image_field');

// Single
$imagePath = (string) $rawValue;

// Multiple
$images = json_decode((string) $rawValue, true) ?? [];

Usage Examples​

Single Image Field​

<!-- File: administrator/components/com_yourplugin/forms/item.xml -->

<field
name="thumbnail"
type="J2CommerceImage"
addfieldprefix="J2Commerce\Component\J2commerce\Administrator\Field"
label="COM_YOURPLUGIN_FIELD_THUMBNAIL_LABEL"
description="COM_YOURPLUGIN_FIELD_THUMBNAIL_DESC"
directory="images/products"
thumbnail_height="100"
/>

Multiple Images with a Cap​

<field
name="gallery"
type="J2CommerceImage"
addfieldprefix="J2Commerce\Component\J2commerce\Administrator\Field"
label="COM_YOURPLUGIN_FIELD_GALLERY_LABEL"
multiple="true"
max="5"
directory="images/gallery"
thumbnail_height="80"
preview_style="contain"
/>

Inside a Subform​

The field initialises via the joomla:updated DOM event, which Joomla fires each time a subform row is added. No extra wiring is needed.

<field name="slides" type="subform" multiple="true" layout="joomla.form.field.subform.repeatable">
<form>
<field
name="image"
type="J2CommerceImage"
addfieldprefix="J2Commerce\Component\J2commerce\Administrator\Field"
label="COM_YOURPLUGIN_FIELD_SLIDE_IMAGE_LABEL"
directory="images/slides"
/>
<field name="caption" type="text" label="COM_YOURPLUGIN_FIELD_CAPTION_LABEL" />
</form>
</field>

In a J2Commerce App Plugin XML​

<!-- File: plugins/j2commerce/app_yourplugin/config.xml -->

<?xml version="1.0" encoding="UTF-8"?>
<config>
<fields name="params">
<fieldset name="basic" label="COM_PLUGINS_BASIC_FIELDSET_LABEL">
<field
name="logo"
type="J2CommerceImage"
addfieldprefix="J2Commerce\Component\J2commerce\Administrator\Field"
label="PLG_J2COMMERCE_APP_YOURPLUGIN_FIELD_LOGO_LABEL"
directory="images/plugins"
thumbnail_height="64"
/>
</fieldset>
</fields>
</config>

Registering the Field Namespace​

Because J2CommerceImageField lives in the J2Commerce component namespace, any form that uses it outside that component must declare addfieldprefix. Add it either per-field (as in the examples above) or on the root <form> element:

<form addfieldprefix="J2Commerce\Component\J2commerce\Administrator\Field">
<fieldset name="basic">
<field name="image" type="J2CommerceImage" label="..." />
</fieldset>
</form>

No additional service provider registration is required. Joomla's form system resolves the class through the PSR-4 autoloader.

Comparison with MultiImageUploader​

FeatureJ2CommerceImageMultiImageUploader
Primary use caseCompact inline picker, single or small setFull product image gallery
Single-image modeYes (default)No — always multiple
Sort / reorderNoYes — drag handles
Alt text editingNoYes
Image editor (crop/rotate)NoYes
Thumbnail stripInline in form rowFull grid within the field
Choose button hidden at capYesN/A
Suitable for subformsYesNot recommended
Asset bundleShared Uppy bundle + own JS/CSSShared Uppy bundle + own JS/CSS

Use J2CommerceImage when the form design calls for a compact single-image picker or a small curated set. Use MultiImageUploader for the product image gallery where sorting and alt-text management matter.

CSS Customisation​

All visual sizing is driven by a single CSS custom property set inline on the .j2commerce-image-field wrapper:

--j2img-thumb-size: 80px;   /* set from thumbnail_height attribute */

Override it in your own stylesheet or inline via a Joomla form layout override:

/* Make all image fields in a specific form larger */
#your-form .j2commerce-image-field {
--j2img-thumb-size: 120px;
}

The preview_style attribute controls object-fit:

/* default — square crop */
.j2commerce-image-thumb img {
object-fit: cover;
}

/* preview_style="contain" — letterboxed */
.j2commerce-image-thumb.preview-contain img {
object-fit: contain;
}

The remove button (×) appears on hover. Dark mode is handled automatically via prefers-color-scheme: dark.

Asset Loading​

J2CommerceImageField::loadAssets() calls MultiImageUploaderField::loadAssetsStatic() first (guarded by a static flag, so assets load only once per page), then registers its own assets:

Asset nameFileNotes
com_j2commerce.uppy.cssmedia/com_j2commerce/css/uppy/uppy.min.cssUppy base styles
com_j2commerce.multiimageuploader.cssmedia/com_j2commerce/css/administrator/multiimageuploader.cssModal / browser grid styles
com_j2commerce.uppy.jsmedia/com_j2commerce/js/uppy/uppy.min.jsUppy bundle
com_j2commerce.multiimageuploader.jsmedia/com_j2commerce/js/admin/multiimageuploader.jsFull uploader JS (deferred, type=module)
com_j2commerce.j2commerceimage.cssmedia/com_j2commerce/css/administrator/j2commerceimage.cssThumbnail strip styles
com_j2commerce.j2commerceimage.jsmedia/com_j2commerce/js/admin/j2commerceimage.jsJ2CommerceImagePicker class (deferred)

Both J2CommerceImage and MultiImageUploader fields can appear on the same page without loading Uppy twice.

JavaScript API​

The J2CommerceImagePicker class is exposed on window.J2CommerceImagePicker for programmatic access. Each .j2commerce-image-field element stores its instance at element._j2imgPicker.

// Get the picker instance for a specific field
const wrapper = document.getElementById('jform_thumbnail-wrapper');
const picker = wrapper?._j2imgPicker;

// Read the current selection (array of paths)
console.log(picker.selectedPaths);

// Programmatically set a value and re-render
picker.selectedPaths = ['images/products/override.jpg'];
picker.updateHiddenInput();
picker.renderThumbnails();
picker.updateChooseButton();

The class also re-initialises on the joomla:updated event, so it works correctly inside repeatable subforms.

Upload Endpoint​

Uploads go through the shared multiimageuploader controller task:

POST index.php?option=com_j2commerce&task=multiimageuploader.upload&format=json

The path meta field sets the upload directory. autoThumbnail=1 triggers server-side thumbnail generation. CSRF protection is appended automatically by the JS class.