7

I have magento2 admin custom module with image upload functionality. I want to upload image from admin. what code should apply for display image field in from, upload image, also image display in edit action.

Thanks

File Path : app\code\[Vendor]\[Module]\Block\Adminhtml\Emp\Edit\Tab\Main.php

    /**
     * Prepare form
     *
     * @return $this
     * @SuppressWarnings(PHPMD.ExcessiveMethodLength)
    */
    protected function _prepareForm()
    {
        $model = $this->_coreRegistry->registry('emp_post');

        $isElementDisabled = false;

        /** @var \Magento\Framework\Data\Form $form */
        $form = $this->_formFactory->create();

        $form->setHtmlIdPrefix('page_');

        $fieldset = $form->addFieldset('base_fieldset', ['legend' => __('Employee Information')]);

        if ($model->getId()) {
            $fieldset->addField('customer_id', 'hidden', ['name' => 'customer_id']);
        }

        $fieldset->addField(
            'firstname',
            'text',
            [
                'name' => 'firstname',
                'label' => __('First Name'),
                'title' => __('First Name'),
                'required' => true,
                'disabled' => $isElementDisabled,
                'value' =>'abc'
            ]
        );

        $fieldset->addField(
            'lastname',
            'text',
            [
                'name' => 'lastname',
                'label' => __('Last Name'),
                'title' => __('Last Name'),
                'required' => true,
                'disabled' => $isElementDisabled,
                'value' =>'abc'
            ]
        );

        $fieldset->addField(
            'email',
            'text',
            [
                'name' => 'email',
                'label' => __('Email Address'),
                'title' => __('Email Address'),
                'required' => true,
                'disabled' => $isElementDisabled,
                'value' =>'abc'
            ]
        );


        $fieldset->addField(
            'image',
            'image',
            array(
                'name' => 'image',
                'label' => __('Image'),
                'title' => __('Image')
            )
        );

        $fieldset->addField(
            'telephone',
            'text',
            [
                'name' => 'telephone',
                'label' => __('Telephone'),
                'title' => __('Telephone'),
                'required' => true,
                'disabled' => $isElementDisabled,
                'value' =>'abc'
            ]
        );

        $dateFormat = $this->_localeDate->getDateFormat(
            \IntlDateFormatter::SHORT
        );

        $fieldset->addField(
            'dob',
            'date',
            [
                'name' => 'dob',
                'label' => __('Date of birth'),
                'date_format' => $dateFormat,
                'disabled' => $isElementDisabled,
                'class' => 'validate-date validate-date-range date-range-custom_theme-from'
            ]
        );

        $fieldset->addField(
            'is_active',
            'select',
            [
                'label' => __('Status'),
                'title' => __('Status'),
                'name' => 'is_active',
                'required' => true,
                'options' => $this->_status->getOptionArray(),
                'disabled' => $isElementDisabled
            ]
        );
        if (!$model->getId()) {
            $model->setData('is_active', $isElementDisabled ? '0' : '1');
        }


        if($model->getData('image')){
            $model->setData('image','learning/images'.$model->getData('image'));
        }

        $form->setValues($model->getData());
        $this->setForm($form);

        return parent::_prepareForm();
    } 
17

You need to create a class to handle your image upload field and show the image once is uploaded.

So create [Namespace]\[Module]\Block\Adminhtml\[Entity]\Helper\Image class

<?php
namespace [Namespace]\[Module]\Block\Adminhtml\[Entity]\Helper;
use Magento\Framework\Data\Form\Element\Image as ImageField;
use Magento\Framework\Data\Form\Element\Factory as ElementFactory;
use Magento\Framework\Data\Form\Element\CollectionFactory as ElementCollectionFactory;
use Magento\Framework\Escaper;
use [Namespace]\[Module]\Model\[Entity]\Image as [Entity]Image;
use Magento\Framework\UrlInterface;

/**
 * @method string getValue()
 */
class Image extends ImageField
{
    /**
     * image model
     *
     * @var \[Namespace]\[Module]\Model\[Entity]\Image
     */
    protected $imageModel;

    /**
     * @param [Entity]Image $imageModel
     * @param ElementFactory $factoryElement
     * @param ElementCollectionFactory $factoryCollection
     * @param Escaper $escaper
     * @param UrlInterface $urlBuilder
     * @param array $data
     */
    public function __construct(
        [Entity]Image $imageModel,
        ElementFactory $factoryElement,
        ElementCollectionFactory $factoryCollection,
        Escaper $escaper,
        UrlInterface $urlBuilder,
        $data = []
    )
    {
        $this->imageModel = $imageModel;
        parent::__construct($factoryElement, $factoryCollection, $escaper, $urlBuilder, $data);
    }
    /**
     * Get image preview url
     *
     * @return string
     */
    protected function _getUrl()
    {
        $url = false;
        if ($this->getValue()) {
            $url = $this->imageModel->getBaseUrl().$this->getValue();
        }
        return $url;
    }
}

then create the class that will help you retrieve the image upload path and upload dir

<?php
namespace [Namespace]\[Module]\Model\[Entity];
use Magento\Framework\UrlInterface;
use Magento\Framework\Filesystem;
use Magento\Framework\App\Filesystem\DirectoryList;
class Image
{
    /**
     * media sub folder
     * @var string
     */
    protected $subDir = '[namespace]/[module]/[entity]';
    /**
     * url builder
     *
     * @var \Magento\Framework\UrlInterface
     */
    protected $urlBuilder;
    /**
     * @var \Magento\Framework\Filesystem
     */
    protected $fileSystem;
    /**
     * @param UrlInterface $urlBuilder
     * @param Filesystem $fileSystem
     */
    public function __construct(
        UrlInterface $urlBuilder,
        Filesystem $fileSystem
    )
    {
        $this->urlBuilder = $urlBuilder;
        $this->fileSystem = $fileSystem;
    }
    /**
     * get images base url
     *
     * @return string
     */
    public function getBaseUrl()
    {
        return $this->urlBuilder->getBaseUrl(['_type' => UrlInterface::URL_TYPE_MEDIA]).$this->subDir.'/image';
    }
    /**
     * get base image dir
     *
     * @return string
     */
    public function getBaseDir()
    {
        return $this->fileSystem->getDirectoryWrite(DirectoryList::MEDIA)->getAbsolutePath($this->subDir.'/image');
    }
}

now in your edit for tab add this in the method _prepareForm right after declaring the fieldset

$fieldset->addType('image', '\[Namespace]\[Module]\Block\Adminhtml\[Entity]\Helper\Image');

and add your image field like this

$fieldset->addField(
    'image_field_name',
    'image',
    [
        'name'        => 'image_field_name',
        'label'       => __('Image field Label'),
        'title'       => __('Image field Label'),
    ]
);

In the controller that saves your entity you need to inject in the constructor the following classes

Magento\MediaStorage\Model\File\UploaderFactory and [Namespace]\[Module]\Model\[Entity]\Image

So make your class look like this

<?php
use Magento\Framework\Exception\LocalizedException as FrameworkException;

class ....

protected $uploaderFactory;
protected $imageModel;

public function __construct(
    ....
    \Magento\MediaStorage\Model\File\UploaderFactory $uploaderFactory,
    \[Namespace]\[Module]\Model\[Entity]\Image $imageModel,
    ....
){
    ...
    $this->uploaderFactory = $uploaderFactory;
    $this->imageModel = $imageModel;
    ...
}

Now, in the same controller add this, before calling $[entity]->save()

$imageName = $this->uploadFileAndGetName('image_field_name', $this->imageModel->getBaseDir(), $data);
$[entity]->setImageFieldName($imageName);

and create this method:

public function uploadFileAndGetName($input, $destinationFolder, $data)
{
    try {
        if (isset($data[$input]['delete'])) {
            return '';
        } else {
            $uploader = $this->uploaderFactory->create(['fileId' => $input]);
            $uploader->setAllowRenameFiles(true);
            $uploader->setFilesDispersion(true);
            $uploader->setAllowCreateFolders(true);
            $result = $uploader->save($destinationFolder);
            return $result['file'];
        }
    } catch (\Exception $e) {
        if ($e->getCode() != \Magento\Framework\File\Uploader::TMP_NAME_EMPTY) {
            throw new FrameworkException($e->getMessage());
        } else {
            if (isset($data[$input]['value'])) {
                return $data[$input]['value'];
            }
        }
    }
    return '';
}

A full example on how to create an entity that supports image and file upload (it's a bit different than described here as it contains an extra class for upload) can be found here

  • given url exension not working. it throw error on screen exception 'Magento\Framework\Exception\LocalizedException' with message 'Source class "\Magento\Framework\View\Element\UiComponent\DataProvider\Collection" for "Magento\Framework\View\Element\UiComponent\DataProvider\CollectionFactory" generation does not exist.' – Suresh Chikani Oct 13 '15 at 8:48
  • @SHPatel. Clear the contents of var/generation. If this problem persists it can for 2 reasons. You either don't have the latest version of Magento 2 or my extension does not work on the latest version. If the problem is my extension I will check it when I have some time. – Marius Oct 13 '15 at 11:11
  • @Marius, How can we display such image into adminhtml Grid section too? Right now is Default magento 2 is showing it for Product Grid. – Praful Rajput Oct 13 '15 at 13:29
  • @PrafulRajput. I didn't get to check that part out yet. I have no idea how it's done. – Marius Oct 13 '15 at 13:38
  • @marius this works in RC 2. One thing you mention adding $fieldset->addType('image', '[Namespace][Module]\Adminhtml[Entity]\Helper\Image'); I am pretty sure you are missing a "Block" callout. [Namespace][Module]\Block\Adminhtml[Entity]\Helper\Image – Eirik Nov 9 '15 at 20:47
3

Admin module for basic add/update news is here. In case you are looking for simple image upload solution look at the following snippet which is taken from the link.

use Magento\Framework\App\Filesystem\DirectoryList;
use Magento\Backend\App\Action;
protected $_fileUploaderFactory;
public function __construct(
    \Magento\MediaStorage\Model\File\UploaderFactory $fileUploaderFactory,
    Action\Context $context     
) {
    $this->_fileUploaderFactory = $fileUploaderFactory;
    parent::__construct($context);
}
public function execute(){
    $uploader = $this->_fileUploaderFactory->create(['fileId' => 'image']);
    $uploader->setAllowedExtensions(['jpg', 'jpeg', 'gif', 'png']);
    $uploader->setAllowRenameFiles(false);
    $uploader->setFilesDispersion(false);
    $path = $this->_objectManager->get('Magento\Framework\Filesystem')->getDirectoryRead(DirectoryList::MEDIA)
    ->getAbsolutePath('images/');
    $uploader->save($path);
}
  • _filesystem not definded :( – fudu Oct 30 '18 at 8:48
  • found it, we need to add this to work, also create it in construct() function as well use \Magento\Framework\Filesystem; – fudu Oct 30 '18 at 8:57
  • Replace _filesystem by $this->_objectManager->get('Magento\Framework\Filesystem') – divya sekar Apr 15 at 5:12
  • @divyasekar Can you please answer this question? -> magento.stackexchange.com/questions/287175/… – Kowsigan Atsayam Sep 3 at 16:45
1

You could add image field in _prepareForm() method of your admin form:

$fieldset->addField(
    'imagefieldname',
    'image',
    array(
        'name' => 'imagefieldname',
        'label' => __('Image'),
        'title' => __('Image')
    )

  );
  • 1
    @chanresh image field added done but i need to display image preview on form. – Suresh Chikani Oct 13 '15 at 8:49
  • 1
    If you upload image and save the record then it will show small thumbnail near "Choose File" input file field. – Chandresh P. Oct 13 '15 at 9:08
  • 1
    I have uplode image and save it but thumbnail image can't display. – Suresh Chikani Oct 13 '15 at 9:27
  • Please add your code snippet for _prepareForm(). – Chandresh P. Oct 13 '15 at 12:24
  • check my question, question updated with _prepareForm(). – Suresh Chikani Oct 13 '15 at 12:36
0

Check the following link for admin custom form image upload

admin custom form image upload magento 2

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.