1: <?php
2:
3: declare(strict_types=1);
4:
5: namespace Atk4\Ui\Form\Control;
6:
7: use Atk4\Ui\Form;
8: use Atk4\Ui\Lister;
9:
10: class Radio extends Form\Control
11: {
12: public $ui = false;
13: public array $class = ['grouped', 'fields'];
14:
15: public $defaultTemplate = 'form/control/radio.html';
16:
17: /** @var Lister Contains a lister that will render individual radio buttons. */
18: public $lister;
19:
20: /** @var array<int|string, string> List of values. */
21: public $values = [];
22:
23: #[\Override]
24: protected function init(): void
25: {
26: parent::init();
27:
28: // radios are annoying because they don't send value when they are not ticked
29: if ($this->form) {
30: $this->form->onHook(Form::HOOK_LOAD_POST, function (Form $form, array &$postRawData) {
31: if (!isset($postRawData[$this->shortName])) {
32: $postRawData[$this->shortName] = '';
33: }
34: });
35: }
36:
37: $this->lister = Lister::addTo($this, [], ['Radio']);
38: $this->lister->tRow->set('_name', $this->shortName);
39: }
40:
41: #[\Override]
42: protected function renderView(): void
43: {
44: if (!$this->model) {
45: // we cannot use "id" column here as seeding Array_ persistence with 0 will throw "Must not be a zero"
46: // $this->setSource($this->values);
47: $this->setSource(array_map(static fn ($k, string $v) => ['k' => $k, 'name' => $v], array_keys($this->values), $this->values));
48: $this->model->idField = 'k';
49: }
50:
51: $value = $this->entityField ? $this->entityField->get() : $this->content;
52:
53: $this->lister->setModel($this->model);
54:
55: $this->lister->onHook(Lister::HOOK_BEFORE_ROW, function (Lister $lister) use ($value) {
56: if ($this->disabled) {
57: $lister->tRow->dangerouslySetHtml('disabledClass', 'disabled');
58: $lister->tRow->dangerouslySetHtml('disabled', 'disabled="disabled"');
59: } elseif ($this->readOnly) {
60: $lister->tRow->dangerouslySetHtml('disabledClass', 'read-only');
61: $lister->tRow->dangerouslySetHtml('disabled', 'readonly="readonly"');
62: }
63:
64: $lister->tRow->set('value', $this->getApp()->uiPersistence->typecastSaveField($this->entityField->getField(), $lister->currentRow->getId()));
65:
66: $lister->tRow->dangerouslySetHtml('checked', $lister->model->compare($lister->model->idField, $value) ? 'checked="checked"' : '');
67: });
68:
69: $this->js(true, null, '.ui.checkbox.radio')->checkbox([
70: 'uncheckable' => !$this->entityField || ($this->entityField->getField()->nullable || !$this->entityField->getField()->required),
71: ]);
72:
73: parent::renderView();
74: }
75:
76: #[\Override]
77: public function onChange($expr, $defaults = []): void
78: {
79: if (is_bool($defaults)) {
80: $defaults = $defaults ? [] : ['preventDefault' => false, 'stopPropagation' => false];
81: }
82:
83: $this->on('change', 'input', $expr, $defaults);
84: }
85: }
86: