Aggiunta di un elemento del modulo immagine a un modulo Aggiungi / Modifica


12

Sto costruendo un modulo CRUD per Magento 2 utilizzando i componenti dell'interfaccia utente per l'elenco e il modulo di amministrazione e una delle mie entità ha un campo immagine.
Ma non posso farlo funzionare come dovrebbe.
Ecco come dovrebbe funzionare.
In modalità Aggiungi o Modifica senza immagini caricate, dovrebbe apparire come un semplice input di file.

Quando un file viene caricato, dovrebbe mostrare l'anteprima dell'immagine e una casella di eliminazione sotto di essa.

Non sto cercando esattamente questo design. Potrebbe avere un aspetto diverso ma avere la stessa funzionalità.

In Magento 1 sono stato in grado di farlo, semplicemente creando il mio renderizzatore di blocchi

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

E aggiungendo questo nel mio blocco di moduli

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

Ma non ho un blocco modulo in Magento 2.
So che posso usare un nome di classe per un campo modulo nel file dei componenti dell'interfaccia utente

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

Ovviamente devo creare questa classe, ma cosa dovrei estendere?
Tutto quello che so è che devo implementare l'interfaccia Magento\Framework\View\Element\UiComponentInterfacema non ho trovato nulla da estendere.
Quindi la mia vera domanda è: posso estendere un po 'di classe per ottenere il comportamento desiderato? In caso contrario, come posso iniziare a creare questo renderer di elementi?


Ciao @Marius, ho provato a usare il tuo esempio per poter aggiungere immagini di prodotto nella mia pagina di modifica della griglia personalizzata, ma ho riscontrato questo errore: Errore irreversibile: classe 'Varien_Data_Form_Element_' non trovata in ... \ lib \ Varien \ Data \ Form \ Abstract.php sulla linea 146
bestwebdevs

Risposte:


21

Ho trovato un modo per farlo senza richiedere una classe collegata al campo. Voglio dire, esiste una classe collegata all'elemento form ma non come renderer.
La colonna dovrebbe essere definita come questa:

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

Avevo anche bisogno di creare il file modello di anteprima a cui fa riferimento [Namespace]_[Module]/image-preview.
Ecco app/code/[Namespace]/[Module]/view/adminhtml/web/template/image-preview.htmlcome appare:

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

Questo codice genererà un campo come questo:

Dopo aver caricato un'immagine (in tempo reale) è simile al seguente:

L' url elemento all'interno di uploaderConfigè l'URL in cui è postata l'immagine quando viene caricata. Quindi ho dovuto creare anche questo:

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

Questa classe utilizza un'istanza [Namespace]\[Module]\Model\ImageUploadersimile a \Magento\Catalog\Model\ImageUploader.

Questo giunge al lavoro. Ho ancora problemi nel salvare l'immagine nel db, ma questo è un problema completamente diverso.
Ho usato come ispirazione il imagecampo per l'entità categoria


Posso caricare correttamente l'immagine e salvare il nome dell'immagine nel database, quindi quando apro il record che ho appena creato, tutti i campi diversi dal campo immagine vengono visualizzati come previsto. Quando cambio il campo immagine in un normale campo "testo", allora verrà visualizzato. Ne hai idea?
Nero,

1
@Nero. È necessario il valore dell'immagine in un determinato formato json. Ecco un esempio di come puoi trasformarlo nel vero json
Marius

Non voglio caricare un'immagine ma voglio immagine visualizzata in Admin Ui form.Actually posso caricare un'immagine dal modulo frontend e voglio visualizzare in interfaccia utente amministrativa form.So Please help me come fare
Sneha Panchal

Si è verificato un errore in [Spazio dei nomi] [Modulo] \ Controller \ Adminhtml [Entità] \ Immagine \ upload.php sulla riga numero 61 Controllare e aggiornare la risposta.
Prince Patel,

@PrincePatel Qual è il messaggio di errore?
Marius

2

Sì, la classe che dovresti estendere è \Magento\Ui\Component\Form\Element\AbstractElement.

Questa classe implementa ciò a ElementInterfacecui esso stesso estende il UiComponentInterfaceriferimento.

Inoltre, se controlli i componenti dichiarati sotto Magento\Ui\Component\Form\Elementpuoi vedere che estendono tutti quella classe.

Il motivo per cui sceglierei questa classe è perché il rendermetodo \Magento\Backend\Block\Widget\Form\Renderer\Elementaccetta solo questo tipo di classe:(Questa è in realtà un'istanza Magento\Framework\Data\Form\Element\AbstractElementaccettata, non \Magento\Ui\Component\Form\Element\AbstractElement)


Qualche suggerimento su come dovrebbe apparire la mia classe?
Marius

@Marius hmmm Non sono troppo sicuro, proverò a scoprirlo
Raffaello al Pianismo digitale

1
Non penso che tu debba ancora farlo. Penso di aver trovato una soluzione senza usare una classe nel componente dell'interfaccia utente, ma devo prima provare.
Marius

@Marius hmmmm Penso di aver sbagliato, penso che dovresti dare un'occhiata: github.com/magento/magento2-samples/tree/master/…
Raffaello al Pianismo digitale
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.