Using dataPersistor to get Form data, thought you're using getSession
$data = $this->getSession()->getFormData();
Save action
<?php
namespace Vendor\Module\Controller\Adminhtml\Scheduler;
use Magento\Framework\Exception\LocalizedException;
class Save extends \Magento\Backend\App\Action
{
protected $dataPersistor;
/**
* @param \Magento\Backend\App\Action\Context $context
* @param \Magento\Framework\App\Request\DataPersistorInterface $dataPersistor
*/
public function __construct(
\Magento\Backend\App\Action\Context $context,
\Magento\Framework\App\Request\DataPersistorInterface $dataPersistor
) {
$this->dataPersistor = $dataPersistor;
parent::__construct($context);
}
/**
* Save actionSave action
*
* @return \Magento\Framework\Controller\ResultInterface
*/
public function execute()
{
/** @var \Magento\Backend\Model\View\Result\Redirect $resultRedirect */
$resultRedirect = $this->resultRedirectFactory->create();
$data = $this->getRequest()->getPostValue();
if ($data) {
$id = $this->getRequest()->getParam('scheduler_id');
$model = $this->_objectManager->create('Vendor\Module\Model\Scheduler')->load($id);
if (!$model->getId() && $id) {
$this->messageManager->addErrorMessage(__('This Scheduler no longer exists.'));
return $resultRedirect->setPath('*/*/');
}
$model->setData($data);
try {
$model->save();
$this->messageManager->addSuccessMessage(__('You saved the Scheduler.'));
$this->dataPersistor->clear('engraving_scheduler');
if ($this->getRequest()->getParam('back')) {
return $resultRedirect->setPath('*/*/edit', ['scheduler_id' => $model->getId()]);
}
return $resultRedirect->setPath('*/*/');
} catch (LocalizedException $e) {
$this->messageManager->addErrorMessage($e->getMessage());
} catch (\Exception $e) {
$this->messageManager->addExceptionMessage($e, __('Something went wrong while saving the Scheduler.'));
}
$this->dataPersistor->set('engraving_scheduler', $data);
return $resultRedirect->setPath('*/*/edit', ['scheduler_id' => $this->getRequest()->getParam('scheduler_id')]);
}
return $resultRedirect->setPath('*/*/');
}
}
DataProvider
<?php
namespace Vendor\Module\Model\Scheduler;
use Vendor\Module\Model\ResourceModel\Scheduler\CollectionFactory;
use Magento\Framework\App\Request\DataPersistorInterface;
class DataProvider extends \Magento\Ui\DataProvider\AbstractDataProvider
{
protected $dataPersistor;
protected $loadedData;
protected $collection;
/**
* Constructor
*
* @param string $name
* @param string $primaryFieldName
* @param string $requestFieldName
* @param CollectionFactory $collectionFactory
* @param DataPersistorInterface $dataPersistor
* @param array $meta
* @param array $data
*/
public function __construct(
$name,
$primaryFieldName,
$requestFieldName,
CollectionFactory $collectionFactory,
DataPersistorInterface $dataPersistor,
array $meta = [],
array $data = []
) {
$this->collection = $collectionFactory->create();
$this->dataPersistor = $dataPersistor;
parent::__construct($name, $primaryFieldName, $requestFieldName, $meta, $data);
}
/**
* Get data
*
* @return array
*/
public function getData()
{
if (isset($this->loadedData)) {
return $this->loadedData;
}
$items = $this->collection->getItems();
foreach ($items as $model) {
$this->loadedData[$model->getId()] = $model->getData();
}
$data = $this->dataPersistor->get('engraving_scheduler');
if (!empty($data)) {
$model = $this->collection->getNewEmptyItem();
$model->setData($data);
$this->loadedData[$model->getId()] = $model->getData();
$this->dataPersistor->clear('engraving_scheduler');
}
return $this->loadedData;
}
}
ui form xml
<?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">
<argument name="data" xsi:type="array">
<item name="js_config" xsi:type="array">
<item name="provider" xsi:type="string">engraving_scheduler_form.scheduler_form_data_source</item>
<item name="deps" xsi:type="string">engraving_scheduler_form.scheduler_form_data_source</item>
</item>
<item name="label" translate="true" xsi:type="string">General Information</item>
<item name="config" xsi:type="array">
<item name="dataScope" xsi:type="string">data</item>
<item name="namespace" xsi:type="string">engraving_scheduler_form</item>
</item>
<item name="template" xsi:type="string">templates/form/collapsible</item>
<item name="buttons" xsi:type="array">
<item name="back" xsi:type="string">Vendor\Module\Block\Adminhtml\Scheduler\Edit\BackButton</item>
<item name="delete" xsi:type="string">Vendor\Module\Block\Adminhtml\Scheduler\Edit\DeleteButton</item>
<item name="save" xsi:type="string">Vendor\Module\Block\Adminhtml\Scheduler\Edit\SaveButton</item>
<item name="save_and_continue" xsi:type="string">Vendor\Module\Block\Adminhtml\Scheduler\Edit\SaveAndContinueButton</item>
</item>
</argument>
<dataSource name="scheduler_form_data_source">
<argument name="dataProvider" xsi:type="configurableObject">
<argument name="class" xsi:type="string">Vendor\Module\Model\Scheduler\DataProvider</argument>
<argument name="name" xsi:type="string">scheduler_form_data_source</argument>
<argument name="primaryFieldName" xsi:type="string">scheduler_id</argument>
<argument name="requestFieldName" xsi:type="string">scheduler_id</argument>
<argument name="data" xsi:type="array">
<item name="config" xsi:type="array">
<item name="submit_url" path="*/*/save" xsi:type="url"/>
</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="General">
<argument name="data" xsi:type="array">
<item name="config" xsi:type="array">
<item name="label" xsi:type="string"/>
</item>
</argument>
<field name="label">
<argument name="data" xsi:type="array">
<item name="config" xsi:type="array">
<item name="dataType" xsi:type="string">text</item>
<item name="label" translate="true" xsi:type="string">Title</item>
<item name="formElement" xsi:type="string">input</item>
<item name="source" xsi:type="string">Scheduler</item>
<item name="sortOrder" xsi:type="number">10</item>
<item name="dataScope" xsi:type="string">label</item>
<item name="validation" xsi:type="array">
<item name="required-entry" xsi:type="boolean">true</item>
</item>
</item>
</argument>
</field>
</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
My main problem that DataProvider::getData() function weren't executed was because it didn't know which row to populate. When I added /settings_id/1/ into an url then this function was called.
And return value should be set like this:
where
I hope it helps somebody.