[UPDATED MY ANSWER]
etc/adminhtml/di.xml
Add modifier to add custom form modal
<virtualType name="Vendor\Module\Ui\DataProvider\Item\Form\Modifier\Pool" type="Magento\Ui\DataProvider\Modifier\Pool">
<arguments>
<argument name="modifiers" xsi:type="array">
<item name="item-form-modal" xsi:type="array">
<item name="class" xsi:type="string">Vendor\Module\Ui\DataProvider\Item\Form\Modifier\Item</item>
<item name="sortOrder" xsi:type="number">10</item>
</item>
</argument>
</arguments>
</virtualType>
Button action for render modal
return [
'label' => __('Add New Item'),
'class' => 'primary button-add-item',
'data_attribute' => [
'mage-init' => [
'Magento_Ui/js/form/button-adapter' => [
'actions' => [
[
'targetName' => 'item_form.item_form.item_form_modal',
'actionName' => 'toggleModal'
],
[
'targetName' => 'item_form.item_form.item_form_modal.insert_item_form',
'actionName' => 'render'
]
]
]
]
],
'on_click' => '',
'sort_order' => 20
];
}
File Modifier where i defination form
return $this->arrayManager->set(
'item_form_modal',
$meta,
[
'arguments' => [
'data' => [
'config' => [
'isTemplate' => false,
'componentType' => 'modal',
'options' => [
'title' => __('New Item'),
],
'imports' => [
'state' => '!index=insert_item_form:responseStatus'
],
],
],
],
'children' => [
'insert_item_form' => [
'arguments' => [
'data' => [
'config' => [
'label' => '',
'componentType' => 'container',
'component' => 'Magento_Ui/js/form/components/insert-form',
'dataScope' => '',
'update_url' => $this->urlBuilder->getUrl('mui/index/render'),
'render_url' => $this->urlBuilder->getUrl(
'mui/index/render_handle',
[
'handle' => 'megamenuadmin_item_form',
'store' => $this->_storeManager->getStore()->getId(),
'buttons' => 1
]
),
'autoRender' => false,
'ns' => 'item_add_form',
'externalProvider' => 'item_add_form.item_add_form_data_source',
'toolbarContainer' => '${ $.parentName }',
'formSubmitType' => 'ajax',
],
],
]
]
]
]
);
item_form_modal
has child element form ui insert_item_form
insert via ajax. Handle layout megamenuadmin_item_form
contain ui-form
. Between children [] you can add any components such as: fieldsets, fields, selects, inputs v.v or ui-form like i do
layout megamenuadmin_item_form
<page>
<referenceContainer name="content">
<uiComponent name="item_add_form"/>
</referenceContainer>
</page>
form ui-component item_add_form
<?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">item_add_form.item_add_form_data_source</item>
<item name="deps" xsi:type="string">item_add_form.item_add_form_data_source</item>
<item name="namespace" xsi:type="string">item_add_form</item>
</item>
<item name="buttons" xsi:type="array">
<item name="cancel" xsi:type="string">Vendor\Module\Block\Adminhtml\Item\Button\Cancel</item>
<item name="save" xsi:type="string">Vendor\Module\Block\Adminhtml\Item\Button\Save</item>
</item>
<item name="template" xsi:type="string">templates/form/collapsible</item>
<item name="config" xsi:type="array">
<item name="ajaxSaveType" xsi:type="string">simple</item>
</item>
</argument>
<dataSource name="item_add_form_data_source">
<argument name="dataProvider" xsi:type="configurableObject">
<argument name="class" xsi:type="string">Vendor\Module\Model\Item\DataProvider</argument>
<argument name="name" xsi:type="string">item_add_form_data_source</argument>
<argument name="primaryFieldName" xsi:type="string">id</argument>
<argument name="requestFieldName" xsi:type="string">menu_id</argument>
<argument name="data" xsi:type="array">
<item name="config" xsi:type="array">
<item name="submit_url" xsi:type="url" path="megamenuadmin/item/save"/>
</item>
</argument>
</argument>
<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>
</dataSource>
<fieldset name="filedset1">
Fields go here
</fieldset>
<fieldset name="fieldset2">
</fieldset>
</form>
Yo, whats up guys. I just had to wrestle with this in 2.1.9 and think I may have a legit answer.
All of these answers are close, but none seem to be completely correct so far. I'll explain how I figured this out.
Unfortuantely, for any of us that have worked with any depth in Magento 2, likely we've come to realize that if you want to do anything... you need to be able to trace core code. Which... is difficult- with all the knockout , xml... fun.
Enough nonsense. Lets get to it.
First, save button:
<argument name="data" xsi:type="array">
<item name="js_config" xsi:type="array">
<item name="provider" xsi:type="string">educationfiles_edit.educationfiles_edit_data_source</item>
<item name="deps" xsi:type="string">educationfiles_edit.educationfiles_edit_data_source</item>
</item>
<item name="layout" xsi:type="array">
<item name="type" xsi:type="string">tabs</item>
</item>
<item name="buttons" xsi:type="array">
<item name="manage" xsi:type="array">
<item name="name" xsi:type="string">manage</item>
<item name="label" xsi:type="string" translate="true">Manage</item>
<item name="class" xsi:type="string">manage</item>
<item name="url" xsi:type="string">*/*/</item>
</item>
<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>
</item>
</argument>
Within your top data block, shown above, you have the buttons section. Here your button is defined, note that there is no route defined on it... for some reason you don't need it. Meaning you DO NOT need:
<item name="url" xsi:type="string">*/*/save</item>
Like the manage button has above it. I'm guessing that the form expects the item named save to fire the submit_url. Whats the submit_url, right, onto that.
Within your datasource:
<dataSource name="educationfiles_edit_data_source">
<argument name="dataProvider" xsi:type="configurableObject">
<argument name="class" xsi:type="string">Augustash\EducationFiles\Model\Upload\DataProvider</argument>
<argument name="name" xsi:type="string">educationfiles_edit_data_source</argument>
<argument name="primaryFieldName" xsi:type="string">entity_id</argument>
<argument name="requestFieldName" xsi:type="string">id</argument>
</argument>
<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 name="submit_url" path="*/*/save" xsi:type="url" />
</item>
</argument>
</dataSource>
Take note of:
<item name="submit_url" path="*/*/save" xsi:type="url" />
This will cause your save button to fire the defined path.
That solves the problem, for extra credit continue on.
How the hell did I figure this out? This is the most important part. Take note of the js_config definition within our datasource block:
<item name="js_config" xsi:type="array">
<item name="component" xsi:type="string">Magento_Ui/js/form/provider</item>
<item name="submit_url" path="*/*/save" xsi:type="url" />
</item>
This means that Magento is using 'Magento_Ui/js/form/provider' to process this form block. Where is that file...?
'Magento_Ui' is a core module. It is located where all the core files are within your 'vendor' folder at the web root. Within 'vendor' the directory will be named 'module-[modulename]', because of '_Ui'.
Magento_Ui
vendor/magento/module-ui
Knockout files are within 'view', then the respective area- meaning 'base', 'adminhtml', or 'frontend', then the 'web' directory.
vendor/magento/module-ui/view/[area]
From there the path is 'vendor/magento/module-ui/view/base/web/js/form/provider.js'.
Magento_Ui/js/form/provider
vendor/magento/module-ui/view/base/web/js/form/provider.js
Meaning you have to know knockout files are in 'view/[area]/web', then you can piece together the actual file path.
Within provider.js you can find what Magento is looking for, to give yourself a clue as to why/what you are defining in your xml. In this case:
defaults: {
clientConfig: {
urls: {
save: '${ $.submit_url }',
beforeSave: '${ $.validate_url }'
}
}
},
This tells us that provider.js save is looking for a 'submit_url' definition. Which means the 'name' of an xml definition should be that, in our case:
<item name="submit_url" path="*/*/save" xsi:type="url" />
The astute among you will realize that this means we can also define a validation url with 'validate_url'. I haven't tested that... we probly shouldn't assume that it works- but its intended to work, lol. Magento.
Then we know this is javascript, so we can guess that this definition should be set within the 'js_config':
<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 name="submit_url" path="*/*/save" xsi:type="url" />
</item>
</argument>
In total, our form data and datasource xml:
<argument name="data" xsi:type="array">
<item name="js_config" xsi:type="array">
<item name="provider" xsi:type="string">educationfiles_edit.educationfiles_edit_data_source</item>
<item name="deps" xsi:type="string">educationfiles_edit.educationfiles_edit_data_source</item>
</item>
<item name="layout" xsi:type="array">
<item name="type" xsi:type="string">tabs</item>
</item>
<item name="buttons" xsi:type="array">
<item name="manage" xsi:type="array">
<item name="name" xsi:type="string">manage</item>
<item name="label" xsi:type="string" translate="true">Manage</item>
<item name="class" xsi:type="string">manage</item>
<item name="url" xsi:type="string">*/*/</item>
</item>
<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>
</item>
</argument>
<dataSource name="educationfiles_edit_data_source">
<argument name="dataProvider" xsi:type="configurableObject">
<argument name="class" xsi:type="string">Augustash\EducationFiles\Model\Upload\DataProvider</argument>
<argument name="name" xsi:type="string">educationfiles_edit_data_source</argument>
<argument name="primaryFieldName" xsi:type="string">entity_id</argument>
<argument name="requestFieldName" xsi:type="string">id</argument>
</argument>
<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 name="submit_url" path="*/*/save" xsi:type="url" />
</item>
</argument>
</dataSource>
Obviously you'll have to replace various details within this code for it to work.
Best Answer
In my case I used ButtonProviderInterface
While declaring my button on the listing xml file
logger_log_listing.xml
, like so :PS: I don't know why but not using
'on_click' => ''
resulted in redirection to base url (front page)