Skip to content

Commit

Permalink
RadioList: added setEmptyItem()
Browse files Browse the repository at this point in the history
  • Loading branch information
dg committed May 5, 2024
1 parent 07a630f commit ae69980
Show file tree
Hide file tree
Showing 3 changed files with 62 additions and 1 deletion.
35 changes: 34 additions & 1 deletion src/Forms/Controls/RadioList.php
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ class RadioList extends ChoiceControl
protected Html $separator;
protected Html $container;
protected Html $itemLabel;
private string|Stringable|false $emptyItem = false;


public function __construct(string|Stringable|null $label = null, ?array $items = null)
Expand All @@ -40,6 +41,25 @@ public function __construct(string|Stringable|null $label = null, ?array $items
}


/**
* Sets the first N/A item.
*/
public function setEmptyItem(string|Stringable|false $label): static
{
$this->emptyItem = $label;
return $this;
}


/**
* Returns the first N/A item.
*/
public function getEmptyItem(): string|Stringable|false
{
return $this->emptyItem;
}


public function getControl(): Html
{
$input = parent::getControl();
Expand All @@ -51,12 +71,25 @@ public function getControl(): Html
}
}

$selected = $this->value;
if ($this->emptyItem !== false) {
if ($this->isRequired()) {
throw new Nette\InvalidStateException('Required radiolist cannot have empty item.');
}
$emptyKey = '';
while (isset($items[$emptyKey])) {
$emptyKey .= "\x1";
}
$items = [$emptyKey => $this->translate($this->emptyItem)] + $items;
$selected ??= $emptyKey;
}

return $this->container->setHtml(
Nette\Forms\Helpers::createInputList(
$this->translate($items),
array_merge($input->attrs, [
'id:' => $ids,
'checked?' => $this->value,
'checked?' => $selected,
'disabled:' => $this->disabled,
'data-nette-rules:' => [key($items) => $input->attrs['data-nette-rules']],
]),
Expand Down
11 changes: 11 additions & 0 deletions tests/Forms/Controls.RadioList.loadData.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,17 @@ testException('setValue() and invalid argument', function () use ($series) {
}, Nette\InvalidArgumentException::class, "Value 'unknown' is out of allowed set ['red-dwarf', 'the-simpsons', 0, ''] in field 'radio'.");


test('empty item selected', function () {
$_POST = ['radio' => ''];

$form = new Form;
$input = $form->addRadioList('radio', null, ['a' => 'First'])->setEmptyItem('n/a');

Assert::true($form->isValid());
Assert::null($input->getValue());
});


test('object as value', function () {
$form = new Form;
$input = $form->addRadioList('radio', null, ['2013-07-05 00:00:00' => 1])
Expand Down
17 changes: 17 additions & 0 deletions tests/Forms/Controls.RadioList.render.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,23 @@ test('Html', function () {
});


test('empty item', function () {
$form = new Form;
$input = $form->addRadioList('list', 'Label', [
'' => 'First',
])->setEmptyItem('n/a');

Assert::same('<label><input type="radio" name="list" checked value="' . "\x01" . '">n/a</label><br><label><input type="radio" name="list" value="">First</label>', (string) $input->getControl());

$input->setRequired();
Assert::exception(
fn() => $input->getControl(),
Nette\InvalidStateException::class,
'Required radiolist cannot have empty item.',
);
});


test('validation rules', function () {
$form = new Form;
$input = $form->addRadioList('list', 'Label', [
Expand Down

0 comments on commit ae69980

Please sign in to comment.