Magento 2 UiComponent form with tabs has empty fields - forms

I have and issue with empty form fields when I'm using tabs.
If I removing tabs usage, fields contains correct values.
My form uicomponent is large, so I will paste only important parts of configuration:
<argument name="data" xsi:type="array">
<item name="js_config" xsi:type="array">
<item name="provider" xsi:type="string">vendor_modulename_form.vendor_modulename_form_data_source</item>
</item>
<item name="label" xsi:type="string" translate="true">Item</item>
...
</argument>
<settings>
...
<namespace>vendor_modulename_form</namespace>
<dataScope>data</dataScope>
<deps>
<dep>vendor_modulename_form.vendor_modulename_form_data_source</dep>
</deps>
<layout>
<navContainerName>left</navContainerName>
<type>tabs</type>
</layout>
</settings>
<fieldset name="modules">
<settings>
<collapsible>true</collapsible>
<opened>true</opened>
<label translate="true">Details</label>
</settings>
<field name="name" formElement="input">
<argument name="data" xsi:type="array">
<item name="config" xsi:type="array">
<item name="source" xsi:type="string">module</item>
</item>
</argument>
<settings>
<dataType>text</dataType>
<label translate="true">Name</label>
<dataType>text</dataType>
<visible>true</visible>
<dataScope>name</dataScope>
</settings>
</field>
...
</fieldset>
Console log and magento logs are empty. I'm working in developer mode.
Any ideas?

In the dataprovider you have to wrap all the content of your fieldset with the key after loading the data.
Eg:
$id = $this->request->getParam('id');
/** #var Collection $items */
$items = $this->collectionFactory->create()->addFieldToFilter('id', $id)->getItems();
foreach ($items as $item) {
$formData['modules'] = $item->getData();
$this->loadedData[$item->getId()] = $formData;
}

Related

magento 2 admin form ui component

I want to create ui component with tabs.
I want to my base data shows in general tabs and additional in next.
ui component
<?xml version="1.0" encoding="UTF-8"?>
<form xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Ui:etc/ui_configuration.xsd">
<argument name="data" xsi:type="array">
<item name="js_config" xsi:type="array">
<item name="provider" xsi:type="string">my_blog_form.my_blog_listing_data_source</item>
<item name="deps" xsi:type="string">my_blog_form.my_blog_listing_data_source</item>
</item>
<item name="label" xsi:type="string" translate="true">General</item>
<item name="layout" xsi:type="array">
<item name="type" xsi:type="string">tabs</item>
<item name="navContainerName" xsi:type="string">left</item>
</item>
<item name="buttons" xsi:type="array">
<item name="save" xsi:type="array">
<item name="name" xsi:type="string">save</item>
<item name="label" xsi:type="string" translate="true">Save</item>
<item name="class" xsi:type="string">primary</item>
<item name="url" xsi:type="string">*/*/save</item>
</item>
</item>
</argument>
<dataSource name="my_blog_form_data_source">
<argument name="dataProvider" xsi:type="configurableObject">
<argument name="class" xsi:type="string">MY\Blog\Ui\DataProvider</argument>
<argument name="name" xsi:type="string">my_blog_form_data_source</argument>
<argument name="primaryFieldName" xsi:type="string">id</argument>
<argument name="requestFieldName" xsi:type="string">id</argument>
<argument name="collectionFactory" xsi:type="object">
\MY\Blog\Model\Post\ResourceModel\Post\CollectionFactory
</argument>
</argument>
</dataSource>
<fieldset name="general">
<argument name="data" xsi:type="array">
<item name="config" xsi:type="array">
<item name="label" xsi:type="string" translate="true">Sample Fieldset</item>
</item>
</argument>
<!-- This field has data type 'text' and standard 'input' form element and looks like input -->
<field name="title">
<argument name="data" xsi:type="array">
<item name="config" xsi:type="array">
<item name="label" xsi:type="string">Title</item>
<item name="visible" xsi:type="boolean">true</item>
<item name="dataType" xsi:type="string">text</item>
<item name="formElement" xsi:type="string">input</item>
<item name="source" xsi:type="string">title</item>
</item>
</argument>
</field>
</fieldset>
</form>
Corresponding dataSource
<?php
namespace MY\Blog\Ui;
use Magento\Ui\DataProvider\AbstractDataProvider;
use \My\Blog\Model\Post\ResourceModel\Post\CollectionFactory;
class DataProvider extends AbstractDataProvider
{
protected $collection;
public function __construct(
$name,
$primaryFieldName,
$requestFieldName,
CollectionFactory $collectionFactory,
array $meta = [],
array $data = []
) {
parent::__construct($name, $primaryFieldName, $requestFieldName, $meta, $data);
$this->collection = $collectionFactory->create();
}
public function getData()
{
return [];
$results = [];
// var_dump($this->collection->getItems());die();
foreach ($this->collection->getItems() as $item) {
$results[$item->getId()]['general'] = $item->getData();
}
return $results;
}
}
I don't see any tabs and spinner never stops. What am I missing here I got 0 console errors. Model works because I have working data grid that shows my data.
Add this in your form XML
<settings>
<deps>
<dep>my_blog_form.my_blog_listing_data_source</dep>
</deps>
<layout>
<navContainerName>left</navContainerName>
<type>tabs</type>
</layout>
</settings>
set layout 2-column left like this
<?xml version="1.0"?>
<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" layout="admin-2columns-left" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
<body>
<referenceContainer name="content">
<uiComponent name="your_form_name" />
</referenceContainer>
</body>
</page>

Orbeon form, show first element of dropdown menu

How to show first element of dropdown menu instead of "Please select"?
I am loading elements in 2 dropdown menus like this:
<xf:instance id="makes">
<root>
<item name="Tesla" value="Tesla"/>
<item name="Toyota" value="Toyota"/>
<item name="Suzuki" value="Suzuki"/>
<item name="Jeep" value="Jeep"/>
<item name="Alfa" value="Alfa"/>
</root>
</xf:instance>
<xf:instance id="models">
<root>
<item makeValue="Tesla" modelValue="Tesla S" modelName="Tesla S"/>
<item makeValue="Tesla" modelValue="Tesla X" modelName="Tesla X"/>
<item makeValue="Tesla" modelValue="Tesla Roadster" modelName="Tesla Roadster"/>
<item makeValue="Alfa" modelValue="Brera" modelName="Brera" />
<item makeValue="Alfa" modelValue="Giulietta" modelName="Giulietta"/>
<item makeValue="Alfa" modelValue="Spider" modelName="Spider"/>
<item makeValue="Alfa" modelValue="MiTo" modelName="MiTo"/>
<item makeValue="Alfa" modelValue="GT" modelName="GT"/>
<item makeValue="Suzuki" modelValue="Swift" modelName="Swift"/>
<item makeValue="Suzuki" modelValue="Samurai" modelName="Samurai"/>
<item makeValue="Suzuki" modelValue="Vitara" modelName="Vitara" />
<item makeValue="Toyota" modelValue="Corolla Verso" modelName="Corolla Verso"/>
<item makeValue="Toyota" modelValue="Aygo" modelName="Aygo" />
<item makeValue="Toyota" modelValue="Yaris" modelName="Yaris" />
<item makeValue="Toyota" modelValue="Avensis" modelName="Avensis"/>
<item makeValue="Toyota" modelValue="Rav4" modelName="Rav4"/>
<item makeValue="Jeep" modelValue="Grand Cherokee" modelName="Grand Cherokee"/>
<item makeValue="Jeep" modelValue="Commander" modelName="Commander"/>
<item makeValue="Jeep" modelValue="Compass" modelName="Compass"/>
<item makeValue="Jeep" modelValue="Liberty" modelName="Liberty"/>
<item makeValue="Jeep" modelValue="Patriot" modelName="Patriot"/>
<item makeValue="Jeep" modelValue="Renegade" modelName="Renegade"/>
</root>
</xf:instance>
And than bind them:
<xh:tr>
<xh:td>
<xf:select1 id="vehicle-make-control" bind="vehicle-make-bind" appearance="dropdown">
<xf:label ref="$form-resources/vehicle-make/label"/>
<xf:hint ref="$form-resources/vehicle-make/hint"/>
<xf:alert ref="$fr-resources/detail/labels/alert"/>
<xf:itemset ref="instance('makes')/item">
<xf:label ref="#name"/>
<xf:value ref="#value"/>
</xf:itemset>
</xf:select1>
</xh:td>
</xh:tr>
Same thing is for models, just control name is vehicle-model.
When i select vehicle make i got appropriate models for specified veh. make, but first element is please select of blank. I need to show Tesla S as first when Tesla is selected etc.
To have it like this:
OPEN PICTURE.
I set in initial value XPath expression $(.)[1] but it is not working.
I imagine this is for a form you created with Form Builder, and to which you added the <xf:instance id="makes"> and <xf:instance id="models"> by editing the source of the form.
If so, if you want the dropdowns to have the first item as their initial value, instead of "Please select", then you'll want to set the initial value of the field to the value of the first item. You can do so in the Control Settings dialog, in the Formulas tab. You can do so with an expression like:
instance('makes')/item[1]/#value

In Magento2 (2.2.5) uicomponent form in frontend, SAVE button not appearing with form

I added uiform in frontend. Form is loading but save button is not appearing. Code details:
1. employee_form.xml code:
<argument name="data" xsi:type="array">
<item name="js_config" xsi:type="array">
<item name="provider" xsi:type="string">employee_form.employee_form_data_source</item>
</item>
<item name="label" xsi:type="string" translate="true">Assign Product Form</item>
<item name="template" xsi:type="string">templates/form/collapsible</item>
<item name="spinner" xsi:type="string">uiform_index_columns2</item>
</argument>
<settings>
<buttons>
<button name="save" class="Cn\Uiform\Block\Employee\Form\SaveButton"/>
<button name="back">
<url path="*/*/"/>
<class>back</class>
<label translate="true">Back</label>
</button>
</buttons>
<namespace>employee_form</namespace>
<dataScope>data</dataScope>
<deps>
<dep>employee_form.employee_form_data_source</dep>
</deps>
</settings>
<dataSource name="employee_form_data_source">
<argument name="data" xsi:type="array">
<item name="js_config" xsi:type="array">
<item name="component" xsi:type="string">Magento_Ui/js/form/provider</item>
</item>
</argument>
<settings>
<submitUrl path="*/*/save"/>
</settings>
<dataProvider class="Cn\Uiform\Model\DataProvider" name="employee_form_data_source">
<settings>
<primaryFieldName>id</primaryFieldName>
<requestFieldName>id</requestFieldName>
</settings>
</dataProvider>
</dataSource>
2. DataProvide.php methods code
public function prepareMeta(array $meta) {
return $meta;
}
public function getData() {
return [];
}
3. SaveButton.php class code
use Magento\Framework\View\Element\UiComponent\Control\ButtonProviderInterface;
class SaveButton extends GenericButton implements ButtonProviderInterface {
public function getButtonData() {
return [
'label' => __('Save Slide'),
'class' => 'save primary',
'data_attribute' => [
'mage-init' => ['button' => ['event' => 'save']],
'form-role' => 'save',
],
'sort_order' => 90,
];
}
}
4. di.xml
<!--for edit uiform-->
<type name="Magento\Framework\View\Element\UiComponent\DataProvider\CollectionFactory">
<arguments>
<argument name="collections" xsi:type="array">
<item name="employee_form_data_source" xsi:type="string">Cn\Uiform\Model\ResourceModel\Employee\Collection</item>
</argument>
</arguments>
</type>
=> But, the ui form is loading without SAVE button.
For displaying buttons on frontend UI component form. You have to add a Container reference in your layout.
<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
<body>
<referenceContainer name="page.main.actions">
<block class="Magento\Framework\View\Element\Template" name="page.actions.toolbar" template="Magento_Backend::pageactions.phtml"/>
</referenceContainer>
<referenceContainer name="admin.scope.col.wrap" htmlClass="admin__old" />
<referenceContainer name="content">
<uiComponent name="employee_form"/>
</referenceContainer>
</body>
</page>
I've never implemented IU components on the frontend, but as far as the backend goes, my own forms have the buttons included inside the 'data' argument. E.g.
<argument name="data" xsi:type="array">
<item name="buttons" xsi:type="arrayā€¯>
<item name="save" xsi:type="string">Cn\Uiform\Block\Employee\Form\SaveButton</item>
</item>
</argument>

Magento2 : Custom Image Attribute in Category Not Saving?

I have create an custom image attribute in category and image uploaded successfully but it's saving Database. Can anyone guide me what is the issue in below code.
path:- /app/code/Catattribute/Catthumbnail/Setup/InstallData.php
namespace Catattribute\Catthumbnail\Setup;
use Magento\Eav\Setup\EavSetup;
use Magento\Eav\Setup\EavSetupFactory;
use Magento\Framework\Module\Setup\Migration;
use Magento\Framework\Setup\InstallDataInterface;
use Magento\Framework\Setup\ModuleContextInterface;
use Magento\Framework\Setup\ModuleDataSetupInterface;
use Magento\Catalog\Setup\CategorySetupFactory;
class InstallData implements InstallDataInterface
{
private $eavSetupFactory;
public function __construct(CategorySetupFactory $categorySetupFactory)
{
$this->categorySetupFactory = $categorySetupFactory;
}
public function install(ModuleDataSetupInterface $setup, ModuleContextInterface $context)
{
$installer = $setup;
$setup->startSetup();
$categorySetup = $this->categorySetupFactory->create(['setup' => $setup]);
$entityTypeId = $categorySetup->getEntityTypeId(\Magento\Catalog\Model\Category::ENTITY);
$attributeSetId = $categorySetup->getDefaultAttributeSetId($entityTypeId);
$categorySetup->removeAttribute(
\Magento\Catalog\Model\Category::ENTITY, 'image_thumb' );
$categorySetup->addAttribute(
\Magento\Catalog\Model\Category::ENTITY, 'image_thumb', [
'type' => 'varchar',
'label' => 'Thumbnail Image',
'input' => 'image',
'backend' => 'Magento\Catalog\Model\Category\Attribute\Backend\Image',
'required' => false,
'sort_order' => 5,
'global' => \Magento\Eav\Model\Entity\Attribute\ScopedAttributeInterface::SCOPE_STORE,
'group' => 'General Information',
]
);
$setup->endSetup();
}
}
path:- /app/code/Catattribute/Catthumbnail/view/adminhtml/ui_component/category_form.xml
<?xml version="1.0" encoding="UTF-8"?>
<form xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Ui:etc/ui_configuration.xsd">
<fieldset name="content">
<argument name="data" xsi:type="array">
<item name="config" xsi:type="array">
<item name="label" xsi:type="string" translate="true">Content</item>
<item name="collapsible" xsi:type="boolean">true</item>
<item name="sortOrder" xsi:type="number">10</item>
</item>
</argument>
<field name="image_thumb">
<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">category</item>
<item name="label" xsi:type="string" translate="true">Thumbnail 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">Magento_Catalog/image-preview</item>
<item name="required" xsi:type="boolean">false</item>
<item name="sortOrder" xsi:type="number">40</item>
<item name="uploaderConfig" xsi:type="array">
<item name="url" xsi:type="url" path="catthumbnail/category_thumb/upload"/>
</item>
</item>
</argument>
</field>
</fieldset>
</form>

Adding a new input form to checkout in magento 2

Want to add an input form to checkout page for updating the shipping price. So far, I have done the following modifications :
1) Created /view/frontend/web/js/custom-checkout-form.js file and added the following code:
define(
[
'ko',
'uiComponent',
'underscore',
'Magento_Checkout/js/model/step-navigator'
],
function (
ko,
Component,
_,
stepNavigator
) {
'use strict';
/**
*
* mystep - is the name of the component's .html template,
* your_module_dir - is the name of the your module directory.
*
*/
return Component.extend({
defaults: {
template: 'your_module_dir/mystep'
},
//add here your logic to display step,
isVisible: ko.observable(true),
/**
*
* #returns {*}
*/
initialize: function () {
this._super();
// register your step
stepNavigator.registerStep(
//step code will be used as step content id in the component template
'step_code',
//step alias
null,
//step title value
'Step Title',
//observable property with logic when display step or hide step
this.isVisible,
_.bind(this.navigate, this),
/**
* sort order value
* 'sort order value' < 10: step displays before shipping step;
* 10 < 'sort order value' < 20 : step displays between shipping and payment step
* 'sort order value' > 20 : step displays after payment step
*/
15
);
return this;
},
/**
* The navigate() method is responsible for navigation between checkout step
* during checkout. You can add custom logic, for example some conditions
* for switching to your custom step
*/
navigate: function () {
},
/**
* #returns void
*/
navigateToNextStep: function () {
stepNavigator.next();
}
});
}
);
2) Created the HTML template /view/frontend/web/template/custom-checkout-form.html
<div>
<form id="custom-checkout-form" class="form" data-bind="attr: {'data-hasrequired': $t('* Required Fields')}">
<fieldset class="fieldset">
<legend data-bind="i18n: 'Custom Checkout Form'"></legend>
<!-- ko foreach: getRegion('custom-checkout-form-fields') -->
<!-- ko template: getTemplate() --><!-- /ko -->
<!--/ko-->
</fieldset>
<button type="reset">
<span data-bind="i18n: 'Reset'"></span>
</button>
<button type="button" data-bind="click: onSubmit" class="action">
<span data-bind="i18n: 'Submit'"></span>
</button>
</form>
</div>
3) Deleted all files in the pub/static/frontend and var/view_preprocessing directories. Reloaded the pages.
4) Created a checkout_index_index.xml layout update in the /view/frontend/layout/
<?xml version="1.0"?>
<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
<body>
<referenceBlock name="checkout.root">
<arguments>
<argument name="jsLayout" xsi:type="array">
<item name="components" xsi:type="array">
<item name="checkout" xsi:type="array">
<item name="children" xsi:type="array">
<item name="steps" xsi:type="array">
<item name="children" xsi:type="array">
<item name="shipping-step" xsi:type="array">
<item name="children" xsi:type="array">
<item name="shippingAddress" xsi:type="array">
<item name="children" xsi:type="array">
<item name="before-form" xsi:type="array">
<item name="children" xsi:type="array">
<!-- Your form declaration here -->
<item name="custom-checkout-form-container" xsi:type="array">
<item name="component" xsi:type="string">%your_module_dir%/js/view/custom-checkout-form</item>
<item name="provider" xsi:type="string">checkoutProvider</item>
<item name="config" xsi:type="array">
<item name="template" xsi:type="string">%your_module_dir%/custom-checkout-form</item>
</item>
<item name="children" xsi:type="array">
<item name="custom-checkout-form-fieldset" xsi:type="array">
<!-- uiComponent is used as a wrapper for form fields (its template will render all children as a list) -->
<item name="component" xsi:type="string">uiComponent</item>
<!-- the following display area is used in template (see below) -->
<item name="displayArea" xsi:type="string">custom-checkout-form-fields</item>
<item name="children" xsi:type="array">
<item name="text_field" xsi:type="array">
<item name="component" xsi:type="string">Magento_Ui/js/form/element/abstract</item>
<item name="config" xsi:type="array">
<!-- customScope is used to group elements within a single form (e.g. they can be validated separately) -->
<item name="customScope" xsi:type="string">customCheckoutForm</item>
<item name="template" xsi:type="string">ui/form/field</item>
<item name="elementTmpl" xsi:type="string">ui/form/element/input</item>
</item>
<item name="provider" xsi:type="string">checkoutProvider</item>
<item name="dataScope" xsi:type="string">customCheckoutForm.text_field</item>
<item name="label" xsi:type="string">Text Field</item>
<item name="sortOrder" xsi:type="string">1</item>
<item name="validation" xsi:type="array">
<item name="required-entry" xsi:type="string">true</item>
</item>
</item>
<item name="checkbox_field" xsi:type="array">
<item name="component" xsi:type="string">Magento_Ui/js/form/element/boolean</item>
<item name="config" xsi:type="array">
<!--customScope is used to group elements within a single form (e.g. they can be validated separately)-->
<item name="customScope" xsi:type="string">customCheckoutForm</item>
<item name="template" xsi:type="string">ui/form/field</item>
<item name="elementTmpl" xsi:type="string">ui/form/element/checkbox</item>
</item>
<item name="provider" xsi:type="string">checkoutProvider</item>
<item name="dataScope" xsi:type="string">customCheckoutForm.checkbox_field</item>
<item name="label" xsi:type="string">Checkbox Field</item>
<item name="sortOrder" xsi:type="string">3</item>
</item>
<item name="select_field" xsi:type="array">
<item name="component" xsi:type="string">Magento_Ui/js/form/element/select</item>
<item name="config" xsi:type="array">
<!--customScope is used to group elements within a single form (e.g. they can be validated separately)-->
<item name="customScope" xsi:type="string">customCheckoutForm</item>
<item name="template" xsi:type="string">ui/form/field</item>
<item name="elementTmpl" xsi:type="string">ui/form/element/select</item>
</item>
<item name="options" xsi:type="array">
<item name="0" xsi:type="array">
<item name="label" xsi:type="string">Please select value</item>
<item name="value" xsi:type="string"></item>
</item>
<item name="1" xsi:type="array">
<item name="label" xsi:type="string">Value 1</item>
<item name="value" xsi:type="string">value_1</item>
</item>
<item name="2" xsi:type="array">
<item name="label" xsi:type="string">Value 2</item>
<item name="value" xsi:type="string">value_2</item>
</item>
</item>
<!-- value element allows to specify default value of the form field -->
<item name="value" xsi:type="string">value_2</item>
<item name="provider" xsi:type="string">checkoutProvider</item>
<item name="dataScope" xsi:type="string">customCheckoutForm.select_field</item>
<item name="label" xsi:type="string">Select Field</item>
<item name="sortOrder" xsi:type="string">2</item>
</item>
<item name="date_field" xsi:type="array">
<item name="component" xsi:type="string">Magento_Ui/js/form/element/date</item>
<item name="config" xsi:type="array">
<!--customScope is used to group elements within a single form (e.g. they can be validated separately)-->
<item name="customScope" xsi:type="string">customCheckoutForm</item>
<item name="template" xsi:type="string">ui/form/field</item>
<item name="elementTmpl" xsi:type="string">ui/form/element/date</item>
</item>
<item name="provider" xsi:type="string">checkoutProvider</item>
<item name="dataScope" xsi:type="string">customCheckoutForm.date_field</item>
<item name="label" xsi:type="string">Date Field</item>
<item name="validation" xsi:type="array">
<item name="required-entry" xsi:type="string">true</item>
</item>
</item>
</item>
</item>
</item>
</item>
</item>
</item>
</item>
</item>
</item>
</item>
</item>
</item>
</item>
</item>
</item>
</argument>
</arguments>
</referenceBlock>
</body>
</page>
But it is not working for me. Referred the magento's doc http://devdocs.magento.com/guides/v2.0/howdoi/checkout/checkout_form.html. Correct me if I'm doing wrong in naming of the files or so. I would really appreciate if someone could help!!!