Skip to content

Commit

Permalink
Allow radio form control to be unchecked (#2063)
Browse files Browse the repository at this point in the history
  • Loading branch information
mvorisek authored Jun 5, 2023
1 parent 6fee84e commit cb993ec
Show file tree
Hide file tree
Showing 29 changed files with 142 additions and 117 deletions.
12 changes: 6 additions & 6 deletions phpstan.neon.dist
Original file line number Diff line number Diff line change
Expand Up @@ -224,7 +224,7 @@ parameters:
# TODO fix contravariance for View::set() method
-
path: 'src/Console.php'
message: '~^Parameter #1 \$fx \(Closure\(\$this\(Atk4\\Ui\\Console\)\): void\) of method Atk4\\Ui\\Console::set\(\) should be contravariant with parameter \$arg1 \(mixed\) of method Atk4\\Ui\\View::set\(\)$~'
message: '~^Parameter #1 \$fx \(Closure\(\$this\): void\) of method Atk4\\Ui\\Console::set\(\) should be contravariant with parameter \$arg1 \(mixed\) of method Atk4\\Ui\\View::set\(\)$~'
-
path: 'src/Console.php'
message: '~^Parameter #2 \$event \(bool\|string\) of method Atk4\\Ui\\Console::set\(\) should be contravariant with parameter \$arg2 \(mixed\) of method Atk4\\Ui\\View::set\(\)$~'
Expand All @@ -233,16 +233,16 @@ parameters:
message: '~^Parameter #2 \$ignore \(\*NEVER\*\) of method Atk4\\Ui\\Form\\Control::set\(\) should be compatible with parameter \$arg2 \(mixed\) of method Atk4\\Ui\\View::set\(\)$~'
-
path: 'src/Form/Control/Calendar.php'
message: '~^Parameter #1 \$expr \(Atk4\\Ui\\Js\\JsExpressionable\) of method Atk4\\Ui\\Form\\Control\\Calendar::onChange\(\) should be contravariant with parameter \$expr \(array{Closure\(Atk4\\Ui\\Js\\Jquery, mixed, mixed, mixed, mixed, mixed, mixed, mixed, mixed, mixed, mixed\): Atk4\\Ui\\Js\\JsExpressionable\|Atk4\\Ui\\View\|string\|void}\|Atk4\\Ui\\Js\\JsExpressionable\|\(Closure\(Atk4\\Ui\\Js\\Jquery, mixed, mixed, mixed, mixed, mixed, mixed, mixed, mixed, mixed, mixed\): Atk4\\Ui\\Js\\JsExpressionable\|Atk4\\Ui\\View\|string\|void\)\) of method Atk4\\Ui\\Form\\Control::onChange\(\)$~'
message: '~^Parameter #1 \$expr \(Atk4\\Ui\\Js\\JsExpressionable\) of method Atk4\\Ui\\Form\\Control\\Calendar::onChange\(\) should be contravariant with parameter \$expr \(array\{Closure\(Atk4\\Ui\\Js\\Jquery, mixed, mixed, mixed, mixed, mixed, mixed, mixed, mixed, mixed, mixed\): \(Atk4\\Ui\\Js\\JsExpressionable\|Atk4\\Ui\\View\|string\|void\)\}\|Atk4\\Ui\\Js\\JsExpressionable\|\(Closure\(Atk4\\Ui\\Js\\Jquery, mixed, mixed, mixed, mixed, mixed, mixed, mixed, mixed, mixed, mixed\): \(Atk4\\Ui\\Js\\JsExpressionable\|Atk4\\Ui\\View\|string\|void\)\)\) of method Atk4\\Ui\\Form\\Control::onChange\(\)$~'
-
path: 'src/Form/Control/Upload.php'
message: '~^Parameter #1 \$fileId \(string\) of method Atk4\\Ui\\Form\\Control\\Upload::set\(\) should be contravariant with parameter \$value \(mixed\) of method Atk4\\Ui\\Form\\Control::set\(\)$~'
-
path: 'src/JsCallback.php'
message: '~^Parameter #1 \$fx \(Closure\(Atk4\\Ui\\Js\\Jquery, mixed, mixed, mixed, mixed, mixed, mixed, mixed, mixed, mixed, mixed\): Atk4\\Ui\\Js\\JsExpressionable\|Atk4\\Ui\\View\|string\|void\) of method Atk4\\Ui\\JsCallback::set\(\) should be contravariant with parameter \$fx \(Closure\(mixed, mixed, mixed, mixed, mixed, mixed, mixed, mixed, mixed, mixed\): mixed\) of method Atk4\\Ui\\Callback::set\(\)$~'
message: '~^Parameter #1 \$fx \(Closure\(Atk4\\Ui\\Js\\Jquery, mixed, mixed, mixed, mixed, mixed, mixed, mixed, mixed, mixed, mixed\): \(Atk4\\Ui\\Js\\JsExpressionable\|Atk4\\Ui\\View\|string\|void\)\) of method Atk4\\Ui\\JsCallback::set\(\) should be contravariant with parameter \$fx \(Closure\(mixed, mixed, mixed, mixed, mixed, mixed, mixed, mixed, mixed, mixed\): mixed\) of method Atk4\\Ui\\Callback::set\(\)$~'
-
path: 'src/Loader.php'
message: '~^Parameter #1 \$fx \(Closure\(\$this\(Atk4\\Ui\\Loader\)\): void\) of method Atk4\\Ui\\Loader::set\(\) should be contravariant with parameter \$arg1 \(mixed\) of method Atk4\\Ui\\View::set\(\)$~'
message: '~^Parameter #1 \$fx \(Closure\(\$this\): void\) of method Atk4\\Ui\\Loader::set\(\) should be contravariant with parameter \$arg1 \(mixed\) of method Atk4\\Ui\\View::set\(\)$~'
-
path: 'src/Loader.php'
message: '~^Parameter #2 \$ignore \(\*NEVER\*\) of method Atk4\\Ui\\Loader::set\(\) should be compatible with parameter \$arg2 \(mixed\) of method Atk4\\Ui\\View::set\(\)$~'
Expand All @@ -260,10 +260,10 @@ parameters:
message: '~^Parameter #2 \$ignore \(\*NEVER\*\) of method Atk4\\Ui\\Popup::set\(\) should be compatible with parameter \$arg2 \(mixed\) of method Atk4\\Ui\\View::set\(\)$~'
-
path: 'src/VirtualPage.php'
message: '~^Parameter #1 \$fx \(Closure\(\$this\(Atk4\\Ui\\VirtualPage\), mixed, mixed, mixed, mixed, mixed, mixed, mixed, mixed, mixed, mixed\): void\) of method Atk4\\Ui\\VirtualPage::set\(\) should be contravariant with parameter \$arg1 \(mixed\) of method Atk4\\Ui\\View::set\(\)$~'
message: '~^Parameter #1 \$fx \(Closure\(\$this, mixed, mixed, mixed, mixed, mixed, mixed, mixed, mixed, mixed, mixed\): void\) of method Atk4\\Ui\\VirtualPage::set\(\) should be contravariant with parameter \$arg1 \(mixed\) of method Atk4\\Ui\\View::set\(\)$~'
-
path: 'src/VirtualPage.php'
message: '~^Parameter #1 \$fx of method Atk4\\Ui\\Callback::set\(\) expects \(Closure\(mixed, mixed, mixed, mixed, mixed, mixed, mixed, mixed, mixed, mixed\): void\)\|null, Closure\(\$this\(Atk4\\Ui\\VirtualPage\), mixed, mixed, mixed, mixed, mixed, mixed, mixed, mixed, mixed, mixed\): void given.$~'
message: '~^Parameter #1 \$fx of method Atk4\\Ui\\Callback::set\(\) expects \(Closure\(mixed, mixed, mixed, mixed, mixed, mixed, mixed, mixed, mixed, mixed\): void\)\|null, Closure\(\$this, mixed, mixed, mixed, mixed, mixed, mixed, mixed, mixed, mixed, mixed\): void given\.$~'
-
path: 'src/VirtualPage.php'
message: '~^Parameter #2 \$fxArgs \(array\) of method Atk4\\Ui\\VirtualPage::set\(\) should be contravariant with parameter \$arg2 \(mixed\) of method Atk4\\Ui\\View::set\(\)$~'
Expand Down
6 changes: 2 additions & 4 deletions src/Form/Control.php
Original file line number Diff line number Diff line change
Expand Up @@ -64,14 +64,12 @@ class Control extends View
public $hint;

/**
* Is input field disabled?
* Disabled input fields are not editable and will not be submitted.
* Disabled field is not editable and will not be submitted.
*/
public bool $disabled = false;

/**
* Is input field read only?
* Read only input fields are not editable, but will be submitted.
* Read-only field is not editable, but will be submitted.
*/
public bool $readOnly = false;

Expand Down
7 changes: 3 additions & 4 deletions src/Form/Control/Checkbox.php
Original file line number Diff line number Diff line change
Expand Up @@ -63,13 +63,12 @@ protected function renderView(): void

$this->content = null;

if ($this->readOnly) {
$this->addClass('read-only');
}

if ($this->disabled) {
$this->addClass('disabled');
$this->template->dangerouslySetHtml('disabled', 'disabled="disabled"');
} elseif ($this->readOnly) {
$this->addClass('read-only');
$this->template->dangerouslySetHtml('disabled', 'readonly="readonly"');
}

$this->js(true)->checkbox();
Expand Down
44 changes: 21 additions & 23 deletions src/Form/Control/Dropdown.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,13 @@
namespace Atk4\Ui\Form\Control;

use Atk4\Ui\HtmlTemplate;
use Atk4\Ui\Js\Jquery;
use Atk4\Ui\Js\JsExpression;
use Atk4\Ui\Js\JsExpressionable;
use Atk4\Ui\Js\JsFunction;

class Dropdown extends Input
{
public $ui = 'dropdown fluid search selection';
public $defaultTemplate = 'form/control/dropdown.html';

public string $inputType = 'hidden';
Expand All @@ -33,16 +33,6 @@ class Dropdown extends Input
/** @var string The string to set as an empty values. */
public $empty = "\u{00a0}"; // Unicode NBSP

/**
* The icon to display at the dropdown menu.
* The template default is set to: 'dropdown'.
* Note: dropdown icon is show on the right side of the menu
* while other icon are usually display on the left side.
*
* @var string|null
*/
public $dropIcon;

/** @var array Dropdown options as per Fomantic-UI dropdown options. */
public $dropdownOptions = [];

Expand Down Expand Up @@ -175,12 +165,23 @@ public function setDropdownOptions($options): void
$this->dropdownOptions = array_merge($this->dropdownOptions, $options);
}

/**
* @param bool|string $when
* @param JsExpressionable $action
*
* @return Jquery
*/
protected function jsDropdown($when = false, $action = null): JsExpressionable
{
return $this->js($when, $action, 'div.ui.dropdown:has(> #' . $this->name . '_input)');
}

/**
* Render JS for dropdown.
*/
protected function jsRenderDropdown(): JsExpressionable
{
return $this->js(true)->dropdown($this->dropdownOptions);
return $this->jsDropdown(true)->dropdown($this->dropdownOptions);
}

/**
Expand Down Expand Up @@ -220,31 +221,28 @@ protected function htmlRenderValue(): void
protected function renderView(): void
{
if ($this->multiple) {
$this->addClass('multiple');
$this->template->dangerouslySetHtml('multipleClass', 'multiple');
}

if ($this->readOnly || $this->disabled) {
$this->setDropdownOption('allowTab', false);
$this->removeClass('search');
if ($this->multiple) {
$this->js(true)->find('a i.delete.icon')->attr('class', 'disabled');
$this->jsDropdown(true)->find('a i.delete.icon')->attr('class', 'disabled');
}
}

if ($this->disabled) {
$this->addClass('disabled');
}
$this->template->set('disabledClass', 'disabled');
$this->template->dangerouslySetHtml('disabled', 'disabled="disabled"');
} elseif ($this->readOnly) {
$this->template->set('disabledClass', 'read-only');
$this->template->dangerouslySetHtml('disabled', 'readonly="readonly"');

if ($this->readOnly) {
$this->setDropdownOption('allowTab', false);
$this->setDropdownOption('onShow', new JsFunction([], [new JsExpression('return false')]));
}

if ($this->dropIcon) {
$this->template->trySet('DropIcon', $this->dropIcon);
}

$this->template->trySet('DefaultText', $this->empty);
$this->template->set('DefaultText', $this->empty);

$this->htmlRenderValue();
$this->jsRenderDropdown();
Expand Down
8 changes: 4 additions & 4 deletions src/Form/Control/DropdownCascade.php
Original file line number Diff line number Diff line change
Expand Up @@ -43,12 +43,12 @@ protected function init(): void
$expr = [
function (Jquery $j) use ($cascadeFromValue) {
return new JsBlock([
$this->js()->dropdown('change values', $this->getNewValues($cascadeFromValue)),
$this->js()->removeClass('loading'),
$this->jsDropdown()->dropdown('change values', $this->getNewValues($cascadeFromValue)),
$this->jsDropdown()->removeClass('loading'),
]);
},
$this->js()->dropdown('clear'),
$this->js()->addClass('loading'),
$this->jsDropdown()->dropdown('clear'),
$this->jsDropdown()->addClass('loading'),
];

$this->cascadeFrom->onChange($expr, ['args' => [$this->cascadeFrom->name => $this->cascadeFrom->jsInput()->val()]]);
Expand Down
2 changes: 1 addition & 1 deletion src/Form/Control/Input.php
Original file line number Diff line number Diff line change
Expand Up @@ -110,8 +110,8 @@ public function getInput()
'placeholder' => $this->inputType !== 'hidden' ? $this->placeholder : false,
'id' => $this->name . '_input',
'value' => $this->getValue(),
'readonly' => $this->readOnly && $this->inputType !== 'hidden',
'disabled' => $this->disabled && $this->inputType !== 'hidden',
'readonly' => $this->readOnly && $this->inputType !== 'hidden' && !$this->disabled,
], $this->inputAttr));
}

Expand Down
29 changes: 20 additions & 9 deletions src/Form/Control/Lookup.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
use Atk4\Ui\Js\Jquery;
use Atk4\Ui\Js\JsBlock;
use Atk4\Ui\Js\JsExpression;
use Atk4\Ui\Js\JsExpressionable;
use Atk4\Ui\Js\JsFunction;
use Atk4\Ui\Js\JsModal;
use Atk4\Ui\Js\JsToast;
Expand Down Expand Up @@ -130,7 +131,6 @@ protected function init(): void
parent::init();

$this->template->set([
'inputId' => $this->name . '-ac',
'placeholder' => $this->placeholder,
]);

Expand All @@ -142,6 +142,17 @@ protected function init(): void
});
}

/**
* @param bool|string $when
* @param JsExpressionable $action
*
* @return Jquery
*/
protected function jsDropdown($when = false, $action = null): JsExpressionable
{
return $this->js($when, $action, 'div.ui.dropdown:has(> #' . $this->name . '_input)');
}

/**
* Returns URL which would respond with first 50 matching records.
*/
Expand Down Expand Up @@ -261,7 +272,7 @@ protected function initQuickNewRecord(): void
$res->addStatement((new Jquery())->closest('.atk-modal')->modal('hide'));

$row = $this->renderRow($form->model);
$chain = new Jquery('#' . $this->name . '-ac');
$chain = $this->jsDropdown();
$chain->dropdown('set value', $row['value'])->dropdown('set text', $row['title']);
$res->addStatement($chain);

Expand Down Expand Up @@ -352,17 +363,17 @@ protected function renderView(): void
}

if ($this->disabled) {
$this->settings['allowTab'] = false;

$this->template->dangerouslySetHtml('disabled', 'disabled="disabled"');
$this->template->set('disabledClass', 'disabled');
}
$this->template->dangerouslySetHtml('disabled', 'disabled="disabled"');

$this->settings['allowTab'] = false;
} elseif ($this->readOnly) {
$this->template->set('disabledClass', 'read-only');
$this->template->dangerouslySetHtml('disabled', 'readonly="readonly"');

if ($this->readOnly) {
$this->settings['allowTab'] = false;
$this->settings['apiSettings'] = null;
$this->settings['onShow'] = new JsFunction([], [new JsExpression('return false')]);
$this->template->dangerouslySetHtml('readonly', 'readonly="readonly"');
}

if ($this->dependency) {
Expand All @@ -371,7 +382,7 @@ protected function renderView(): void
], $this->apiConfig['data'] ?? []);
}

$chain = new Jquery('#' . $this->name . '-ac');
$chain = $this->jsDropdown();

$this->initDropdown($chain);

Expand Down
14 changes: 10 additions & 4 deletions src/Form/Control/Radio.php
Original file line number Diff line number Diff line change
Expand Up @@ -39,15 +39,21 @@ protected function renderView(): void
$this->lister->setModel($this->model);

$this->lister->onHook(Lister::HOOK_BEFORE_ROW, function (Lister $lister) use ($value) {
if ($this->readOnly) {
$lister->tRow->dangerouslySetHtml('disabled', $value !== (string) $lister->model->getId() ? 'disabled="disabled"' : '');
} elseif ($this->disabled) {
if ($this->disabled) {
$lister->tRow->dangerouslySetHtml('disabledClass', 'disabled');
$lister->tRow->dangerouslySetHtml('disabled', 'disabled="disabled"');
} elseif ($this->readOnly) {
$lister->tRow->dangerouslySetHtml('disabledClass', 'read-only');
$lister->tRow->dangerouslySetHtml('disabled', 'readonly="readonly"');
}

$lister->tRow->dangerouslySetHtml('checked', $value === (string) $lister->model->getId() ? 'checked="checked"' : '');
$lister->tRow->dangerouslySetHtml('checked', $lister->model->compare($lister->model->idField, $value) ? 'checked="checked"' : '');
});

$this->js(true, null, '.ui.checkbox.radio')->checkbox([
'uncheckable' => !$this->entityField || ($this->entityField->getField()->nullable || !$this->entityField->getField()->required),
]);

parent::renderView();
}

Expand Down
2 changes: 1 addition & 1 deletion src/Form/Control/Textarea.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@ public function getInput()
'rows' => $this->rows,
'placeholder' => $this->placeholder,
'id' => $this->name . '_input',
'readonly' => $this->readOnly,
'disabled' => $this->disabled,
'readonly' => $this->readOnly && !$this->disabled,
], $this->inputAttr), $this->getValue() ?? '');
}
}
30 changes: 18 additions & 12 deletions src/Form/Control/Upload.php
Original file line number Diff line number Diff line change
Expand Up @@ -65,8 +65,11 @@ protected function init(): void

$this->cb = JsCallback::addTo($this);

if (!$this->action) {
$this->action = new Button(['icon' => 'upload', 'class.disabled' => $this->disabled || $this->readOnly]);
if ($this->action === null) {
$this->action = new Button([
'icon' => 'upload',
'class.disabled' => $this->disabled || $this->readOnly,
]);
}
}

Expand Down Expand Up @@ -123,10 +126,8 @@ public function setFileId($id): void

/**
* Add a JS action to be returned to server on callback.
*
* @param JsExpressionable $action
*/
public function addJsAction($action): void
public function addJsAction(JsExpressionable $action): void
{
$this->jsActions[] = $action;
}
Expand Down Expand Up @@ -162,7 +163,10 @@ public function onUpload(\Closure $fx): void
$this->setInput($fileId);
}

$this->addJsAction($fx(...$postFiles));
$jsRes = $fx(...$postFiles);
if ($jsRes !== null) { // @phpstan-ignore-line https://github.com/phpstan/phpstan/issues/9388
$this->addJsAction($jsRes);
}

if (count($postFiles) > 0 && reset($postFiles)['error'] === 0) {
$this->addJsAction(
Expand All @@ -186,7 +190,11 @@ public function onDelete(\Closure $fx): void
if (($_POST['fUploadAction'] ?? null) === self::DELETE_ACTION) {
$this->cb->set(function () use ($fx) {
$fileId = $_POST['fUploadId'];
$this->addJsAction($fx($fileId));

$jsRes = $fx($fileId);
if ($jsRes !== null) { // @phpstan-ignore-line https://github.com/phpstan/phpstan/issues/9388
$this->addJsAction($jsRes);
}

return new JsBlock($this->jsActions);
});
Expand All @@ -195,10 +203,6 @@ public function onDelete(\Closure $fx): void

protected function renderView(): void
{
// need before parent rendering.
if ($this->disabled) {
$this->addClass('disabled');
}
parent::renderView();

if ($this->cb->canTerminate()) {
Expand All @@ -222,8 +226,10 @@ protected function renderView(): void
$this->template->dangerouslySetHtml('multiple', 'multiple="multiple"');
}

$this->template->set('placeholderReadonly', $this->disabled ? 'disabled="disabled"' : 'readonly="readonly"');

if ($this->placeholder) {
$this->template->trySet('PlaceHolder', $this->placeholder);
$this->template->set('Placeholder', $this->placeholder);
}

$this->js(true)->atkFileUpload([
Expand Down
Loading

0 comments on commit cb993ec

Please sign in to comment.