Question

I want to call custom block to call my custom .phtml in ui-form field.

How to do that?

My form field :

<field name="title">
    <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">Title</item>
            <item name="formElement" xsi:type="string">input</item>
            <item name="source" xsi:type="string">title</item>
            <item name="dataScope" xsi:type="string">title</item>
        </item>
    </argument>
</field>

I want to add this as html code (Go to stores -> Attributes -> Product -> Edit attribute -> Manage Labels):

enter image description here enter image description here

Any help would be appreciated.

Was it helpful?

Solution

Follow this below steps to store labels in ui form

1) Add this container in your ui form inside fieldset :

<container name="group_title_container">
   <argument name="data" xsi:type="array">
      <item name="config" xsi:type="array">
         <item name="sortOrder" xsi:type="number">20</item>
         <item name="validation" xsi:type="array">
            <item name="required-entry" xsi:type="boolean">true</item>
         </item>
      </item>
   </argument>
   <htmlContent name="group_title">
      <argument name="data" xsi:type="array">
         <item name="config" xsi:type="array">
            <item name="additionalClasses" xsi:type="string">admin__field</item>
            <item name="label" xsi:type="string" translate="true">Group Title</item>
         </item>
      </argument>
      <argument name="block" xsi:type="object">Vendor\Module\Block\Adminhtml\Custom</argument>
   </htmlContent>
</container>

Using this, you can add custom block in htmlContent

<argument name="block" xsi:type="object">Vendor\Module\Block\Adminhtml\Custom</argument>

2) Create Custom.php block file for call phtml file :

app/code/Vendor/Module/Block/Adminhtml/Custom.php

<?php
namespace Vendor\Module\Block\Adminhtml;

class Custom extends \Magento\Backend\Block\Template {
    /**
     * Block template
     *
     * @var string
     */
    protected $_template = 'custom.phtml';
}

3) Create custom.phtml file to create store label field :

app/code/Vendor/Module/view/adminhtml/templates/custom.phtml

<?php

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

// @codingStandardsIgnoreFile

?>
<?php
$objectManager = \Magento\Framework\App\ObjectManager::getInstance();
$storeManager = $objectManager->create("\Magento\Store\Model\StoreManagerInterface");
$stores = $storeManager->getStores(true, false);
?>
<label class="label admin__field-label" for="group_name" data-ui-id="adminhtml-form-renderer-fieldset-multistore-0-text-name-label"><span><?php echo __("Store Label") ?></span></label>
<div class="admin__field-control control">
    <div class="fieldset-wrapper-content in collapse" id="manage-store-labels">
        <fieldset class="admin__fieldset fieldset">
            <div class="admin__control-table-wrapper">
                <table class="admin__control-table" id="attribute-labels-table">
                    <thead>
                    <tr>
                        <?php foreach ($stores as $_store): ?>
                            <th class="col-store-view"><?= /* @escapeNotVerified */ $_store->getName() ?></th>
                        <?php endforeach; ?>
                    </tr>
                    </thead>
                    <tbody>
                    <tr>
                        <?php foreach ($stores as $_store): ?>
                            <td class="col-store-view">
                                <input class="input-text<?php if ($_store->getId() == \Magento\Store\Model\Store::DEFAULT_STORE_ID): ?> required-option<?php endif; ?>" type="text" name="frontend_label[<?= /* @escapeNotVerified */ $_store->getId() ?>]" value="<?php echo "Test"; ?>"<?php if ($block->getReadOnly()):?> disabled="disabled"<?php endif;?>/>
                            </td>
                        <?php endforeach; ?>
                    </tr>
                    </tbody>
                </table>
            </div>
        </fieldset>
    </div>
</div>

For proper layout, Add this below css code :

#manage-store-labels .admin__fieldset
        {
            padding-bottom: 0;
            padding-top: 0;
        }

Output :

enter image description here

Hope, It will helpful for you.

OTHER TIPS

You can use the htmlContent element near you field inside a fieldset, but not inside the field because of the schema restrictions:

<?xml version="1.0" ?>
<form xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Ui:etc/ui_configuration.xsd">
    <fieldset name="general">
        <field name="some_field" sortOrder="10" formElement="checkbox">
            <argument name="data" xsi:type="array">
                <item name="config" xsi:type="array">
                    <item name="source" xsi:type="string">category</item>
                    <item name="default" xsi:type="number">0</item>
                </item>
            </argument>
            <settings>
                <dataType>boolean</dataType>
                <label translate="true">Some Title</label>
            </settings>
            <formElements>
                <checkbox>
                    <settings>
                        <valueMap>
                            <map name="false" xsi:type="string">0</map>
                            <map name="true" xsi:type="string">1</map>
                        </valueMap>
                        <prefer>toggle</prefer>
                    </settings>
                </checkbox>
            </formElements>
        </field>
        <!-- Html conent (block) inside UI-form fieldset -->
        <htmlContent name="html_content">
            <block name="block_name_here" class="Magento\Backend\Block\Template" template="Vendor_Module::test.phtml"/>
        </htmlContent>
    </fieldset>
</form>

My dummy phtml-template (Vendor_Module::test.phtml):

<h3><?= __('Test Message');?></h3>

Result:

result

Elements which are available inside the <field> declared in the vendor/magento/module-ui/etc/ui_configuration.xsd:

<xs:group name="formElementsConfig">
    <xs:choice>
        <xs:element name="hidden" type="formElementHidden" maxOccurs="unbounded"/>
        <xs:element name="file" type="formElementFile" maxOccurs="unbounded"/>
        <xs:element name="input" type="formElementInput" maxOccurs="unbounded"/>
        <xs:element name="date" type="formElementDate" maxOccurs="unbounded"/>
        <xs:element name="boolean" type="formElementBoolean" maxOccurs="unbounded"/>
        <xs:element name="checkbox" type="formElementCheckbox" maxOccurs="unbounded"/>
        <xs:element name="checkboxset" type="formElementCheckboxset" maxOccurs="unbounded"/>
        <xs:element name="email" type="formElementEmail" maxOccurs="unbounded"/>
        <xs:element name="colorPicker" type="formElementColorPicker" maxOccurs="unbounded"/>
        <xs:element name="select" type="formElementSelect" maxOccurs="unbounded"/>
        <xs:element name="multiselect" type="formElementMultiselect" maxOccurs="unbounded"/>
        <xs:element name="text" type="formElementText" maxOccurs="unbounded"/>
        <xs:element name="textarea" type="formElementTextarea" maxOccurs="unbounded"/>
        <xs:element name="price" type="formElementPrice" maxOccurs="unbounded"/>
        <xs:element name="radioset" type="formElementRadioset" maxOccurs="unbounded"/>
        <xs:element name="wysiwyg" type="formElementWysiwyg" maxOccurs="unbounded"/>
        <xs:element name="fileUploader" type="formElementFileUploader" maxOccurs="unbounded"/>
        <xs:element name="imageUploader" type="formElementImageUploader" maxOccurs="unbounded"/>
        <xs:element name="button" type="formElementButton" maxOccurs="unbounded"/>
    </xs:choice>
</xs:group>

Another way is write a custom component for the input field with a custom template, add some methods which could load custom controller with your block using ajax each time when it loaded. If you share your requirements in more details I will update my answer, if I can :)

Here is example:

Add inside ui-form new field:

<htmlContent name="example_title">
    <argument name="block" xsi:type="object">MageWorx\ShippingRules\Block\Adminhtml\Shippingrules\Carrier\Edit\Tab\ExampleTitle</argument>
</htmlContent>

Create corresponding block:

app/code/MageWorx/ShippingRules/Block/Adminhtml/Shippingrules/Carrier/Edit/Tab/ExampleTitle.php

<?php
/**
 * Copyright © MageWorx. All rights reserved.
 * See LICENSE.txt for license details.
 */

namespace MageWorx\ShippingRules\Block\Adminhtml\Shippingrules\Carrier\Edit\Tab;

use Magento\Backend\Block\Template;

/**
 * Class ExampleTitle
 */
class ExampleTitle extends Template
{
    /**
     * @var string
     */
    protected $_template = 'MageWorx_ShippingRules::example_title.phtml';

    /**
     * Use your ui-form name
     *
     * @var string
     */
    protected $dataFormPart = 'mageworx_shippingrules_carrier_form';

    /**
     * Use your data source name
     *
     * @var string
     */
    protected $source = 'carrier';

    /**
     * Retrieve stores collection with default store
     *
     * @return \Magento\Store\Model\ResourceModel\Store\Collection
     */
    public function getStores()
    {
        if (!$this->hasStores()) {
            $this->setData('stores', $this->_storeManager->getStores());
        }
        return $this->_getData('stores');
    }

    /**
     * @return array
     */
    public function getValues(): array
    {
        // Next part of data must be obtained from your object!
        // Data exist as an example
        $values = [
            0 => 'Main Title'
        ];
        // Next part of data must be obtained from your object!
        // Data exist as an example
        $storeValues = [
            1 => 'Label One',
            3 => 'Label Three',
        ];

        foreach ($this->getStores() as $store) {
            if ($store->getId() != 0) {
                $values[$store->getId()] = isset($storeValues[$store->getId()]) ? $storeValues[$store->getId()] : '';
            }
        }

        return $values;
    }

    /**
     * @return string
     */
    public function getDataFormPart(): string
    {
        return $this->dataFormPart;
    }

    /**
     * @return string
     */
    public function getSource(): string
    {
        return $this->source;
    }
}

and template:

app/code/MageWorx/ShippingRules/view/adminhtml/templates/example_title.phtml

<?php
/** @var \MageWorx\ShippingRules\Block\Adminhtml\Shippingrules\Carrier\Edit\Tab\ExampleTitle $block */
?>
<?php

use Magento\Store\Model\Store;

?>
<div class="admin__field-control">
    <table class="admin__field-control admin__control-table" id="attribute-labels-table">
        <thead>
        <tr>
            <th class="col-store-view"><?= $block->escapeHtml(__('Main Value (Admin)')); ?></th>
            <?php foreach ($block->getStores() as $store): ?>
                <th class="col-store-view"><?= $block->escapeHtml($store->getName()); ?></th>
            <?php endforeach; ?>
        </tr>
        </thead>
        <tbody>
        <tr>
            <?php $titles = $block->getValues(); ?>
            <td class="col-store-view">
                <input class="admin__control-text input-text required-option"
                       type="text"
                       data-form-part="<?= $block->escapeHtml($block->getDataFormPart())?>"
                       name="<?= $block->escapeHtmlAttr($block->getSource());?>[example_title][<?= /* @noEscape */
                       (string)Store::DEFAULT_STORE_ID ?>]"
                       value="<?= $block->escapeHtml($titles[Store::DEFAULT_STORE_ID] ?? '') ?>"
                />
            </td>
            <?php foreach ($block->getStores() as $store): ?>
                <td class="col-store-view">
                    <input class="admin__control-text input-text<?php if ($store->getId(
                        ) == Store::DEFAULT_STORE_ID): ?> required-option<?php endif; ?>"
                           type="text"
                           data-form-part="<?= $block->escapeHtml($block->getDataFormPart())?>"
                           name="<?= $block->escapeHtmlAttr($block->getSource());?>[example_title][<?= /* @noEscape */
                           $store->getId() ?>]"
                           value="<?= $block->escapeHtml($titles[$store->getId()]) ?>"
                        <?php if ($block->getReadOnly()): ?> disabled="disabled"<?php endif; ?>
                    />
                </td>
            <?php endforeach; ?>
        </tr>
        </tbody>
    </table>
</div>

Do not forget to change the protected $dataFormPart = 'mageworx_shippingrules_carrier_form'; and protected $source = 'carrier'; according your ui-form settings. Implement method which load data from a model.

Field on the form will be looking like this:

form example with new fields

Data could be obtained from the post in your controller:

request headers

post data in controller xdebug

Licensed under: CC-BY-SA with attribution
Not affiliated with magento.stackexchange
scroll top