Skip to content

Commit

Permalink
Add docs, add methods to Select widget (#126)
Browse files Browse the repository at this point in the history
  • Loading branch information
terabytesoftw committed Oct 28, 2021
1 parent 98ad449 commit eaac104
Show file tree
Hide file tree
Showing 6 changed files with 217 additions and 91 deletions.
1 change: 1 addition & 0 deletions README.md
Expand Up @@ -45,6 +45,7 @@ The following documentation describes how to use widgets with PHP:
- [Radio](docs/radio.md)
- [RadioList](docs/radiolist.md)
- [Range](docs/range.md)
- [Select](docs/select.md)
- [ResetButton](docs/resetbutton.md)
- [SubmitButton](docs/submitbutton.md)
- [Text](docs/text.md)
Expand Down
123 changes: 123 additions & 0 deletions docs/select.md
@@ -0,0 +1,123 @@
# Select widget

[Select](https://www.w3.org/TR/2012/WD-html-markup-20120329/select.html) is a form control that allows the user to select one or more options.

## Usage

```php
<?php

declare(strict_types=1);

namespace App\Form;

use Yiisoft\Form\FormModel;

final class TestForm extends FormModel
{
public int $cityOfBirth = 0;
}
```

Widget view:

```php
<?php

declare(strict_types=1);

use Yiisoft\Form\FormModelInterface;
use Yiisoft\Form\Widget\Field;
use Yiisoft\Form\Widget\Form;
use Yiisoft\Form\Widget\Select;

/**
* @var FormModelInterface $data
* @var object $csrf
*/

$prompt = [
'text' => 'Select City Birth',
'attributes' => [
'value' => '0',
'selected' => 'selected',
],
];
$groups = [
'a' => ['label' => 'Russia'],
'b' => ['label' => 'Chile'],
];
$citiesGroups = [
'a' => [
'1' => ' Moscu',
'2' => ' San Petersburgo',
'3' => ' Novosibirsk',
'4' => ' Ekaterinburgo',
],
'b' => [
'5' => 'Santiago',
'6' => 'Concepcion',
'7' => 'Chillan',
],
];
?>

<?= Form::widget()->action('widgets')->csrf($csrf)->begin(); ?>
<?= Select::widget()->config($data, 'cityOfBirth')->groups($groups)->items($citiesGroups)->prompt($prompt); ?>
<hr class="mt-3">
<?= Field::widget()->submitButton(['class' => 'button is-block is-info is-fullwidth', 'value' => 'Save']); ?>
<?= Form::end(); ?>
```

That would generate the following code:

```html
<form action="widgets" method="POST" _csrf="1rvzUIEIEkHrdKQhm-jl0d2bmgtXjCrLCiW69nxzdRSy1oICs2RRIN8FnWXEhZXjh-jxJm7HRrg6SO6-JQAYWA==">
<input type="hidden" name="_csrf" value="1rvzUIEIEkHrdKQhm-jl0d2bmgtXjCrLCiW69nxzdRSy1oICs2RRIN8FnWXEhZXjh-jxJm7HRrg6SO6-JQAYWA==">
<select id="testform-cityofbirth" name="TestForm[cityOfBirth]">
<option value="0" selected="">Select City Birth</option>
<optgroup label="Russia">
<option value="1"> Moscu</option>
<option value="2"> San Petersburgo</option>
<option value="3"> Novosibirsk</option>
<option value="4"> Ekaterinburgo</option>
</optgroup>
<optgroup label="Chile">
<option value="5">Santiago</option>
<option value="6">Concepcion</option>
<option value="7">Chillan</option>
</optgroup>
</select>
<hr class="mt-3">
<div>
<input type="submit" id="submit-38635684505001" class="button is-block is-info is-fullwidth" name="submit-38635684505001" value="Save">
</div>
</form>
```

### `Select` methods:

Method | Description | Default
-------|-------------|---------
`groups(array $value = [])` | Sets the groups of the select list. | `[]`
`items(array $value = [])` | Sets the items of the select list. | `[]`
`itemsAttributes(array $value = [])` | Sets the attributes of the items of the select list. | `[]`
`multiple(bool $value = true)` | If set, means the widget accepts one or more values. | `false`
`optionsData(array $data, bool $encode)` | Whether option content should be HTML-encoded. | `[]`
`prompt(array $value = [])` | Sets the prompt of the select list. | `[]`
`size(int $value = 0)` | The height of the select list with multiple is true. | `0`
`unselectValue(?string $value)` | Sets the value of the unselect option. | `null`

### `Common` methods:

Method | Description | Default
-------|-------------|---------
`autofocus(bool $value = true)` | Sets the autofocus attribute | `false`
`charset(string $value)` | Sets the charset attribute | `UTF-8`
`config(FormModelInterface $formModel, string $attribute, array $attributes = [])` | Configures the widget. |
`disabled(bool $value = true)` | Sets the disabled attribute | `false`
`form(string $value)` | Sets the form attribute | `''`
`id(string $value)` | Sets the id attribute | `''`
`readonly()` | Sets the readonly attribute | `false`
`required(bool $value = true)` | Sets the required attribute | `false`
`tabIndex(int $value = 0)` | Sets the tabindex attribute | `0`
17 changes: 13 additions & 4 deletions src/Widget/Field.php
Expand Up @@ -766,14 +766,22 @@ public function select(array $attributes = [], array $items = [], array $groups
$attributes = $new->setInputAttributes($attributes);
/** @var bool */
$encode = $attributes['encode'] ?? false;
/** @var array<array-key, string> */
/** @psalm-var array<array-key, string> */
$itemsAttributes = $attributes['itemsAttributes'] ?? [];
/** @var array<array-key, string> */
/** @psalm-var array<array-key, string> */
$optionsData = $attributes['optionsData'] ?? [];
/** @var array<array-key, mixed> */
/** @psalm-var array<array-key, mixed> */
$prompt = $attributes['prompt'] ?? [];
/** @var string|null */
$unselectValue = $attributes['unselectValue'] ?? null;

unset($attributes['encode'], $attributes['itemsAttributes'], $attributes['optionsData'], $attributes['prompt']);
unset(
$attributes['encode'],
$attributes['itemsAttributes'],
$attributes['optionsData'],
$attributes['prompt'],
$attributes['unselectValue']
);

$new->parts['{input}'] = Select::widget()
->config($new->getFormModel(), $new->attribute, $attributes)
Expand All @@ -782,6 +790,7 @@ public function select(array $attributes = [], array $items = [], array $groups
->itemsAttributes($itemsAttributes)
->optionsData($optionsData, $encode)
->prompt($prompt)
->unselectValue($unselectValue)
->render();

return $new;
Expand Down
29 changes: 16 additions & 13 deletions src/Widget/Select.php
Expand Up @@ -33,6 +33,7 @@ final class Select extends Widget
/** @var string[] */
private array $optionsData = [];
private array $prompt = [];
private ?string $unselectValue = null;

/**
* The attributes for the optgroup tags.
Expand Down Expand Up @@ -205,6 +206,13 @@ public function size(int $value = 4): self
return $new;
}

public function unselectValue(?string $value): self
{
$new = clone $this;
$new->unselectValue = $value;
return $new;
}

/**
* @return Optgroup[]|Option[]
*/
Expand Down Expand Up @@ -246,6 +254,13 @@ protected function run(): string
$new = clone $this;
$select = SelectTag::tag();

/** @var iterable<int, scalar|Stringable>|scalar|Stringable|null */
$value = HtmlForm::getAttributeValue($new->getFormModel(), $new->attribute);

if (is_object($value)) {
throw new InvalidArgumentException('Select widget value can not be an object.');
}

if (isset($new->attributes['multiple']) && !isset($new->attributes['size'])) {
$new = $new->size();
}
Expand All @@ -268,18 +283,6 @@ protected function run(): string
$select = $select->optionsData($new->optionsData, $new->encode);
}

/** @var iterable<int, scalar|Stringable>|scalar|Stringable|null */
$value = HtmlForm::getAttributeValue($new->getFormModel(), $new->attribute) ?? '';

if (is_object($value)) {
throw new InvalidArgumentException('Select widget required bool|float|int|iterable|string|null.');
}

/** @var string|null */
$unselectValue = $new->attributes['unselectValue'] ?? null;

unset($new->attributes['unselectValue']);

if (is_iterable($value)) {
$select = $select->values($value);
} elseif (null !== $value) {
Expand All @@ -291,7 +294,7 @@ protected function run(): string
->id($new->getId())
->name(HtmlForm::getInputName($new->getFormModel(), $new->attribute))
->promptOption($promptOption)
->unselectValue($unselectValue)
->unselectValue($new->unselectValue)
->render();
}
}

0 comments on commit eaac104

Please sign in to comment.