0

How Can Add Extra image upload attribute in Backend form Like Screenshot.

I Follow this link "magento 2 how to upload images and videos in custom module" but not working.

Not use in custom module use in product form.

enter image description here

3

As per your requirement, I think you need to add a checkbox like Hide from Product Page checkbox.

Please follow this steps for checkbox checked and save value in database :

=> Create InstallSchema.php on below path for add custom field in database :

/app/code/CompanyName/ModuleName/Setup

<?php
namespace CompanyName\ModuleName\Setup;

use Magento\Framework\Setup\InstallSchemaInterface;
use Magento\Framework\Setup\ModuleContextInterface;
use Magento\Framework\Setup\SchemaSetupInterface;

class InstallSchema implements InstallSchemaInterface {
    public function install(SchemaSetupInterface $setup, ModuleContextInterface $context) {
        $installer = $setup;
        $installer->startSetup();
        /**
         * [$tableName catalog_product_option]
         * @var [catalog_product_option]
         */
        $tableName = $setup->getTable('catalog_product_entity_media_gallery_value');

        if ($setup->getConnection()->isTableExists($tableName) == true) {
            $columns = [
                'displayimage' => [
                    'type' => \Magento\Framework\DB\Ddl\Table::TYPE_SMALLINT,
                    'length' => 5,
                    'nullable' => false,
                    'comment' => 'Display Image',
                    'default' => '0',
                ],
            ];
            $connection = $setup->getConnection();
            foreach ($columns as $name => $definition) {
                $connection->addColumn($tableName, $name, $definition);
            }
        }

        $installer->endSetup();
    }
}

=> Create events.xml file on this below path for add events catalog_product_save_after and catalog_product_gallery_prepare_layout

/app/code/CompanyName/ModuleName/etc/adminhtml

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Event/etc/events.xsd">
    <event name="catalog_product_save_after">
        <observer name="validate" instance="CompanyName\ModuleName\Observer\ProductSaveAfter" />
    </event>
    <event name="catalog_product_gallery_prepare_layout">
        <observer name="change_template" disabled="true"/>
        <observer name="custom_change_template" instance="CompanyName\ModuleName\Observer\ChangeTemplateObserver" />
    </event> 
</config>

=> Create ChangeTemplateObserver.php file for prepare layout of product gallery :

/app/code/CompanyName/ModuleName/Observer

<?php

namespace CompanyName\ModuleName\Observer;

use Magento\Framework\Event\ObserverInterface;

class ChangeTemplateObserver implements ObserverInterface {

    public function execute(\Magento\Framework\Event\Observer $observer) {
        $observer->getBlock()->setTemplate('CompanyName_ModuleName::helper/gallery.phtml');
    }
}

=> Create gallery.phtml on the below path for make layout of product gallery :

/app/code/CompanyName/ModuleName/view/adminhtml/templates/helper

<?php
/**
 * Copyright © Magento, Inc. All rights reserved.
 * See COPYING.txt for license details.
 */

// @codingStandardsIgnoreFile

/** @var $block \Magento\Catalog\Block\Adminhtml\Product\Helper\Form\Gallery\Content */
$elementName = $block->getElement()->getName() . '[images]';
$formName = $block->getFormName();
?>
<div id="<?= $block->getHtmlId() ?>"
     class="gallery"
     data-mage-init='{"productGallery":{"template":"#<?= $block->getHtmlId() ?>-template"}}'
     data-parent-component="<?= $block->escapeHtml($block->getData('config/parentComponent')) ?>"
     data-images="<?= $block->escapeHtml($block->getImagesJson()) ?>"
     data-types="<?= $block->escapeHtml(
         $this->helper('Magento\Framework\Json\Helper\Data')->jsonEncode($block->getImageTypes())
     ) ?>"
    >
    <?php if (!$block->getElement()->getReadonly()) {?>
        <div class="image image-placeholder">
            <?= $block->getUploaderHtml() ?>
            <div class="product-image-wrapper">
                <p class="image-placeholder-text">
                    <?= /* @escapeNotVerified */ __('Browse to find or drag image here') ?>
                </p>
            </div>
        </div>
    <?php } ?>
    <?php foreach ($block->getImageTypes() as $typeData) {
    ?>
        <input name="<?= $block->escapeHtml($typeData['name']) ?>"
               data-form-part="<?= /* @escapeNotVerified */ $formName ?>"
               class="image-<?= $block->escapeHtml($typeData['code']) ?>"
               type="hidden"
               value="<?= $block->escapeHtml($typeData['value']) ?>"/>
    <?php

} ?>

    <script id="<?= $block->getHtmlId() ?>-template" type="text/x-magento-template">
        <div class="image item<% if (data.disabled == 1) { %> hidden-for-front<% } %>"
             data-role="image">
            <input type="hidden"
                   name="<?= /* @escapeNotVerified */ $elementName ?>[<%- data.file_id %>][position]"
                   value="<%- data.position %>"
                   data-form-part="<?= /* @escapeNotVerified */ $formName ?>"
                   class="position"/>
            <input type="hidden"
                   name="<?= /* @escapeNotVerified */ $elementName ?>[<%- data.file_id %>][file]"
                   data-form-part="<?= /* @escapeNotVerified */ $formName ?>"
                   value="<%- data.file %>"/>
            <input type="hidden"
                   name="<?= /* @escapeNotVerified */ $elementName ?>[<%- data.file_id %>][value_id]"
                   data-form-part="<?= /* @escapeNotVerified */ $formName ?>"
                   value="<%- data.value_id %>"/>
            <input type="hidden"
                   name="<?= /* @escapeNotVerified */ $elementName ?>[<%- data.file_id %>][label]"
                   data-form-part="<?= /* @escapeNotVerified */ $formName ?>"
                   value="<%- data.label %>"/>
            <input type="hidden"
                   name="<?= /* @escapeNotVerified */ $elementName ?>[<%- data.file_id %>][disabled]"
                   data-form-part="<?= /* @escapeNotVerified */ $formName ?>"
                   value="<%- data.disabled %>"/>
            <input type="hidden"
                   name="<?= /* @escapeNotVerified */ $elementName ?>[<%- data.file_id %>][displayimage]"
                   data-form-part="<?= /* @escapeNotVerified */ $formName ?>"
                   value="<%- data.displayimage %>"/>
            <input type="hidden"
                   name="<?= /* @escapeNotVerified */ $elementName ?>[<%- data.file_id %>][media_type]"
                   data-form-part="<?= /* @escapeNotVerified */ $formName ?>"
                   value="image"/>
            <input type="hidden"
                   name="<?= /* @escapeNotVerified */ $elementName ?>[<%- data.file_id %>][removed]"
                   data-form-part="<?= /* @escapeNotVerified */ $formName ?>"
                   value=""
                   class="is-removed"/>

            <div class="product-image-wrapper">
                <img class="product-image"
                     data-role="image-element"
                     src="<%- data.url %>"
                     alt="<%- data.label %>"/>

                <div class="actions">
                    <button type="button"
                            class="action-remove"
                            data-role="delete-button"
                            title="<?= /* @escapeNotVerified */ __('Delete image') ?>">
                    <span>
                        <?= /* @escapeNotVerified */ __('Delete image') ?>
                    </span>
                    </button>
                    <div class="draggable-handle"></div>
                </div>
                <div class="image-fade"><span><?= /* @escapeNotVerified */ __('Hidden') ?></span></div>
            </div>


            <div class="item-description">
                <div class="item-title" data-role="img-title"><%- data.label %></div>
                <div class="item-size">
                  <span data-role="image-dimens"></span>, <span data-role="image-size"><%- data.sizeLabel %></span>
                </div>
            </div>

            <ul class="item-roles" data-role="roles-labels">
                <?php
                foreach ($block->getImageTypes() as $typeData) {
                    ?>
                    <li data-role-code="<?php /* @escapeNotVerified */ echo $block->escapeHtml(
                        $typeData['code']
                    ) ?>" class="item-role item-role-<?php /* @escapeNotVerified */ echo $block->escapeHtml(
                        $typeData['code']
                    ) ?>">
                        <?= /* @escapeNotVerified */ $block->escapeHtml($typeData['label']) ?>
                    </li>
                    <?php
                }
                ?>
            </ul>
        </div>
    </script>

    <script data-role="img-dialog-container-tmpl" type="text/x-magento-template">
      <div class="image-panel" data-role="dialog">
      </div>
    </script>

    <script data-role="img-dialog-tmpl" type="text/x-magento-template">
            <div class="image-panel-preview">
                <img src="<%- data.url %>" alt="<%- data.label %>" />
            </div>
            <div class="image-panel-controls">
                <strong class="image-name"><%- data.label %></strong>

                <fieldset class="admin__fieldset fieldset-image-panel">
                    <div class="admin__field field-image-description">
                        <label class="admin__field-label" for="image-description">
                            <span><?= /* @escapeNotVerified */ __('Alt Text') ?></span>
                        </label>

                        <div class="admin__field-control">
                            <textarea data-role="image-description"
                                      rows="3"
                                      class="admin__control-textarea"
                                      name="<?php /* @escapeNotVerified */
                                      echo $elementName
                                      ?>[<%- data.file_id %>][label]"><%- data.label %></textarea>
                        </div>
                    </div>

                    <div class="admin__field field-image-role">
                        <label class="admin__field-label">
                            <span><?= /* @escapeNotVerified */ __('Role') ?></span>
                        </label>
                        <div class="admin__field-control">
                            <ul class="multiselect-alt">
                                <?php
                                foreach ($block->getMediaAttributes() as $attribute) :
                                    ?>
                                    <li class="item">
                                        <label>
                                            <input class="image-type"
                                                   data-role="type-selector"
                                                   data-form-part="<?= /* @escapeNotVerified */ $formName ?>"
                                                   type="checkbox"
                                                   value="<?php /* @escapeNotVerified */ echo $block->escapeHtml(
                                                       $attribute->getAttributeCode()
                                                   ) ?>"
                                                />
                                            <?php /* @escapeNotVerified */ echo $block->escapeHtml(
                                                $attribute->getFrontendLabel()
                                            ) ?>
                                        </label>
                                    </li>
                                <?php
                                endforeach;
                                ?>
                            </ul>
                        </div>
                    </div>

                    <div class="admin__field admin__field-inline field-image-size" data-role="size">
                        <label class="admin__field-label">
                            <span><?= /* @escapeNotVerified */ __('Image Size') ?></span>
                        </label>
                        <div class="admin__field-value" data-message="<?= /* @escapeNotVerified */ __('{size}') ?>"></div>
                    </div>

                    <div class="admin__field admin__field-inline field-image-resolution" data-role="resolution">
                        <label class="admin__field-label">
                            <span><?= /* @escapeNotVerified */ __('Image Resolution') ?></span>
                        </label>
                        <div class="admin__field-value" data-message="<?= /* @escapeNotVerified */ __('{width}^{height} px') ?>"></div>
                    </div>

                    <div class="admin__field field-image-hide">
                        <div class="admin__field-control">
                            <div class="admin__field admin__field-option">
                                <input type="checkbox"
                                       id="hide-from-product-page"
                                       data-role="visibility-trigger"
                                       data-form-part="<?= /* @escapeNotVerified */ $formName ?>"
                                       value="1"
                                       class="admin__control-checkbox"
                                       name="<?= /* @escapeNotVerified */ $elementName ?>[<%- data.file_id %>][disabled]"
                                <% if (data.disabled == 1) { %>checked="checked"<% } %> />

                                <label for="hide-from-product-page" class="admin__field-label">
                                    <?= /* @escapeNotVerified */ __('Hide from Product Page') ?>
                                </label>
                            </div>
                        </div>
                    </div>

                    <div class="admin__field field-display-image">
                        <div class="admin__field-control">
                            <div class="admin__field admin__field-option">
                                <input type="checkbox"
                                       id="display-image-from-product-page-<%- data.file_id %>"
                                       data-role="visibility-trigger-display-image"
                                       data-form-part="<?= /* @escapeNotVerified */ $formName ?>"
                                       value="1"
                                       class="admin__control-checkbox"
                                       name="<?= /* @escapeNotVerified */ $elementName ?>[<%- data.file_id %>][displayimage]"
                                <% if (data.displayimage == 1) { %>checked="checked"<% } %> />

                                <label for="display-image-from-product-page-<%- data.file_id %>" class="admin__field-label">
                                    <?= /* @escapeNotVerified */ __('Display Image') ?>
                                </label>
                            </div>
                        </div>
                    </div>
                </fieldset>
            </div>
    </script>
    <?= $block->getChildHtml('new-video') ?>
</div>
<script>
    jQuery('body').trigger('contentUpdated');
</script>

=> Create ProductSaveAfter.php observer on this below path for save custom field value in databse :

/app/code/CompanyName/ModuleName/Observer

<?php
namespace CompanyName\ModuleName\Observer;

use Magento\Framework\Event\ObserverInterface;
use \Magento\Store\Model\StoreManagerInterface;

class ProductSaveAfter implements ObserverInterface
{
    protected $_objectManager;
    protected $messageManager;
    protected $_productmetalFactory;
    protected $_productdiamondFactory;
    protected $_productstoneFactory;
    protected $_eavConfig;
    protected $stonestore;
    protected $scopeConfig;
    protected $storeManager;

    public function __construct(
        \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig,
        \Magento\Framework\ObjectManagerInterface $objectManager,
        \Magento\Framework\App\RequestInterface $request,
        \Magento\Eav\Model\Config $eavConfig,
        StoreManagerInterface $storeManager,
        \Magento\Framework\Message\ManagerInterface $messageManager
    ) {
        $this->_objectManager = $objectManager;
        $this->_request = $request;
        $this->scopeConfig = $scopeConfig;
        $this->_eavConfig = $eavConfig;
        $this->storeManager = $storeManager;
        $this->messageManager = $messageManager;
    }
    public function execute(\Magento\Framework\Event\Observer $observer)
    {
        $data = $this->_request->getParams();
        $objectManager = \Magento\Framework\App\ObjectManager::getInstance();
        $array_element = 0;
        $images = $data['product']['media_gallery']['images'];
        foreach ($images as $value) {
            if ($value['value_id'] == "") {
                $array_element++;
            }
        }

        $productCollection = $objectManager->create('Magento\Catalog\Model\ResourceModel\Product\CollectionFactory');
        $collection = $productCollection->create();
        $collection->getSelect()->join(
            array('value_entity' => $collection->getTable('catalog_product_entity_media_gallery_value')),
            'e.entity_id = value_entity.entity_id',
            array('value_id')
        );
        $collection->getSelect()->join(
            array('value_data' => $collection->getTable('catalog_product_entity_media_gallery')),
            'value_entity.value_id = value_data.value_id',
            array('value')
        );
        $product = $collection->addFieldToFilter('entity_id', ['eq' => $data['id']]);
        $collection_updated = array_slice($product->getData(), "-" . $array_element, $array_element, true);
        $new_image_id = [];
        foreach ($collection_updated as $key => $value) {
            $new_image_id[] = $value['value_id'];
        }
        try
        {
            $getDisplayImage = [];
            $resource = $objectManager->get('Magento\Framework\App\ResourceConnection');
            $connection = $resource->getConnection();
            $tableName = $resource->getTableName('catalog_product_entity_media_gallery_value');
            foreach ($images as $image) {
                if ($image['removed'] != "") {
                    $sql = "DELETE FROM " . $tableName . " WHERE value_id =" . $image['value_id'];
                    $connection->query($sql);
                }
                if ($image['value_id'] == "") {
                    if (!isset($image['store_id']) || $image['store_id'] == "") {
                        $store_id = '0';
                    } else {
                        $store_id = $image['store_id'];
                    }
                    $getDisplayImage[] = $image['displayimage'];
                } else {
                    $sql = "update " . $tableName . " set displayimage = " . $image['displayimage'] . " where value_id = " . $image['value_id'];
                    $connection->query($sql);
                }
            }

            if ($array_element > 0) {
                $count = 0;
                foreach ($collection_updated as $key1 => $value1) {
                    $collection_updated[$key1]['new_displayimage'] = $getDisplayImage[$count];
                    $count++;
                    $sql = "update " . $tableName . " set displayimage  = " . $collection_updated[$key1]['new_displayimage'] . " where value_id = " . $collection_updated[$key1]['value_id'];
                    $connection->query($sql);
                }
            }
        } catch (\Magento\Framework\Exception\LocalizedException $e) {
            $this->messageManager->addError($e->getMessage());
        } catch (\RuntimeException $e) {
            $this->messageManager->addError($e->getMessage());
        } catch (\Exception $e) {
            $this->messageManager->addError($e->getMessage());
        }
    }
}

=> Create di.xml file on this below path for override module :

/app/code/CompanyName/ModuleName/etc

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
<preference for="Magento\Catalog\Model\ResourceModel\Product\Gallery" type="CompanyName\ModuleName\Model\ResourceModel\Product\Gallery" />
</config>

=> Create Gallery.php file on this below path for override module :

/app/code/CompanyName/ModuleName/Model/ResourceModel/Product

<?php
/**
 * Copyright © Magento, Inc. All rights reserved.
 * See COPYING.txt for license details.
 */
namespace CompanyName\ModuleName\Model\ResourceModel\Product;

use Magento\Store\Model\Store;

/**
 * Catalog product media gallery resource model.
 *
 * @api
 * @since 101.0.0
 */
class Gallery extends \Magento\Catalog\Model\ResourceModel\Product\Gallery {
  public function createBatchBaseSelect($storeId, $attributeId) {
    $linkField = $this->metadata->getLinkField();

    $positionCheckSql = $this->getConnection()->getCheckSql(
      'value.position IS NULL',
      'default_value.position',
      'value.position'
    );

    $mainTableAlias = $this->getMainTableAlias();

    $select = $this->getConnection()->select()->from(
      [$mainTableAlias => $this->getMainTable()],
      [
        'value_id',
        'file' => 'value',
        'media_type',
      ]
    )->joinInner(
      ['entity' => $this->getTable(self::GALLERY_VALUE_TO_ENTITY_TABLE)],
      $mainTableAlias . '.value_id = entity.value_id',
      [$linkField]
    )->joinLeft(
      ['value' => $this->getTable(self::GALLERY_VALUE_TABLE)],
      implode(
        ' AND ',
        [
          $mainTableAlias . '.value_id = value.value_id',
          $this->getConnection()->quoteInto('value.store_id = ?', (int) $storeId),
          'value.' . $linkField . ' = entity.' . $linkField,
        ]
      ),
      ['label', 'position', 'disabled', 'displayimage']
    )->joinLeft(
      ['default_value' => $this->getTable(self::GALLERY_VALUE_TABLE)],
      implode(
        ' AND ',
        [
          $mainTableAlias . '.value_id = default_value.value_id',
          $this->getConnection()->quoteInto('default_value.store_id = ?', Store::DEFAULT_STORE_ID),
          'default_value.' . $linkField . ' = entity.' . $linkField,
        ]
      ),
      ['label_default' => 'label', 'position_default' => 'position', 'disabled_default' => 'disabled', 'displayimage_default' => 'displayimage']
    )->where(
      $mainTableAlias . '.attribute_id = ?',
      $attributeId
    )->where(
      $mainTableAlias . '.disabled = 0'
    )->order(
      $positionCheckSql . ' ' . \Magento\Framework\DB\Select::SQL_ASC
    );

    return $select;
  }
}

=> Now, override product-gallery.js file. So, create requirejs-config.js on this below path for add custom js :

/app/code/CompanyName/ModuleName/view/adminhtml

var config = {
    "map": {
        "*": {
            productGallery: "CompanyName_ModuleName/js/product-gallery",
        }
    }
}

=> Create product-gallery.js file on this below path :

/app/code/CompanyName/ModuleName/view/adminhtml/web/js

/**
 * Copyright © Magento, Inc. All rights reserved.
 * See COPYING.txt for license details.
 */

/**
 * @api
 */
define([
    'jquery',
    'underscore',
    'mage/template',
    'uiRegistry',
    'jquery/ui',
    'baseImage',
    'productGallery'
], function ($, _, mageTemplate, registry) {
    'use strict';


});

Then,

=> Add this line after line no 195 :

'displayimage': imageData.displayimage ? imageData.displayimage : 0,

=> Add this function after line no 515 :

$dialog.on('change', '[data-role=visibility-trigger-displayimage]', $.proxy(function (e) {
                var imageData = $dialog.data('imageData');

                this.element.trigger('updateVisibility', {
                    disabled : $("#hide-from-product-page").is(':checked'),
                    displayimage : $("#virtual-displayimage-from-product-page-"+imageData.file_id).is(':checked'),
                    imageData: imageData
                });
            }, this));

=> Add this function after line no 620 :

displayimage = +data.displayimage,

=> Add this function after line no 628 :

$imageContainer.find('[name*="displayimage"]').val(displayimage);
imageData.displayimage = displayimage;

Hope it'll help you.

This answer copy from https://magento.stackexchange.com/a/230077/67044 So, if it's fulfill your requirement then you must thanks to Rohan Hapani.

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.