Додавання елемента форми зображення до форми додавання / редагування


12

Я будую модуль CRUD для Magento 2, використовуючи компоненти ui для списку та форми адміністратора, і одна з моїх сутностей має поле зображення.
Але я не можу змусити його працювати як слід.
Ось як це має працювати.
У режимі додавання або в режимі редагування без завантаженого зображення це має виглядати як простий файл.

Коли файл завантажується, він повинен показувати попередній перегляд зображення та поле видалення під ним.

Я не шукаю саме цієї конструкції. Це може виглядати інакше, але мати однаковий функціонал.

У Magento 1 мені вдалося це зробити, просто створивши власний блок-рендерінг

class {{Namespace}}_{{Module}}_Block_Adminhtml_{{Entity}}_Helper_Image extends Varien_Data_Form_Element_Image
{
    protected function _getUrl()
    {
        $url = false;
        if ($this->getValue()) {
            $url = Mage::helper('{{namespace}}_{{module}}/{{entity}}_image')->getImageBaseUrl().$this->getValue();
        }
        return $url;
    }
}

І додаю це до мого блоку форм

    $fieldset->addType(
        'image',
        Mage::getConfig()->getBlockClassName('{{namespace}}_{{module}}/adminhtml_{{entity}}_helper_image')
    );

Але в Magento 2. у
мене немає форми форми. Я знаю, що я можу використовувати ім’я класу для поля форми у файлі компонентів ui

    <field name="image" class="Class\Name\Here">
        <argument name="data" xsi:type="array">
            <item name="config" xsi:type="array">
                <item name="dataType" xsi:type="string">text</item>
                <item name="label" xsi:type="string" translate="true">Resume</item>
                <item name="formElement" xsi:type="string">image</item>
                <item name="source" xsi:type="string">[entity]</item>
                <item name="dataScope" xsi:type="string">image</item>
            </item>
        </argument>
    </field>

Очевидно, що я маю створити цей клас, але що мені продовжувати?
Все, що я знаю, це те, що мені потрібно реалізувати інтерфейс, Magento\Framework\View\Element\UiComponentInterfaceале я не знайшов нічого, що можу розширити.
Отже, моє справжнє запитання: чи можу я розширити деякий клас, щоб досягти бажаної поведінки? Якщо ні, то як я можу розпочати створення цього елемента візуалізації?


Привіт @Marius, я спробував використати твій приклад, щоб я міг додати зображення товарів на мою сторінку редагування власної сітки, але отримав цю помилку: Фатальна помилка: Клас 'Varien_Data_Form_Element_' не знайдено у ... \ lib \ Varien \ Data \ Form \ Abstract.php на лінії 146
bestwebdevs

Відповіді:


21

Я знайшов спосіб це зробити, не вимагаючи прикріпленого до поля класу. Я маю на увазі, що до елемента форми додається клас, але не є рендерінгом.
Стовпець слід визначити так:

<field name="image">
    <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">[entity]</item>
            <item name="label" xsi:type="string" translate="true">Image</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">[Namespace]_[Module]/image-preview</item>
            <item name="required" xsi:type="boolean">false</item>
            <item name="uploaderConfig" xsi:type="array">
                <item name="url" xsi:type="url" path="[namespace_module]/[entity]_image/upload"/>
            </item>
        </item>
    </argument>
</field>

Мені також потрібно було створити файл шаблону попереднього перегляду, на який посилається [Namespace]_[Module]/image-preview.
Це app/code/[Namespace]/[Module]/view/adminhtml/web/template/image-preview.htmlвиглядає приблизно так:

<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>

Цей код генерує таке поле:

Після завантаження зображення (у режимі реального часу) воно виглядає приблизно так:

url Елемент всередині uploaderConfigє URL , де зображення розміщене при завантаженні. Тому мені потрібно було створити і це:

namespace [Namespace]\[Module]\Controller\Adminhtml\[Entity]\Image;

use Magento\Framework\Controller\ResultFactory;

/**
 * Class Upload
 */
class Upload extends \Magento\Backend\App\Action
{
    /**
     * Image uploader
     *
     * @var \[Namespace]\[Module]\Model\ImageUploader
     */
    protected $imageUploader;

    /**
     * @param \Magento\Backend\App\Action\Context $context
     * @param \[Namespace]\[Module]\Model\ImageUploader $imageUploader
     */
    public function __construct(
        \Magento\Backend\App\Action\Context $context,
        \[Namespace]\[Module]\Model\ImageUploader $imageUploader
    ) {
        parent::__construct($context);
        $this->imageUploader = $imageUploader;
    }

    /**
     * Check admin permissions for this controller
     *
     * @return boolean
     */
    protected function _isAllowed()
    {
        return $this->_authorization->isAllowed('[Namespace]_[Module]::[entity]');
    }

    /**
     * Upload file controller action
     *
     * @return \Magento\Framework\Controller\ResultInterface
     */
    public function execute()
    {
        try {
            $result = $this->imageUploader->saveFileToTmpDir('image');

            $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);
    }
}

Цей клас використовує екземпляр [Namespace]\[Module]\Model\ImageUploader, подібний до \Magento\Catalog\Model\ImageUploader.

Це шви для роботи. У мене все ще виникають проблеми із збереженням зображення в db, але це зовсім інша проблема.
Я використовував як натхнення imageполе для категорії категорії


Я можу успішно завантажувати зображення та зберігати ім'я зображення в базу даних, тоді, коли я відкриваю запис, який я щойно створив, усі поля, крім поля зображення, показують як очікувалося. Коли я зміню поле зображення на звичайне "текстове" поле, воно відобразиться. Чи маєте ви про це уявлення?
Нерон

1
@Nero. Значення зображення потрібно у певному форматі json. Ось приклад того, як можна перетворити його на належний json
Маріус

Я не хочу завантажувати зображення, але я хочу відображати зображення у формі адмініструвального інтерфейсу. Фактично я завантажую зображення із форми фронтальної форми та хочу відобразити її у формі адміністрування. Отже, будь ласка, допоможіть мені, як це зробити
Sneha Panchal

У [Простір імен] [Модуль] \ Контролер \ Adminhtml [Entity] \ Image \ upload.php на рядку номер 61 помилка 61 Перевірте та оновіть відповідь.
Принц Патель

@PrincePatel Що таке повідомлення про помилку?
Маріус

2

Так, клас, який слід розширити, - це \Magento\Ui\Component\Form\Element\AbstractElement.

Цей клас реалізує те, ElementInterfaceщо саме поширюється на яке UiComponentInterfaceви посилаєтесь.

Крім того, якщо ви перевірите декларовані під ними компоненти, Magento\Ui\Component\Form\Elementви побачите, що всі вони поширюють цей клас.

Я б вибрав цей клас, тому що renderметод \Magento\Backend\Block\Widget\Form\Renderer\Elementлише приймає такий тип класу:(Це фактично екземпляр того, Magento\Framework\Data\Form\Element\AbstractElementщо прийнято, не \Magento\Ui\Component\Form\Element\AbstractElement)


Будь-які вказівки на те, як повинен виглядати мій клас?
Маріус

@Marius hmmm Я не надто впевнений, я спробую це з'ясувати
Рафаель в Digital Pianism

1
Я не думаю, що вам цього ще потрібно робити. Я думаю, що я знайшов рішення, не використовуючи клас в компоненті ui, але мені потрібно перевірити спочатку.
Маріус

@Marius hmmmm Я думаю, що я помилявся, я вважаю, що ви повинні перевірити це: github.com/magento/magento2-samples/tree/master/…
Рафаель у Digital Pianism
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.