Skip to content
Draft
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 42 additions & 8 deletions src/guide/start/forms.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Working with forms

This section continues to improve on "Saying Hello." Instead of using URL, you will now ask a user for a message via form.
This section continues to improve on "Saying Hello." Instead of using URL, you will now ask a user for a message and a YAML value via form.

Through this tutorial, you will learn how to:

Expand All @@ -25,7 +25,8 @@ make composer require yiisoft/form-model
## Creating a form <span id="creating-form"></span>

The data to be requested from the user will be represented by a `Form` class as shown below and
saved in the file `/src/Web/Echo/Form.php`:
saved in the file `/src/Web/Echo/Form.php`. The example uses both built-in validation and custom
validation with the `Callback` rule:

```php
<?php
Expand All @@ -34,20 +35,51 @@ declare(strict_types=1);

namespace App\Web\Echo;

use Exception;
use Yiisoft\FormModel\FormModel;
use Yiisoft\Validator\Label;
use Yiisoft\Validator\Result;
use Yiisoft\Validator\Rule\Callback;
use Yiisoft\Validator\Rule\Length;

final class Form extends FormModel
{
#[Label('The message to be echoed')]
#[Length(min: 2)]
public string $message = '';

#[Label('YAML content')]
#[Callback(method: 'validateYaml')]
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@copilot Add label attribute

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done in d767eff: added a Label attribute to the yaml field in the main form example. Screenshot: /tmp/forms-label-attribute-updated.png.

public string $yaml = '';

private function validateYaml(mixed $value): Result
{
if (!is_string($value)) {
return (new Result())->addError('The value must be a string.');
}

$notYamlMessage = 'This value is not valid YAML.';

try {
$data = yaml_parse($value);
} catch (Exception) {
return (new Result())->addError($notYamlMessage);
}

if ($data === false) {
return (new Result())->addError($notYamlMessage);
}

return new Result();
}
}
```

In the above example, the `Form` has a single string property `$message` which length should be at least
of two characters. There's also a custom label for the property.
In the above example, the `Form` has a `$message` property validated with `Length` and a `$yaml` property validated
with the `Callback` rule using `validateYaml()`.
You can combine `Callback` with other attributes such as `Required`, `Length`, or `Regex` on the same property.
See [Callback rule details](https://github.com/yiisoft/validator/blob/master/docs/guide/en/built-in-rules-callback.md)
for full examples and available method signatures.

## Using the form <span id="using-form"></span>

Expand Down Expand Up @@ -142,11 +174,13 @@ $htmlForm = Html::form()

<?= $htmlForm->open() ?>
<?= Field::text($form, 'message')->required() ?>
<?= Field::textarea($form, 'yaml')->required() ?>
<?= Html::submitButton('Say') ?>
<?= $htmlForm->close() ?>

<?php if ($form->isValid()): ?>
Echo said: <?= Html::encode($form->message) ?>
YAML: <?= Html::encode($form->yaml) ?>
<?php endif ?>
```

Expand All @@ -168,11 +202,11 @@ The template renders the CSRF token value as a hidden input to ensure that the r
the form page and not from another website. It will be submitted along with POST form data. Omitting it would result in
[HTTP response code 422](https://tools.ietf.org/html/rfc4918#section-11.2).

You use `Field::text()` to output "message" field, so it takes care about filling the value, escaping it,
You use `Field::text()` and `Field::textarea()` to output "message" and "yaml" fields, so it takes care about filling the value, escaping it,
rendering field label and validation errors.

Now, in case you submit an empty message, you will get a validation error: "The message to be echoed must contain
at least 2 characters."
at least 2 characters." If `yaml` value is not valid YAML, you will also get a validation error.

## Trying it Out <span id="trying-it-out"></span>

Expand All @@ -182,9 +216,9 @@ To see how it works, use your browser to access the following URL:
http://localhost:8080/say
```

You will see a page with a form input field and a label that indicates what data to enter.
You will see a page with a text field and a textarea with labels that indicate what data to enter.
Also, the form has a "submit" button labeled "Say". If you click the "submit" button without entering anything, you will see
that the field is required. If you enter a single character, the form displays an error message next to
that fields are required. If you enter a single character in message or invalid YAML, the form displays an error message next to
the problematic input field.

![Form with a validation error](/images/guide/start/form-error.png)
Expand Down