Menambahkan elemen bentuk gambar ke formulir tambah / edit

12

Saya sedang membangun modul CRUD untuk Magento 2 menggunakan komponen ui untuk daftar dan formulir admin dan salah satu entitas saya memiliki bidang gambar.
Tetapi saya tidak bisa membuatnya berfungsi sebagaimana mestinya.
Inilah cara kerjanya.
Ketika dalam mode tambah atau mode edit tanpa gambar yang diunggah, tampilannya akan tampak seperti input file sederhana.

Ketika sebuah file diunggah, ia harus memperlihatkan pratinjau gambar dan kotak hapus di bawahnya.

Saya tidak mencari desain ini persis. Itu bisa terlihat berbeda tetapi memiliki fungsi yang sama.

Di Magento 1 saya bisa melakukan ini, hanya dengan membuat block renderer saya sendiri

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

Dan menambahkan ini di blok formulir saya

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

Tapi saya tidak punya blok formulir di Magento 2.
Saya tahu saya bisa menggunakan nama kelas untuk bidang formulir di file komponen 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>

Jelas saya harus membuat kelas ini, tetapi apa yang harus saya sampaikan?
Yang saya tahu adalah saya perlu mengimplementasikan antarmuka Magento\Framework\View\Element\UiComponentInterfacetetapi saya tidak menemukan apa pun yang dapat saya kembangkan.
Jadi pertanyaan saya yang sebenarnya adalah: Dapatkah saya memperluas beberapa kelas untuk mencapai perilaku yang diinginkan? Jika tidak, bagaimana saya bisa mulai membuat elemen renderer ini?

Marius
sumber
Hai @Marius, saya mencoba menggunakan contoh Anda untuk dapat menambahkan gambar produk di halaman edit kisi kustom saya, tetapi mendapat kesalahan ini: Kesalahan fatal: Kelas 'Varien_Data_Form_Element_' tidak ditemukan di ... \ lib \ Varien \ Data \ Form \ Abstract.php on line 146
bestwebdevs

Jawaban:

21

Saya menemukan cara untuk melakukannya tanpa memerlukan kelas yang terpasang di lapangan. Maksud saya ada kelas yang dilampirkan ke elemen form tetapi tidak sebagai renderer.
Kolom harus didefinisikan sebagai ini:

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

Saya juga perlu membuat file templat pratinjau yang direferensikan oleh [Namespace]_[Module]/image-preview.
Itu app/code/[Namespace]/[Module]/view/adminhtml/web/template/image-preview.htmlyang terlihat seperti ini:

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

Kode ini akan menghasilkan bidang seperti ini:

Setelah mengunggah gambar (waktu nyata) seperti ini:

The url Item dalam uploaderConfigadalah url di mana foto tersebut diposting ketika upload. Jadi saya perlu membuat ini juga:

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

Kelas ini menggunakan instance [Namespace]\[Module]\Model\ImageUploaderyang mirip dengan \Magento\Catalog\Model\ImageUploader.

Ini bekerja. Saya masih kesulitan menyimpan gambar di db tapi itu masalah yang sama sekali berbeda.
Saya digunakan sebagai inspirasi imagebidang untuk entitas kategori

Marius
sumber
Saya dapat dengan sukses mengunggah gambar dan menyimpan nama gambar ke dalam basis data, lalu ketika saya membuka catatan saya baru saja membuat, semua bidang selain bidang gambar semuanya ditampilkan seperti yang diharapkan. Ketika saya mengubah bidang gambar menjadi bidang "teks" biasa, maka itu akan ditampilkan. Apakah Anda punya ide tentang ini?
Nero
1
@ Tidak. Anda memerlukan nilai gambar dalam format json tertentu. Berikut ini adalah contoh bagaimana Anda dapat mengubahnya menjadi json yang tepat
Marius
Saya tidak ingin mengunggah gambar tetapi saya ingin menampilkan gambar di formulir admin Ui. Sebenarnya saya mengunggah gambar dari formulir frontend dan ingin menampilkannya di formulir admin ui. Jadi tolong bantu saya bagaimana melakukannya
Sneha Panchal
Ada kesalahan dalam [Namespace] [Module] \ Controller \ Adminhtml [Entity] \ Image \ upload.php pada nomor baris 61. Silakan periksa dan perbarui jawaban.
Pangeran Patel
@ PrincePatel Apa pesan kesalahannya?
Marius
2

Ya, kelas yang harus Anda perpanjang adalah \Magento\Ui\Component\Form\Element\AbstractElement.

Kelas ini mengimplementasikan yang ElementInterfacemana itu sendiri memperluas yang UiComponentInterfaceAnda maksud.

Selain itu, jika Anda memeriksa komponen yang dideklarasikan di bawah Magento\Ui\Component\Form\ElementAnda dapat melihat bahwa mereka semua memperluas kelas itu.

Alasan saya memilih kelas ini adalah karena rendermetode \Magento\Backend\Block\Widget\Form\Renderer\Elementhanya menerima jenis kelas seperti itu:(Ini sebenarnya adalah contoh Magento\Framework\Data\Form\Element\AbstractElementyang diterima, bukan \Magento\Ui\Component\Form\Element\AbstractElement)

Raphael di Digital Pianism
sumber
Adakah petunjuk tentang bagaimana kelas saya seharusnya terlihat?
Marius
@Marius hmmm Saya tidak terlalu yakin, saya akan mencoba mencari tahu
Raphael di Digital Pianism
1
Saya pikir Anda belum perlu melakukan itu. Saya pikir saya menemukan solusi tanpa menggunakan kelas di komponen ui, tetapi saya perlu menguji dulu.
Marius
@Marius hmmmm Saya pikir saya salah, saya rasa Anda harus memeriksanya: github.com/magento/magento2-samples/tree/master/…
Raphael di Digital Pianism