Skip to content

Commit 01f32eb

Browse files
alvidenalviden
andauthored
Update forms tutorial (en) (#224)
Co-authored-by: alviden <[email protected]>
1 parent 486db97 commit 01f32eb

File tree

3 files changed

+88
-48
lines changed

3 files changed

+88
-48
lines changed

guide/en/start/forms.md

Lines changed: 88 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -25,31 +25,18 @@ saved in the file `/src/Form/EchoForm.php`:
2525
<?php
2626
namespace App\Form;
2727

28-
use Yiisoft\Form\FormModel;
29-
30-
class EchoForm extends FormModel
28+
class EchoForm
3129
{
3230
private string $message = '';
3331

3432
public function getMessage(): string
3533
{
3634
return $this->message;
3735
}
38-
39-
public function getPropertyLabels(): array
40-
{
41-
return [
42-
'message' => 'Message',
43-
];
44-
}
4536
}
4637
```
4738

48-
The class extends from a base class provided by Yii, commonly used to
49-
represent form data.
50-
5139
The `EchoForm` class has `$message` property and related getter.
52-
These are regular data-related code. `getPropertyLabels()` method provides labels that you're going to display in a view.
5340

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

@@ -85,7 +72,7 @@ class EchoController
8572
$hydrator = new Hydrator();
8673

8774
if ($request->getMethod() === Method::POST) {
88-
$hydrator->hydrate($form, $request->getParsedBody()[$form->getFormName()]);
75+
$hydrator->hydrate($form, $request->getParsedBody()['EchoForm']);
8976
}
9077

9178
return $this->viewRenderer->render('say', [
@@ -123,7 +110,7 @@ To render a form, you need to change your view, `resources/views/echo/say.php`:
123110
```php
124111
<?php
125112

126-
use Yiisoft\Form\Field;
113+
use Yiisoft\Form\Field\Text;
127114
use Yiisoft\Html\Html;
128115

129116
/* @var \App\Form\EchoForm $form */
@@ -143,7 +130,12 @@ use Yiisoft\Html\Html;
143130
->csrf($csrf)
144131
->open() ?>
145132

146-
<?= Field::text($form, 'message') ?>
133+
<?= Text::widget()
134+
->name('EchoForm[message]')
135+
->value($form->getMessage())
136+
->label('Message')
137+
->placeholder('Type your message')
138+
->inputId('echoform-message'); ?>
147139

148140
<?= Html::submitButton('Say') ?>
149141

@@ -157,11 +149,12 @@ You access it as `$urlGenerator` that's a default parameter available in all vie
157149
This variable and alike ones such as `$csrf` are provided by view injections listed in `config/common/params.php`:
158150

159151
```php
160-
'yiisoft/yii-view' => [
152+
'yiisoft/yii-view-renderer' => [
161153
'injections' => [
162154
Reference::to(CommonViewInjection::class),
163155
Reference::to(CsrfViewInjection::class),
164156
Reference::to(LayoutViewInjection::class),
157+
Reference::to(TranslatorViewInjection::class),
165158
],
166159
],
167160
```
@@ -170,30 +163,42 @@ You set the value of CSRF token, and it is rendered as a hidden input to ensure
170163
the form page and not from another website. It will be submitted along with POST form data. Omitting it would result in
171164
[HTTP response code 422](https://tools.ietf.org/html/rfc4918#section-11.2).
172165

173-
To turn on the CSRF protection, you need to add `CsrfMiddleware` to `config/web/params.php`:
166+
CSRF protection is enabled by default. To turn off the CSRF protection,
167+
you need to remove using `CsrfMiddleware` or `CsrfTokenMiddleware` to `config/common/di/router.php`:
174168

175169
```php
176170
<?php
177171

178172
declare(strict_types=1);
179173

180-
use Yiisoft\ErrorHandler\Middleware\ErrorCatcher;
181-
use Yiisoft\Router\Middleware\Router;
182-
use Yiisoft\Session\SessionMiddleware;
174+
use Yiisoft\Config\Config;
183175
use Yiisoft\Csrf\CsrfMiddleware;
176+
use Yiisoft\DataResponse\Middleware\FormatDataResponse;
177+
use Yiisoft\Router\Group;
178+
use Yiisoft\Router\RouteCollection;
179+
use Yiisoft\Router\RouteCollectionInterface;
180+
use Yiisoft\Router\RouteCollectorInterface;
181+
182+
/** @var Config $config */
184183

185184
return [
186-
'middlewares' => [
187-
ErrorCatcher::class,
188-
SessionMiddleware::class,
189-
CsrfMiddleware::class, // <-- here
190-
Router::class,
191-
],
185+
RouteCollectionInterface::class => static function (RouteCollectorInterface $collector) use ($config) {
186+
$collector
187+
->middleware(CsrfMiddleware::class) // <-- here
188+
->middleware(FormatDataResponse::class)
189+
->addGroup(
190+
Group::create()
191+
->routes(...$config->get('routes'))
192+
);
193+
194+
return new RouteCollection($collector);
195+
},
196+
];
192197

193198
// ...
194199
```
195200

196-
You use `Field::text()` to output "message" field, so it takes case about filling the value, escaping it,
201+
You use `Text::widget()` to output "message" field, so it takes case about filling the value, escaping it,
197202
rendering field label and validation errors you're going to take care of next.
198203

199204
## Adding validation
@@ -226,14 +231,19 @@ class EchoController
226231
{
227232
$form = new EchoForm();
228233
$hydrator = new Hydrator();
234+
$errors = null;
229235

230236
if ($request->getMethod() === Method::POST) {
231237
$hydrator->hydrate($form, $request->getParsedBody()[$form->getFormName()]);
232-
$validator->validate($form);
238+
$result = $validator->validate($form);
239+
if (!$result->isValid()) {
240+
$errors = $result->getErrors();
241+
}
233242
}
234243

235244
return $this->viewRenderer->render('say', [
236245
'form' => $form,
246+
'errors' => $errors,
237247
]);
238248
}
239249
}
@@ -246,37 +256,67 @@ Now you need to add validation rules to `/src/Form/EchoForm.php`:
246256
<?php
247257
namespace App\Form;
248258

249-
use Yiisoft\Form\FormModel;
250259
use Yiisoft\Validator\Rule\Required;
251-
use Yiisoft\Validator\RulesProviderInterface;
252260

253-
class EchoForm extends FormModel implements RulesProviderInterface
261+
class EchoForm
254262
{
263+
#[Required]
255264
private string $message = '';
256265

257266
public function getMessage(): string
258267
{
259268
return $this->message;
260269
}
261270

262-
public function getPropertyLabels(): array
263-
{
264-
return [
265-
'message' => 'Message',
266-
];
267-
}
268-
269-
public function getRules() : iterable{
270-
return [
271-
'message' => [
272-
new Required()
273-
]
274-
];
275-
}
276271
}
277272
```
278273

279-
Now, in case you will submit an empty message you will get a validation error: "Value cannot be blank."
274+
Now, in case you will submit an empty message you will get a validation error: "Message cannot be blank."
275+
Also, you can add required attribute to text field in `views/echo/say.php`.
276+
277+
```php
278+
<?php
279+
280+
use Yiisoft\Form\Field\Text;
281+
use Yiisoft\Html\Html;
282+
283+
/* @var \App\Form\EchoForm $form */
284+
/* @var \Yiisoft\Validator\Error[]|null $errors */
285+
/* @var string $csrf */
286+
/* @var \Yiisoft\Router\UrlGeneratorInterface $urlGenerator */
287+
?>
288+
289+
290+
<?php if (!empty($form->getMessage())): ?>
291+
<div class="notification is-success">
292+
The message is: <?= Html::encode($form->getMessage()) ?>
293+
</div>
294+
<?php endif ?>
295+
<?php if (!empty($errors)): ?>
296+
<?php foreach($errors as $error): ?>
297+
<div class="notification is-errors">
298+
<?= Html::encode($error->getMessage()) ?>
299+
</div>
300+
<?php endforeach; ?>
301+
<?php endif ?>
302+
303+
<?= Html::form()
304+
->post($urlGenerator->generate('print/form'))
305+
->csrf($csrf)
306+
->open() ?>
307+
308+
<?= Text::widget()
309+
->name('EchoForm[message]')
310+
->value($form->getMessage())
311+
->label('Message')
312+
->placeholder('Type your message')
313+
->required(true) // <-- here
314+
->inputId('echoform-message'); ?>
315+
316+
<?= Html::submitButton('Say') ?>
317+
318+
<?= '</form>' ?>
319+
```
280320

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

guide/en/start/img/form-error.png

20 Bytes
Loading
-907 Bytes
Loading

0 commit comments

Comments
 (0)