Basically, I want to send 'store' as a parameter when I save the form. For this, I customized the save button and added store_id there, but now save method is called twice. Any idea why this is happening and how can I fix it?
This is the button:(Vendor\Module\Block\Adminhtml\Entity\Edit\SaveButton.php)
public function getButtonData()
{
return [
'label' => __('Save'),
'class' => 'save primary',
'data_attribute' => [
'mage-init' => [
'buttonAdapter' => [
'actions' => [
[
'targetName' => 'vendor_module_entity_form.vendor_module_entity_form',
'actionName' => 'save',
'params' => [
true,
['store' => 5]
]
]
]
]
]
],
'sort_order' => 90,
];
}
and this is the ui_component (vendor_entity_entity_form.xml):
......
<settings>
<buttons>
<button class="Vendor\Module\Block\Adminhtml\Entity\Edit\SaveButton" name="save"/>
</buttons>
</settings>
<dataSource name="entiity_form_data_source">
<settings>
<submitUrl path="*/*/save"/>
<validateUrl path="*/*/validate"/>
</settings>
</dataSource>
......
Please try:
public function getButtonData(): array
{
return [
'label' => __('Save'),
'class' => 'save primary',
'data_attribute' => [
'mage-init' => ['button' => ['event' => 'save']],
'form-role' => 'save',
],
'sort_order' => 10
];
}
please try the below code.
$this->buttonList->add(
'select_all',
[
'label' => __('Select All Rates and Save'),
'class' => 'save',
'onclick' => "jQuery('#testhidden').val(1)",
'data_attribute' => [
'mage-init' => ['button' => ['event' => 'save', 'target' => '#edit_form']],
]
],
10
);
Create a hidden field in the form.php where fields are defined
$fieldset->addField(
'testhidden',
'hidden',
['name' => 'testhidden', 'value' => 0, 'no_span' => true]
);
I followed the ZF3 tutorial and I'm quite satisfied, but I'm something missing with the edit action in my controller. the add action works fine while the edit action doesn't. Probably I don't see it by myself, so I post it here, asking for help, even if it is really basic.
My model is nearly the same as in the tutorial, here a part of it:
public function exchangeArray(array $data)
{
$this->ProjectID= !empty($data['ProjectID']) ? $data['ProjectID'] : null;
$this->CI_Number= !empty($data['CI_Number']) ? $data['CI_Number'] : null;
$this->Description= !empty($data['Description']) ? $data['Description'] : null;
$this->Projectname= !empty($data['Projectname']) ? $data['Projectname'] : null;
$this->Shortcut= !empty($data['Shortcut']) ? $data['Shortcut'] : null;
$this->Component_Class= !empty($data['Component_Class']) ? $data['Component_Class'] : null;
}
public function getArrayCopy()
{
// echo var_dump(get_object_vars($this)
// );
//return get_object_vars($this);
return [
'ProjectID' => $this->ProjectID,
'CI_Number' => $this->CI_Number,
'Description' => $this->Description,
'Projectname' => $this->Projectname,
'Shortcut' => $this->Shortcut,
'Component_Class' => $this->Component_Class,
];
}
and here also my controlleraction:
public function editAction()
{
$id = (int) $this->params()->fromRoute('id', 0);
echo $id;
if (0 === $id) {
return $this->redirect()->toRoute('project', ['action' => 'add']);
}
else {
try {
$project = $this->projectTable->getProject($id);
} catch (\Exception $e) {
return $this->redirect()->toRoute('project', ['action' => 'index']);
}
$form = new ProjectForm();
$form->bind($project);
//$form->bind($project->current());
$form->get('submit')->setAttribute('value', 'save changes');
$request = $this->getRequest();
$viewData = ['ProjectID' => $id, 'form' => $form];
if (! $request->isPost()) {
return $viewData;
}
$form->setInputFilter($project->getInputFilter());
$form->setData($request->getPost());
if (! $form->isValid()) {
echo "nicht valide";
return $viewData;
}
else{
echo $project;
$this->projectTable->saveProject($project);
}
}
// Redirect to album list
// return $this->redirect()->toRoute('project', ['action' => 'index']);
}
here for completion reasons my view edit.phtml:
<?php
$title = 'projects';
$this->headTitle($title);
?>
<h1><?= $this->escapeHtml($title) ?></h1>
<?php
// This provides a default CSS class and placeholder text for the artist element:
$ProjectID= $form->get('ProjectID');
$ProjectID->setAttribute('class', 'form-control');
$ProjectID->setAttribute('placeholder', 'ProjectID');
$Projectname= $form->get('Projectname');
$Projectname->setAttribute('class', 'form-control');
$Projectname->setAttribute('placeholder', 'Projectname');
$CI_Number= $form->get('CI_Number');
$CI_Number->setAttribute('class', 'form-control');
$CI_Number->setAttribute('placeholder', 'CI_number');
$Shortcut= $form->get('Shortcut');
$Shortcut->setAttribute('class', 'form-control');
$Shortcut->setAttribute('placeholder', 'Shortcut');
$Description= $form->get('Description');
$Description->setAttribute('class', 'form-control');
$Description->setAttribute('placeholder', 'Description');
$Component_Class= $form->get('Component_Class');
$Component_Class->setAttribute('class', 'form-control');
$Component_Class->setAttribute('placeholder', 'Component_Class');
// This provides CSS classes for the submit button:
$submit = $form->get('submit');
$submit->setAttribute('class', 'btn btn-primary');
//$form->setAttribute('action', $this->url('project', ['action' => 'edit',])); //,'id'=> $id
$form->setAttribute('action', $this->url('project', [
'action' => 'edit',
'ProjectID' => $id,
]));
$form->prepare();
echo $this->form()->openTag($form);
?>
<?php // Wrap the elements in divs marked as form groups, and render the
// label, element, and errors separately within ?>
<div class="form-group">
<?= $this->formElement($ProjectID) ?>
<?= $this->formElementErrors()->render($ProjectID, ['class' => 'help-block']) ?>
</div>
<div class="form-group">
<?= $this->formLabel($CI_Number) ?>
<?= $this->formElement($CI_Number) ?>
<?= $this->formElementErrors()->render($CI_Number, ['class' => 'help-block']) ?>
</div>
<div class="form-group">
<?= $this->formLabel($Description) ?>
<?= $this->formElement($Description) ?>
<?= $this->formElementErrors()->render($Description, ['class' => 'help-block']) ?>
</div>
<div class="form-group">
<?= $this->formLabel($Projectname) ?>
<?= $this->formElement($Projectname) ?>
<?= $this->formElementErrors()->render($Projectname, ['class' => 'help-block']) ?>
</div>
<div class="form-group">
<?= $this->formLabel($Shortcut) ?>
<?= $this->formElement($Shortcut) ?>
<?= $this->formElementErrors()->render($Shortcut, ['class' => 'help-block']) ?>
</div>
<div class="form-group">
<?= $this->formLabel($Component_Class) ?>
<?= $this->formElement($Component_Class) ?>
<?= $this->formElementErrors()->render($Component_Class, ['class' => 'help-block']) ?>
</div>
<?php
echo $this->formSubmit($submit);
//echo $this->form->get('DCLID');
echo $this->formHidden($form->get('ProjectID'));
echo $this->form()->closeTag();
It will show the recordset properly, but won't save the changes to the database and afterwards redirects to my add action. I hope somebody sees what I'm missing, even it might be a stupid error.
EDIT1: Here is my routing link from index.phtml
Edit
EDIT2: Screenshot to show the routing parameter
EDIT3: describing test issues
here again my controller edit action, to follow up:
public function editAction()
{
$id = (int) $this->params()->fromRoute('id', 0);
echo "variable id: ". $id;
if (0 === $id) {
//return $this->redirect()->toRoute('project', ['action' => 'index']);
echo "id = 0";
}
else {
try {
$project = $this->projectTable->getProject($id);
} catch (\Exception $e) {
return $this->redirect()->toRoute('project', ['action' => 'index']);
}
$form = new ProjectForm();
$form->bind($project);
//$form->bind($project->current());
$form->get('submit')->setAttribute('value', 'save changes');
var_dump(get_object_vars($project));
$request = $this->getRequest();
$viewData = ['ProjectID' => $id, 'form' => $form];
if (!$request->isPost()) {
return $viewData;
}
else {
$form->setInputFilter($project->getInputFilter());
$form->setData($request->getPost());
if (!$form->isValid()) {
echo "nicht valide";
return $viewData;
}
else{
echo "valide";
echo $project;
$this->projectTable->saveProject($project);
}
}
}
// Redirect to album list
// return $this->redirect()->toRoute('project', ['action' => 'index']);
}
I get the output of the vardump, so the project to edit will be delivered correctly. If I send the form with the recordchanges the controller won't catch it, the controller action sees id=0 then, so the method saveProject will be never called. In my understanding it might has to do with the formvalid something, because after sending the data I come never further than if (0 === $id).
EDIT 4: After some actual tests I think it must be a routing issue. If I give the route manually via browser, I won't get the target page at all. If I dump the value, it is always NULL. So I think it could be a bracket to much/to less issue in my module.config.php I show it here because I couldn't finde the problem, I countedt the braskets several times and I won't get it. So any help is appreciated, it must be a very simple topic:
<?php
namespace Import;
use Zend\Router\Http\Segment;
use Zend\Router\Http\Literal;
use Zend\ServiceManager\Factory\InvokableFactory;
//use Zend\ServiceManager\Factory\InvokableFactory;
return [
/* 'controllers' => [
'factories' => [
Controller\ImportController::class => InvokableFactory::class,
],
], */
// hier die Einstellungen für die Routen
'router' => [
'routes' => [
'index' => [
'type' => Segment::class,
'options' => [
'route' => '/import[/:action[/:id]]',
'constraints' => [
'action' => '[a-zA-Z][a-zA-Z0-9_-]*',
'id' => '[0-9]+',
],
'defaults' => [
'controller' => Controller\IndexController::class,
'action' => 'index',
],
],
],
'import' => [
'type' => Segment::class,
'options' => [
'route' => '/import[/:action[/:id]]',
'constraints' => [
'action' => '[a-zA-Z][a-zA-Z0-9_-]*',
'id' => '[0-9]+',
],
'defaults' => [
'controller' => Controller\ImportController::class,
'action' => 'index',
],
],
],
'importdcl' => [
'type' => Segment::class,
'options' => [
'route' => '/importdcl[/:action[/:id]]',
'constraints' => [
'action' => '[a-zA-Z][a-zA-Z0-9_-]*',
'id' => '[0-9]+',
],
'defaults' => [
'controller' => Controller\ImportdclController::class,
'action' => 'index',
],
],
],
'project' => [
'type' => Segment::class,
'options' => [
'route' => '/project[/:action[/:id]]',
'constraints' => [
'action' => '[a-zA-Z][a-zA-Z0-9_-]*',
'id' => '[0-9]+',
],
'defaults' => [
'controller' => Controller\ProjectController::class,
'action' => 'index',
],
],
],
'unit' => [
'type' => Segment::class,
'options' => [
'route' => '/unit[/:action[/:id]]',
'constraints' => [
'action' => '[a-zA-Z][a-zA-Z0-9_-]*',
'id' => '[0-9]+',
],
'defaults' => [
'controller' => Controller\UnitController::class,
'action' => 'index',
],
],
],
'index' => [
'type' => Segment::class,
'options' => [
'route' => '/index[/:action[/:id]]',
'constraints' => [
'action' => '[a-zA-Z][a-zA-Z0-9_-]*',
'id' => '[0-9]+',
],
'defaults' => [
'controller' => Controller\IndexController::class,
'action' => 'index',
],
],
],
'user' => [
'type' => Segment::class,
'options' => [
'route' => '/user[/:action[/:id]]',
'constraints' => [
'action' => '[a-zA-Z][a-zA-Z0-9_-]*',
'id' => '[0-9]+',
],
'defaults' => [
'controller' => Controller\UserController::class,
'action' => 'index',
],
],
],
'followup' => [
'type' => Segment::class,
'options' => [
'route' => '/followup[/:action[/:id]]',
'constraints' => [
'action' => '[a-zA-Z][a-zA-Z0-9_-]*',
'id' => '[0-9]+',
],
'defaults' => [
'controller' => Controller\FollowupController::class,
'action' => 'index',
],
],
],
],
],
'view_manager' => [
'template_path_stack' => [
'import' => __DIR__ . '/../view',
],
],
/* ... */
'navigation' => [
'default' => [
[
'label' => 'Dashboard',
'route' => 'home',
],
[
'label' => 'Project',
'route' => 'project',
'pages' => [
[
'label' => 'Add',
'route' => 'project',
'action' => 'add',
],
[
'label' => 'Edit',
'route' => 'project',
'action' => 'edit',
],
[
'label' => 'Delete',
'route' => 'project',
'action' => 'delete',
],
],
],
[
'label' => 'Unit',
'route' => 'unit',
'pages' => [
[
'label' => 'Add',
'route' => 'unit',
'action' => 'add',
],
[
'label' => 'Edit',
'route' => 'unit',
'action' => 'edit',
],
[
'label' => 'Delete',
'route' => 'unit',
'action' => 'delete',
],
],
],
[
'label' => 'Importlog',
'route' => 'importdcl',
'action' => 'index',
'pages' => [
[
'label' => 'Add',
'route' => 'unit',
'action' => 'add',
],
[
'label' => 'Edit',
'route' => 'unit',
'action' => 'edit',
],
[
'label' => 'Delete',
'route' => 'unit',
'action' => 'delete',
],
],
],
[
'label' => 'Follow up',
'route' => 'followup',
'action' => 'index',
'pages' => [
[
'label' => 'Add',
'route' => 'unit',
'action' => 'add',
],
[
'label' => 'Edit',
'route' => 'unit',
'action' => 'edit',
],
[
'label' => 'Delete',
'route' => 'unit',
'action' => 'delete',
],
],
],
[
'label' => 'User',
'route' => 'user',
'pages' => [
[
'label' => 'Add',
'route' => 'unit',
'action' => 'add',
],
[
'label' => 'Edit',
'route' => 'unit',
'action' => 'edit',
],
[
'label' => 'Delete',
'route' => 'unit',
'action' => 'delete',
],
],
],
[
'label' => 'Logout',
'route' => 'user',
'action' => 'logout',
'pages' => [
[
'label' => 'Add',
'route' => 'unit',
'action' => 'add',
],
[
'label' => 'Edit',
'route' => 'unit',
'action' => 'edit',
],
[
'label' => 'Delete',
'route' => 'unit',
'action' => 'delete',
],
],
],
],
],
/* ... */
];
I'm testing in the usercontroller at the moment, but I have had the same problem in others routes, so I think the error might be in this file.
Based on your code, seem the problem is on $id. It mean the value is 0, that's why it is redirected to project/add.
$id = (int) $this->params()->fromRoute('id', 0);
echo $id;
if (0 === $id) {
return $this->redirect()->toRoute('project', ['action' => 'add']);
}
In your view script, the form action is set to project/edit/ProjectID/$id
$form->setAttribute('action', $this->url('project', [
'action' => 'edit',
'ProjectID' => $id,
]));
That's why your controller cannot retrieve $this->params()->fromRoute('id', 0), because the form send ProjectID param instead of id.
So, the solution please adjust your form (using id) or your controller (using ProjectID).
I at last solved it. My suggestion was right, it was a problem with the module.config.php, I have set an endbracket at the wrong place.
After writing it in parts new, tsting and complete the file, it now works.
I must rewrite post request on rest yii2.
Every time i've post request on url v1/availability
I want to call actionCreate for manage request.
This is my main.php
'urlManager' => [
'enablePrettyUrl' => true,
'enableStrictParsing' => true,
'showScriptName' => false,
'rules' => [
[
'class' => 'yii\rest\UrlRule',
'controller' => ['v1/availability'],
'pluralize' => true,
'extraPatterns' => [
'POST v1/availability' => 'v1/availability/create'
]
],
'OPTIONS v1/user/login' => 'v1/user/login',
'POST v1/user/login' => 'v1/user/login',
'POST v2/user/login' => 'v2/user/login',
'OPTIONS v2/user/login' => 'v2/user/login',
],
],
In the v1/controllers/AvailabilityController.php
i've
public function actions()
{
$actions = parent::actions();
unset($actions['view']);
return array_merge(
$actions,
[
'index' => [
'class' => 'yii\rest\IndexAction',
'modelClass' => $this->modelClass,
'checkAccess' => [$this, 'checkAccess'],
'prepareDataProvider' => [$this, 'index']
],
]
);
}
public function actionCreate(){
throw new \yii\web\HttpException(200, 'IT WORKS!', 200);
}
Any idea?
add url rule outside like below.
'urlManager' => [
'enablePrettyUrl' => true,
'enableStrictParsing' => true,
'showScriptName' => false,
'rules' => [
[
'class' => 'yii\rest\UrlRule',
'controller' => ['v1/availability']
],
'POST v1/availability' => 'v1/availability/create',
'OPTIONS v1/user/login' => 'v1/user/login',
'POST v1/user/login' => 'v1/user/login',
'POST v2/user/login' => 'v2/user/login',
'OPTIONS v2/user/login' => 'v2/user/login',
],
],
And here you need understand rules of Yii. if you add one rule like below.
['class' => 'yii\rest\UrlRule', 'controller' => 'user'],
this open many urls for clients.
[
'PUT,PATCH users/<id>' => 'user/update',
'DELETE users/<id>' => 'user/delete',
'GET,HEAD users/<id>' => 'user/view',
'POST users' => 'user/create',
'GET,HEAD users' => 'user/index',
'users/<id>' => 'user/options',
'users' => 'user/options',
]
above all urls will open for clients.
So...
there are 2 way to override post.
First #Irfan Ali method
This method permit to declare single call in main.php and work with single function in controller.
Second method is
in main.php declare general call to availability
'urlManager' => [
'enablePrettyUrl' => true,
'enableStrictParsing' => true,
'showScriptName' => false,
'rules' => [
[
'class' => 'yii\rest\UrlRule',
'controller' => ['v1/availability'],
'pluralize' => true,
],
],
],
for intercept post method you must override in the controller
public function createAction($id){
throw new \yii\web\HttpException(200, 'You receive post or put', 200);
}
and in this function you must intercept if call is post you do anything.
I love first method!