Images are an important component in Magento 2, in order to offer an extraordinary user experience to online store visitors. In this tutorial, we will guide you on how to upload image using UI component in Magento 2. Among the huge variety of UI components offered by Magento 2, image uploader is a crucial one.
Here are the steps to add image field and preview image in Magento 2 admin UI component form. First of all, you need to develop a UI form.
Step 1. Add this UI component image field in your UI form :
<field name="logo"> <argument name="data" xsi:type="array"> <item name="config" xsi:type="array"> <item name="dataType" xsi:type="string">string</item> <item name="source" xsi:type="string">helloworld</item> <item name="label" xsi:type="string" translate="true">Logo</item> <item name="visible" xsi:type="boolean">true</item> <item name="formElement" xsi:type="string">fileUploader</item> <item name="elementTmpl" xsi:type="string">ui/form/element/uploader/uploader</item> <item name="previewTmpl" xsi:type="string">MD_Helloworld/image-preview</item> <item name="required" xsi:type="boolean">false</item> <item name="sortOrder" xsi:type="number">40</item> <item name="uploaderConfig" xsi:type="array"> <item name="url" xsi:type="url" path="md_helloworld/index/uploader"/> </item> </item> </argument> </field>
Step 2. Then, Create image-preview.html template file at app/code/MD/Helloworld/view/adminhtml/web/template/ for preview image :
<div class="file-uploader-summary"> <div class="file-uploader-preview"> <a attr="href: $parent.getFilePreview($file)" target="_blank"> <img class="preview-image" tabindex="0" event="load: $parent.onPreviewLoad.bind($parent)" attr=" src: $parent.getFilePreview($file), alt: $file.name"> </a> <div class="actions"> <button type="button" class="action-remove" data-role="delete-button" attr="title: $t('Delete image')" click="$parent.removeFile.bind($parent, $file)"> <span translate="'Delete image'"/> </button> </div> </div> <div class="file-uploader-filename" text="$file.name"/> <div class="file-uploader-meta"> <text args="$file.previewWidth"/>x<text args="$file.previewHeight"/> </div> </div>
Step 3. After that, Create Virtual type for Image Uploader file di.xml at app/code/MD/Helloworld/etc/ and paste below code :
<!-- Image Uploader --> <virtualType name="VirtualTypeName" type="Magento\Catalog\Model\ImageUploader"> <arguments> <argument name="baseTmpPath" xsi:type="string">logo/image</argument> <argument name="basePath" xsi:type="string">logo/image</argument> <argument name="allowedExtensions" xsi:type="array"> <item name="jpg" xsi:type="string">jpg</item> <item name="jpeg" xsi:type="string">jpeg</item> <item name="gif" xsi:type="string">gif</item> <item name="png" xsi:type="string">png</item> </argument> </arguments> </virtualType> <type name="MD\Helloworld\Controller\Adminhtml\Index\Uploader"> <arguments> <argument name="imageUploader" xsi:type="object">VirtualTypeName</argument> </arguments> </type> <!-- End Image Uploader -->
Step 4. Thereafter, Create Controller file Uploader.php for Save Image at app/code/MD/Helloworld/Controller/Adminhtml/Index/ and paste below code :
<?php namespace MD\Helloworld\Controller\Adminhtml\Index; use Magento\Framework\App\Filesystem\DirectoryList; use Magento\Framework\Controller\ResultFactory; class Uploader extends \Magento\Backend\App\Action { /** * Image uploader * * @var \Magento\Catalog\Model\ImageUploader */ protected $imageUploader; /** * @var \Magento\Framework\Filesystem */ protected $filesystem; /** * @var \Magento\Framework\Filesystem\Io\File */ protected $fileIo; /** * @var \Magento\Store\Model\StoreManagerInterface */ protected $storeManager; /** * Upload constructor. * * @param \Magento\Backend\App\Action\Context $context * @param \Magento\Catalog\Model\ImageUploader $imageUploader */ public function __construct( \Magento\Backend\App\Action\Context $context, \Magento\Catalog\Model\ImageUploader $imageUploader, \Magento\Framework\Filesystem $filesystem, \Magento\Framework\Filesystem\Io\File $fileIo, \Magento\Store\Model\StoreManagerInterface $storeManager ) { parent::__construct($context); $this->imageUploader = $imageUploader; $this->filesystem = $filesystem; $this->fileIo = $fileIo; $this->storeManager = $storeManager; } /** * Upload file controller action. * * @return \Magento\Framework\Controller\ResultInterface */ public function execute() { $imageUploadId = $this->getRequest()->getParam('param_name', 'logo'); try { $imageResult = $this->imageUploader->saveFileToTmpDir($imageUploadId); // Upload image folder wise $imageName = $imageResult['name']; $firstName = substr($imageName, 0, 1); $secondName = substr($imageName, 1, 1); $basePath = $this->filesystem->getDirectoryRead(DirectoryList::MEDIA)->getAbsolutePath() . 'logo/image/'; $mediaRootDir = $this->filesystem->getDirectoryRead(DirectoryList::MEDIA)->getAbsolutePath() . 'logo/image/' . $firstName . '/' . $secondName . '/'; if (!is_dir($mediaRootDir)) { $this->fileIo->mkdir($mediaRootDir, 0775); } // Set image name with new name, If image already exist $newImageName = $this->updateImageName($mediaRootDir, $imageName); $this->fileIo->mv($basePath . $imageName, $mediaRootDir . $newImageName); $imageResult['cookie'] = [ 'name' => $this->_getSession()->getName(), 'value' => $this->_getSession()->getSessionId(), 'lifetime' => $this->_getSession()->getCookieLifetime(), 'path' => $this->_getSession()->getCookiePath(), 'domain' => $this->_getSession()->getCookieDomain(), ]; } catch (\Exception $e) { $imageResult = ['error' => $e->getMessage(), 'errorcode' => $e->getCode()]; } return $this->resultFactory->create(ResultFactory::TYPE_JSON)->setData($imageResult); } public function updateImageName($path, $file_name) { if ($position = strrpos($file_name, '.')) { $name = substr($file_name, 0, $position); $extension = substr($file_name, $position); } else { $name = $file_name; } $new_file_path = $path . '/' . $file_name; $new_file_name = $file_name; $count = 0; while (file_exists($new_file_path)) { $new_file_name = $name . '_' . $count . $extension; $new_file_path = $path . '/' . $new_file_name; $count++; } return $new_file_name; } }
Step 5. At last, Update code in your DataProvider.php File to display image after saving the records :
<?php namespace MD\Helloworld\Controller\Adminhtml\Index; use Magento\Framework\App\Filesystem\DirectoryList; use Magento\Framework\Controller\ResultFactory; class Uploader extends \Magento\Backend\App\Action { /** * Image uploader * * @var \Magento\Catalog\Model\ImageUploader */ protected $imageUploader; /** * @var \Magento\Framework\Filesystem */ protected $filesystem; /** * @var \Magento\Framework\Filesystem\Io\File */ protected $fileIo; /** * @var \Magento\Store\Model\StoreManagerInterface */ protected $storeManager; /** * Upload constructor. * * @param \Magento\Backend\App\Action\Context $context * @param \Magento\Catalog\Model\ImageUploader $imageUploader */ public function __construct( \Magento\Backend\App\Action\Context $context, \Magento\Catalog\Model\ImageUploader $imageUploader, \Magento\Framework\Filesystem $filesystem, \Magento\Framework\Filesystem\Io\File $fileIo, \Magento\Store\Model\StoreManagerInterface $storeManager ) { parent::__construct($context); $this->imageUploader = $imageUploader; $this->filesystem = $filesystem; $this->fileIo = $fileIo; $this->storeManager = $storeManager; } /** * Upload file controller action. * * @return \Magento\Framework\Controller\ResultInterface */ public function execute() { $imageUploadId = $this->getRequest()->getParam('param_name', 'logo'); try { $imageResult = $this->imageUploader->saveFileToTmpDir($imageUploadId); // Upload image folder wise $imageName = $imageResult['name']; $firstName = substr($imageName, 0, 1); $secondName = substr($imageName, 1, 1); $basePath = $this->filesystem->getDirectoryRead(DirectoryList::MEDIA)->getAbsolutePath() . 'logo/image/'; $mediaRootDir = $this->filesystem->getDirectoryRead(DirectoryList::MEDIA)->getAbsolutePath() . 'logo/image/' . $firstName . '/' . $secondName . '/'; if (!is_dir($mediaRootDir)) { $this->fileIo->mkdir($mediaRootDir, 0775); } // Set image name with new name, If image already exist $newImageName = $this->updateImageName($mediaRootDir, $imageName); $this->fileIo->mv($basePath . $imageName, $mediaRootDir . $newImageName); $imageResult['cookie'] = [ 'name' => $this->_getSession()->getName(), 'value' => $this->_getSession()->getSessionId(), 'lifetime' => $this->_getSession()->getCookieLifetime(), 'path' => $this->_getSession()->getCookiePath(), 'domain' => $this->_getSession()->getCookieDomain(), ]; } catch (\Exception $e) { $imageResult = ['error' => $e->getMessage(), 'errorcode' => $e->getCode()]; } return $this->resultFactory->create(ResultFactory::TYPE_JSON)->setData($imageResult); } public function updateImageName($path, $file_name) { if ($position = strrpos($file_name, '.')) { $name = substr($file_name, 0, $position); $extension = substr($file_name, $position); } else { $name = $file_name; } $new_file_path = $path . '/' . $file_name; $new_file_name = $file_name; $count = 0; while (file_exists($new_file_path)) { $new_file_name = $name . '_' . $count . $extension; $new_file_path = $path . '/' . $new_file_name; $count++; } return $new_file_name; } }
Now, execute below-mentioned commands and you can see image uploader in your UI form :
php bin/magento s:up php bin/magento s:s:d -f php bin/magento c:c
There it is!! This is everything you might need to upload image with UI component in Magento 2. In case you have any queries, feel free to contact us.
Also read: How to Get Product Image URL from REST API in Magento 2?