Magento 2 Add Image Uploader on Admin UI Form
In this article, we'll discuss how to add the UI Component image uploader field on the admin form in Magento 2. With the help of this image uploader, you can pick existing images from the gallery and reuse them.
We'll do the following things in this article.
- Add Image Uploader field on ui form xml file.
- Create controller for image uploader.
- Create Image uploader class.
- Get Save image using dataprovider.
Let's get started!!
Step 1: Add the below on your ui form xml file.
saveCopyzoom_out_map<field name="image_field">
<argument name="data" xsi:type="array">
<item name="config" xsi:type="array">
<item name="dataType" xsi:type="string">string</item>
<item name="label" xsi:type="string" translate="true">Your Image Field</item>
<item name="visible" xsi:type="boolean">true</item>
<item name="allowedExtensions" xsi:type="string">jpg jpeg png</item>
<item name="maxFileSize" xsi:type="number">2097152</item>
<item name="formElement" xsi:type="string">imageUploader</item>
<item name="previewTmpl" xsi:type="string">Magento_Catalog/image-preview</item>
<item name="elementTmpl" xsi:type="string">ui/form/element/uploader/uploader</item>
<item name="dataScope" xsi:type="string">image_field</item>
<item name="sortOrder" xsi:type="number">40</item>
<item name="uploaderConfig" xsi:type="array">
<item name="url" xsi:type="url" path="helloworld/index/upload">
<param name="target_element_id">image_field</param>
<param name="type">image</param>
</item>
</item>
<item name="validation" xsi:type="array">
<item name="required-entry" xsi:type="boolean">true</item>
</item>
</item>
</argument>
</field>
In above code you can see, we've used image_field as a field and helloworld/index/upload as an url path. So, you need to change it according to your. Now we need to create upload controller.
Step 2: Create Upload.php at app/code/Vendorname/Helloworld/Controller/Adminhtml/Index/ and paste the below code.
saveCopyzoom_out_map<?php
namespace Vendorname\Helloworld\Controller\Adminhtml\Index;
use Magento\Framework\Controller\ResultFactory;
class Upload extends \Magento\Backend\App\Action
{
/**
* @var \Vendorname\Helloworld\Model\ImageUploader
*/
public $imageUploader;
/**
* Upload constructor.
* @param \Magento\Backend\App\Action\Context $context
* @param \Vendorname\Helloworld\Model\ImageUploader $imageUploader
*/
public function __construct(
\Magento\Backend\App\Action\Context $context,
\Vendorname\Helloworld\Model\ImageUploader $imageUploader
) {
parent::__construct($context);
$this->imageUploader = $imageUploader;
}
/**
* @return mixed
*/
public function _isAllowed() {
return $this->_authorization->isAllowed('Vendorname_Helloworld::upload');
}
/**
* @return mixed
*/
public function execute() {
try {
$result = $this->imageUploader->saveFileToTmpDir('image_field');
$result['cookie'] = [
'name' => $this->_getSession()->getName(),
'value' => $this->_getSession()->getSessionId(),
'lifetime' => $this->_getSession()->getCookieLifetime(),
'path' => $this->_getSession()->getCookiePath(),
'domain' => $this->_getSession()->getCookieDomain(),
];
} catch (\Exception $e) {
$result = ['error' => $e->getMessage(), 'errorcode' => $e->getCode()];
}
return $this->resultFactory->create(ResultFactory::TYPE_JSON)->setData($result);
}
}
In the above code you need to change your field name with image_field. Also, we've inject imageUploader class for save image. So, need to create that.
Step 3: Create ImageUploader.php at app/code/Vendorname/Helloworld/Model/ImageUploader.php and paste the below code.
saveCopyzoom_out_map<?php
namespace Vendorname\Helloworld\Model;
use Exception;
use Magento\Framework\App\Filesystem\DirectoryList;
use Magento\Framework\Exception\LocalizedException;
use Magento\Framework\Exception\NoSuchEntityException;
use Magento\Framework\UrlInterface;
class ImageUploader
{
const BASE_TMP_PATH = "wysiwyg/helloworld/";
const BASE_PATH = "wysiwyg/helloworld/";
const ALLOWED_EXTENSIONS = ['jpg', 'jpeg', 'png'];
/**
* @var string
*/
public $baseTmpPath;
/**
* @var string
*/
public $basePath;
/**
* @var string[]
*/
public $allowedExtensions;
/**
* @var \Magento\MediaStorage\Helper\File\Storage\Database
*/
private $coreFileStorageDatabase;
/**
* @var \Magento\Framework\Filesystem\Directory\WriteInterface
*/
private $mediaDirectory;
/**
* @var \Magento\MediaStorage\Model\File\UploaderFactory
*/
private $uploaderFactory;
/**
* @var \Magento\Store\Model\StoreManagerInterface
*/
private $storeManager;
/**
* @var \Psr\Log\LoggerInterface
*/
private $logger;
/**
* ImageUploader constructor.
* @param \Magento\MediaStorage\Helper\File\Storage\Database $coreFileStorageDatabase
* @param \Magento\Framework\Filesystem $filesystem
* @param \Magento\MediaStorage\Model\File\UploaderFactory $uploaderFactory
* @param \Magento\Store\Model\StoreManagerInterface $storeManager
* @param \Psr\Log\LoggerInterface $logger
* @throws \Magento\Framework\Exception\FileSystemException
*/
public function __construct(
\Magento\MediaStorage\Helper\File\Storage\Database $coreFileStorageDatabase,
\Magento\Framework\Filesystem $filesystem,
\Magento\MediaStorage\Model\File\UploaderFactory $uploaderFactory,
\Magento\Store\Model\StoreManagerInterface $storeManager,
\Psr\Log\LoggerInterface $logger
) {
$this->coreFileStorageDatabase = $coreFileStorageDatabase;
$this->mediaDirectory = $filesystem->getDirectoryWrite(DirectoryList::MEDIA);
$this->uploaderFactory = $uploaderFactory;
$this->storeManager = $storeManager;
$this->logger = $logger;
$this->baseTmpPath = self::BASE_TMP_PATH;
$this->basePath = self::BASE_PATH;
$this->allowedExtensions = self::ALLOWED_EXTENSIONS;
}
/**
* @param $imageName
* @return mixed
* @throws LocalizedException
*/
public function moveFileFromTmp($imageName)
{
$baseTmpPath = $this->getBaseTmpPath();
$basePath = $this->getBasePath();
$baseImagePath = $this->getFilePath($basePath, $imageName);
$baseTmpImagePath = $this->getFilePath($baseTmpPath, $imageName);
try {
$this->coreFileStorageDatabase->copyFile(
$baseTmpImagePath,
$baseImagePath
);
$this->mediaDirectory->renameFile(
$baseTmpImagePath,
$baseImagePath
);
} catch (Exception $e) {
throw new LocalizedException(
__('Something went wrong while saving the file(s).')
);
}
return $imageName;
}
/**
* @return string
*/
public function getBaseTmpPath()
{
return $this->baseTmpPath;
}
/**
* @param $baseTmpPath
*/
public function setBaseTmpPath($baseTmpPath)
{
$this->baseTmpPath = $baseTmpPath;
}
/**
* @return string
*/
public function getBasePath()
{
return $this->basePath;
}
/**
* @param $basePath
*/
public function setBasePath($basePath)
{
$this->basePath = $basePath;
}
/**
* @param $path
* @param $imageName
* @return string
*/
public function getFilePath($path, $imageName)
{
return rtrim($path, '/') . '/' . ltrim($imageName, '/');
}
/**
* @param $fileId
* @return mixed
* @throws LocalizedException
* @throws NoSuchEntityException
*/
public function saveFileToTmpDir($fileId)
{
$baseTmpPath = $this->getBaseTmpPath();
$uploader = $this->uploaderFactory->create(['fileId' => $fileId]);
$uploader->setAllowedExtensions($this->getAllowedExtensions());
$uploader->setAllowRenameFiles(true);
$result = $uploader->save($this->mediaDirectory->getAbsolutePath($baseTmpPath));
if (!$result) {
throw new LocalizedException(
__('File can not be saved to the destination folder.')
);
}
$result['tmp_name'] = str_replace('\\', '/', $result['tmp_name']);
$result['path'] = str_replace('\\', '/', $result['path']);
$result['url'] = $this->storeManager
->getStore()
->getBaseUrl(
UrlInterface::URL_TYPE_MEDIA
) . $this->getFilePath($baseTmpPath, $result['file']);
$result['name'] = $result['file'];
if (isset($result['file'])) {
try {
$relativePath = rtrim($baseTmpPath, '/') . '/' . ltrim($result['file'], '/');
$this->coreFileStorageDatabase->saveFile($relativePath);
} catch (Exception $e) {
$this->logger->critical($e);
throw new LocalizedException(
__('Something went wrong while saving the file(s).')
);
}
}
return $result;
}
/**
* @return string[]
*/
public function getAllowedExtensions()
{
return $this->allowedExtensions;
}
/**
* @param $allowedExtensions
*/
public function setAllowedExtensions($allowedExtensions)
{
$this->allowedExtensions = $allowedExtensions;
}
public function saveMediaImage($imageName, $imagePath)
{
$baseTmpPath = $this->getBaseTmpPath();
$basePath = $this->getBasePath();
$baseImagePath = $this->getFilePath($basePath, $imageName);
$mediaPath = substr($imagePath, 0, strpos($imagePath, "media"));
$baseTmpImagePath = str_replace($mediaPath . "media/", "", $imagePath);
if ($baseImagePath == $baseTmpImagePath) {
return $imageName;
}
try {
$this->mediaDirectory->copyFile(
$baseTmpImagePath,
$baseImagePath
);
} catch (Exception $e) {
throw new LocalizedException(
__('Something went wrong while saving the file(s).')
);
}
return $imageName;
}
}
You need to change the below code in the above file with your desire path and required file extension.
saveCopyzoom_out_mapconst BASE_TMP_PATH = "wysiwyg/helloworld/"; const BASE_PATH = "wysiwyg/helloworld/"; const ALLOWED_EXTENSIONS = ['jpg', 'jpeg', 'png'];
Step 4: Create Save.php at app/code/Vendorname/Helloworld/Controller/Adminhtml/Index/Save.php and paste the below code.
saveCopyzoom_out_map<?php
namespace Vendorname\Helloworld\Controller\Adminhtml\Index;
use Vendorname\Helloworld\Model\HelloworldFactory;
use Magento\Backend\App\Action\Context;
use Magento\Framework\View\Result\PageFactory;
use Vendorname\Helloworld\Model\ImageUploader;
use Magento\Framework\Message\ManagerInterface;
use Magento\Framework\App\Cache\Manager;
/**
* Class Save
* @package Vendorname\Helloworld\Controller\Adminhtml\Index
*/
class Save extends \Magento\Backend\App\Action
{
/**
* @var PageFactory
*/
protected $resultPageFactory;
/**
* @var HelloworldFactory
*/
protected $helloworldFactory;
/**
* @var ManagerInterface
*/
protected $_messageManager;
/**
* @var TypeListInterface
*/
protected $cacheManager;
/**
* Save constructor.
* @param Context $context
* @param PageFactory $resultPageFactory
* @param HelloworldFactory $helloworldFactory
* @param ManagerInterface $messageManager
* @param UrlRewriteFactory $urlRewriteFactory
* @param StoreRepositoryInterface $storeRepository
* @param CollectionFactory $collectionFactory
*/
public function __construct(
Context $context,
PageFactory $resultPageFactory,
HelloworldFactory $helloworldFactory,
ImageUploader $imageUploaderModel,
ManagerInterface $messageManager,
Manager $cacheManager
)
{
parent::__construct($context);
$this->resultPageFactory = $resultPageFactory;
$this->helloworldFactory = $helloworldFactory;
$this->imageUploaderModel = $imageUploaderModel;
$this->messageManager = $messageManager;
$this->cacheManager = $cacheManager;
}
/**
* @return mixed
*/
public function execute()
{
try {
$resultPageFactory = $this->resultRedirectFactory->create();
$data = $this->getRequest()->getPostValue();
$model = $this->helloworldFactory->create();
$model->setData($data);
$model = $this->imageData($model, $data);
$model->save();
$this->messageManager->addSuccessMessage(__("Data Saved Successfully."));
$buttonData = $this->getRequest()->getParam('back');
if ($buttonData == 'edit' && $model->getId()) {
return $resultPageFactory->setPath('helloworld/index/form', ['id' => $model->getId()]);
}
if ($buttonData == 'new') {
return $resultPageFactory->setPath('helloworld/index/form');
}
if ($buttonData == 'close') {
$this->_redirect('helloworld/index/index');
}
} catch (\Exception $e) {
$this->_messageManager->addErrorMessage(__($e));
}
return $resultPageFactory->setPath('helloworld/index/index');
}
/**
* @param $model
* @param $data
* @return mixed
*/
public function imageData($model, $data)
{
if ($model->getId()) {
$pageData = $this->helloworldFactory->create();
$pageData->load($model->getId());
if (isset($data['image_field'][0]['name'])) {
$imageName1 = $pageData->getThumbnail();
$imageName2 = $data['image_field'][0]['name'];
if ($imageName1 != $imageName2) {
$imageUrl = $data['image_field'][0]['url'];
$imageName = $data['image_field'][0]['name'];
$data['image_field'] = $this->imageUploaderModel->saveMediaImage($imageName, $imageUrl);
} else {
$data['image_field'] = $data['image_field'][0]['name'];
}
} else {
$data['image_field'] = '';
}
} else {
if (isset($data['image_field'][0]['name'])) {
$imageUrl = $data['image_field'][0]['url'];
$imageName = $data['image_field'][0]['name'];
$data['image_field'] = $this->imageUploaderModel->saveMediaImage($imageName, $imageUrl);
}
}
$model->setData($data);
return $model;
}
}
You need to modify your save controller and add imageData function and call it before save process as per above example.
Now, we need to create/update DataProvider to get image on edit.
Step 5: Create/Update DataProvider.php at app/code/Vendorname/Helloworld/Model/DataProvider.php and paste the below code.
saveCopyzoom_out_map<?php
namespace Vendorname\Helloworld\Model;
use Vendorname\Helloworld\Model\ResourceModel\Helloworld\CollectionFactory;
use Magento\Store\Model\StoreManagerInterface;
class DataProvider extends \Magento\Ui\DataProvider\AbstractDataProvider
{
/**
* @var $loadedData
*/
protected $loadedData;
/**
* @var $collection
*/
protected $collection;
/**
* DataProvider constructor.
* @param string $name
* @param string $primaryFieldName
* @param string $requestFieldName
* @param CollectionFactory $collectionFactory
* @param array $meta
* @param array $data
*/
public function __construct(
$name,
$primaryFieldName,
$requestFieldName,
CollectionFactory $collectionFactory,
StoreManagerInterface $storeManager,
array $meta = [],
array $data = []
) {
$this->collection = $collectionFactory->create();
$this->storeManager = $storeManager;
parent::__construct($name, $primaryFieldName, $requestFieldName, $meta, $data);
}
/**
* @return mixed
*/
public function getData()
{
$items = $this->collection->getItems();
foreach ($items as $model) {
$this->loadedData[$model->getId()] = $model->getData();
if ($model->getImageField()) {
$m['image_field'][0]['name'] = $model->getImageField();
$m['image_field'][0]['url'] = $this->getMediaUrl($model->getImageField());
$fullData = $this->loadedData;
$this->loadedData[$model->getId()] = array_merge($fullData[$model->getId()], $m);
}
}
return $this->loadedData;
}
public function getMediaUrl($path = '')
{
$mediaUrl = $this->storeManager->getStore()->getBaseUrl(\Magento\Framework\UrlInterface::URL_TYPE_MEDIA) . 'wysiwyg/helloworld/' . $path;
return $mediaUrl;
}
}
If you already have DataProvider then update getData function with the above one.
Step 6: Now, open Command line in folder root of magento and run both commands.
saveCopyzoom_out_mapphp bin/magento setup:upgrade php bin/magento cache:flush
That's it,
Now open your ui form and check. You'll see somtnhing like below screenshot.

I hope this post helped you to find what you were looking for.
Bookmark it for your future reference. Do comment below if you have any other questions or doubts.
P.S. Do share this post with your team.
AI-Powered Recommended Articles
How to Add Magento Ui Image Uploader on Store Configuration in Magento 2
Enable image uploads in the store configuration section of Magento 2 for a more versatile admin experience.
Magento 2 Add Image on Admin UI Grid
Learn how to add product images to the admin grid in Magento 2 to enhance product visibility in the backend.
How to Resize Product Images Programmatically in Magento 2
Learn how to resize product images programmatically in Magento 2 for faster loading times and better performance.
Magento 2 Allow PDF file in Wysiwyg Editor
Learn how to allow PDF file uploads in the WYSIWYG editor in Magento 2 for better media handling and content management.
How To Get Resize Image in Custom Module
Learn how to retrieve and resize images in your custom module in Magento 2.
Magento 2 - How to Add a Custom Filed in Order Grid
Learn how to add a custom column to the admin order grid in Magento 2 for enhanced order tracking.