Skip to content

Commit

Permalink
Improve form JS init selector (#2049)
Browse files Browse the repository at this point in the history
  • Loading branch information
mvorisek authored May 22, 2023
1 parent 81803a4 commit 02da37a
Show file tree
Hide file tree
Showing 4 changed files with 27 additions and 41 deletions.
3 changes: 0 additions & 3 deletions phpstan.neon.dist
Original file line number Diff line number Diff line change
Expand Up @@ -129,9 +129,6 @@ parameters:
-
path: 'src/Crud.php'
message: '~^Call to an undefined method Atk4\\Ui\\AbstractView&Atk4\\Ui\\UserAction\\ExecutorInterface::onHook\(\)\.$~'
-
path: 'src/Form.php'
message: '~^Call to an undefined method Atk4\\Ui\\AbstractView::addButton\(\)\.$~'
-
path: 'src/Form.php'
message: '~^Call to an undefined method Atk4\\Ui\\Js\\JsChain::preventFormLeave\(\)\.$~'
Expand Down
59 changes: 24 additions & 35 deletions src/Form.php
Original file line number Diff line number Diff line change
Expand Up @@ -135,9 +135,8 @@ protected function init(): void
parent::init();

$this->formElement = View::addTo($this, ['element' => 'form', 'shortName' => 'form'], ['FormElementOnly']);
$this->on('submit', new JsExpression('if (event.target === this) { []; }', [$this->formElement->js()->trigger('submit')]));

// Initialize layout, so when you call addControl / setModel next time, form will know
// where to add your fields.
$this->initLayout();

// set CSS loader for this form
Expand All @@ -146,35 +145,19 @@ protected function init(): void
$this->cb = JsCallback::addTo($this, [], [['desired_name' => 'submit']]);
}

/**
* Initialize form layout. You can inject custom layout
* if you 'layout' => .. to constructor.
*/
protected function initLayout(): void
{
// TODO simplify
if ($this->layout === null) {
$this->layout = [Form\Layout::class]; // @phpstan-ignore-line
}

if (is_string($this->layout) || is_array($this->layout)) { // @phpstan-ignore-line
$this->layout = $this->add(Factory::factory($this->layout, ['form' => $this])); // @phpstan-ignore-line
} elseif (is_object($this->layout)) { // @phpstan-ignore-line
$this->layout->form = $this;
$this->add($this->layout);
} else {
throw (new Exception('Unsupported specification of form layout. Can be array, string or object'))
->addMoreInfo('layout', $this->layout);
if (!is_object($this->layout)) { // @phpstan-ignore-line
$this->layout = Factory::factory($this->layout ?? [Form\Layout::class]); // @phpstan-ignore-line
}
$this->layout->form = $this;
$this->add($this->layout);

// allow to submit by pressing an enter key when child control is focused
$jsSubmit = $this->js(false, null, $this->formElement)->form('submit');
$this->on('submit', new JsExpression('if (event.target === this) { []; }', [$jsSubmit]));

// Add save button in layout
// add save button in layout
if ($this->buttonSave) {
$this->buttonSave = $this->layout->addButton($this->buttonSave);
$this->buttonSave->setAttr('tabindex', 0);
$jsSubmit = $this->js()->form('submit');
$this->buttonSave->on('click', $jsSubmit);
$this->buttonSave->on('keypress', new JsExpression('if (event.keyCode === 13) { []; }', [$jsSubmit]));
}
Expand Down Expand Up @@ -227,7 +210,7 @@ public function setModel(Model $entity, array $fields = null): void
{
$entity->assertIsEntity();

// Model is set for the form and also for the current layout
// set model for the form and also for the current layout
try {
parent::setModel($entity);

Expand Down Expand Up @@ -492,7 +475,7 @@ protected function loadPost(): void

protected function renderView(): void
{
$this->ajaxSubmit();
$this->setupAjaxSubmit();
if ($this->controlDisplayRules !== []) {
$this->js(true, new JsConditionalForm($this, $this->controlDisplayRules, $this->controlDisplaySelector));
}
Expand All @@ -509,7 +492,9 @@ protected function renderTemplateToHtml(): string

public function fixOwningFormAttrInRenderedHtml(string $html): string
{
return preg_replace('~<(button|fieldset|input|output|select|textarea)(?!\w| form=")~i', '$0 form="' . $this->formElement->name . '"', $html);
return preg_replace_callback('~<(?:button|fieldset|input|output|select|textarea)(?!\w| form=")~i', function ($matches) {
return $matches[0] . ' form="' . $this->getApp()->encodeHtml($this->formElement->name) . '"';
}, $html);
}

/**
Expand Down Expand Up @@ -542,15 +527,19 @@ public function setFormConfig($config)
return $this;
}

/**
* Does ajax submit.
*/
public function ajaxSubmit(): void
public function setupAjaxSubmit(): void
{
$this->js(true)->form(array_merge(['inline' => true, 'on' => 'blur'], $this->formConfig));

$this->js(true, null, $this->formElement)
->api(array_merge(['url' => $this->cb->getJsUrl(), 'method' => 'POST', 'serializeForm' => true], $this->apiConfig));
$this->js(true)->form(array_merge([
'on' => 'blur',
'inline' => true,
], $this->formConfig));

$this->formElement->js(true)->api(array_merge([
'on' => 'submit',
'url' => $this->cb->getJsUrl(),
'method' => 'POST',
'serializeForm' => true,
], $this->apiConfig));

// [name] in selector is to suppress https://github.com/fomantic/Fomantic-UI/commit/facbca003cf0da465af7d44af41462e736d3eb8b
// console errors from Multiline/vue fields
Expand Down
4 changes: 2 additions & 2 deletions src/Table/Column/FilterPopup.php
Original file line number Diff line number Diff line change
Expand Up @@ -75,9 +75,9 @@ protected function init(): void
$model->clearData();

return new JsBlock([
$this->form->js(false, null, $this->form->formElement)->form('reset'),
$this->form->js()->form('reset'),
new JsReload($this->reload),
(new Jquery($this->colTrigger))->trigger('click'),
(new Jquery($this->colTrigger))->click(),
]);
});
}
Expand Down
2 changes: 1 addition & 1 deletion src/UserAction/StepExecutorTrait.php
Original file line number Diff line number Diff line change
Expand Up @@ -425,7 +425,7 @@ protected function jsSetSubmitButton(View $view, Form $form, string $step): void
? $this->execActionButton
: $this->nextStepButton; // submit on next

$view->js(true, $button->js()->on('click', new JsFunction([], [$form->js(false, null, $form->formElement)->form('submit')])));
$view->js(true, $button->js()->on('click', new JsFunction([], [$form->js()->form('submit')])));
}

/**
Expand Down

0 comments on commit 02da37a

Please sign in to comment.