画像フォーム要素を追加/編集フォームに追加する


12

管理者リストとフォームのUIコンポーネントを使用してMagento 2のCRUDモジュールを構築しており、エンティティの1つに画像フィールドがあります。
しかし、私はそれを正常に機能させることはできません。
動作方法は次のとおりです。
アップロードされた画像のない追加モードまたは編集モードでは、単純なファイル入力のように見えるはずです。

ファイルがアップロードされると、画像プレビューとその下の削除ボックスが表示されます。

まさにこのデザインを探しているわけではありません。見た目は異なりますが、機能は同じです。

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に見つかりません146行目の\ Abstract.php
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

これでうまくいく。私はまだデータベースに画像を保存するのに苦労していますが、それは全く異なる問題です。カテゴリエンティティのフィールドを
インスピレーションとして使用しimageました


画像を正常にアップロードしてデータベースに保存できます。作成したばかりのレコードを開くと、画像フィールド以外のすべてのフィールドが期待どおりに表示されます。画像フィールドを通常の「テキスト」フィールドに変更すると、表示されます。これについて何かご存知ですか?
ネロ

1
@Nero。特定のjson形式の画像値が必要です。ここでは一例であり、あなたが適切なJSONに変換する方法については
マリウス

行うにはどのように私を助けてください、私は、画像をアップロードする必要はありませんが、私は管理UI form.Actuallyで表示画像にしたい私は、フロントエンドのフォームから画像をアップロードして管理UI form.Soでそれを表示したい
スネハPanchal

[Namespace] [Module] \ Controller \ Adminhtml [Entity] \ Image \ upload.phpに行番号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うーん、私はよくわからない、私は見つけようとします
デジタルピアニズムのラファエル

1
まだそうする必要はないと思います。UIコンポーネントでクラスを使用せずに解決策を見つけたと思いますが、最初にテストする必要があります。
マリウス

@Mariusうーん、私は間違っていたと思う、github.com / magento / magento2
Digital Pianismでのラファエル
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.