src/Form/Control/Radio.php

Summary

Maintainability
A
0 mins
Test Coverage
<?php

declare(strict_types=1);

namespace Atk4\Ui\Form\Control;

use Atk4\Ui\Form;
use Atk4\Ui\Lister;

class Radio extends Form\Control
{
    public $ui = false;
    public array $class = ['grouped', 'fields'];

    public $defaultTemplate = 'form/control/radio.html';

    /** @var Lister Contains a lister that will render individual radio buttons. */
    public $lister;

    /** @var array<int|string, string> List of values. */
    public array $values;

    #[\Override]
    protected function init(): void
    {
        parent::init();

        // radios are annoying because they don't send value when they are not ticked
        if ($this->form !== null) {
            $this->form->onHook(Form::HOOK_LOAD_POST, function (Form $form, array &$postRawData) {
                if (!isset($postRawData[$this->shortName])) {
                    $postRawData[$this->shortName] = '';
                }
            });
        }

        $this->lister = Lister::addTo($this, [], ['Radio']);
        $this->lister->tRow->set('_name', $this->shortName);
    }

    #[\Override]
    protected function renderView(): void
    {
        if ($this->model === null) {
            // we cannot use "id" column here as seeding Array_ persistence with 0 will throw "Must not be a zero"
            // $this->setSource($this->values);
            $this->setSource(array_map(static fn ($k, string $v) => ['k' => $k, 'name' => $v], array_keys($this->values), $this->values));
            $this->model->idField = 'k';
        }

        $value = $this->entityField ? $this->entityField->get() : $this->content;

        $this->lister->setModel($this->model);

        $this->lister->onHook(Lister::HOOK_BEFORE_ROW, function (Lister $lister) use ($value) {
            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->set('value', $this->getApp()->uiPersistence->typecastAttributeSaveField($this->entityField->getField(), $lister->currentRow->getId()));

            $lister->tRow->dangerouslySetHtml('checked', $lister->currentRow->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();
    }

    #[\Override]
    public function onChange($expr, $defaults = []): void
    {
        if (is_bool($defaults)) {
            $defaults = $defaults ? [] : ['preventDefault' => false, 'stopPropagation' => false];
        }

        $this->on('change', 'input', $expr, $defaults);
    }
}