如何使用"货币类型"字段验证表单帖子?
它使用 input type="text"
而不是 type="number"
已经够糟糕的了,但更糟糕的是,输入什么并不重要,比如"asdf",响应总是: valid form posted.
如何获得有用的错误消息,指示用户他们需要输入有效的金额,例如"43.21"?
我尝试'error_bubbling' => true
添加选项,{{ form_errors(form) }}
在树枝视图中,$form->getErrors()
按照这个答案的建议在控制器中,但这些总是空的,因为无论如何,无论用户输入如何,$form->isValid()
总是返回 true。
项目结构:
.
├── composer.json
├── composer.lock
├── pub
│ └── scratch.php
├── vendor
│ └── ...
└── views
└── form.html.twig
scratch.php
<?php require_once __DIR__.'/../vendor/autoload.php';
use Symfony'Component'Form'Forms;
use Symfony'Component'Form'Extension'Core'Type'MoneyType;
use Symfony'Component'Form'Extension'HttpFoundation'HttpFoundationExtension;
use Symfony'Component'HttpFoundation'Request;
use Symfony'Component'Translation'Translator;
use Symfony'Bridge'Twig'Form'TwigRenderer;
use Symfony'Bridge'Twig'Form'TwigRendererEngine;
use Symfony'Bridge'Twig'Extension'FormExtension;
use Symfony'Bridge'Twig'Extension'TranslationExtension;
// the Twig file that holds all the default markup for rendering forms
// this file comes with TwigBridge
$defaultFormTheme = 'form_div_layout.html.twig';
$appVariableReflection = new 'ReflectionClass(''Symfony'Bridge'Twig'AppVariable');
$vendorTwigBridgeDir = dirname($appVariableReflection->getFileName());
// the path to your other templates
$viewsDir = realpath(__DIR__.'/../views');
$twig = new Twig_Environment(new Twig_Loader_Filesystem(array(
$viewsDir,
$vendorTwigBridgeDir.'/Resources/views/Form',
)));
$formEngine = new TwigRendererEngine(array($defaultFormTheme));
$twig->addExtension(
new FormExtension(new TwigRenderer($formEngine))
);
$twig->addExtension(
new TranslationExtension(new Translator('en'))
);
$formEngine->setEnvironment($twig);
// create your form factory as normal
$formFactory = Forms::createFormFactoryBuilder()
->addExtension(new HttpFoundationExtension())
->getFormFactory();
$formBuilder = $formFactory->createBuilder();
$formBuilder->add("amount", MoneyType::class, [
'currency' => 'USD',
'error_bubbling' => true
]);
$form = $formBuilder->getForm();
$request = Request::createFromGlobals();
$form->handleRequest($request);
if ($form->isValid()) {
die('valid form posted.');
}
$form->getErrors(true);
echo $twig->render('form.html.twig', array(
'form' => $form->createView(),
));
form.html.twig
{{ form_start(form) }}
{{ form_errors(form) }}
{{ form_widget(form) }}
<input type="submit" />
{{ form_end(form) }}
composer.json
{
"require": {
"symfony/form": "^3.1",
"symfony/twig-bridge": "^3.1",
"symfony/translation": "^3.1",
"symfony/http-foundation": "^3.1"
}
}
我发现我缺少验证器组件。
use Symfony'Component'Validator'Validation;
// Set up the Validator component
$validator = Validation::createValidator();
然后,我需要将验证器扩展添加到表单工厂。
use Symfony'Component'Form'Extension'Validator'ValidatorExtension;
// create your form factory as normal
$formFactory = Forms::createFormFactoryBuilder()
...
->addExtension(new ValidatorExtension($validator))
...
这当然需要composer require symfony/validator
所以,我不需要
-
$form->getErrors(true)
-
'error_bubbling' => true
-
{{ form_errors(form) }}
scratch.php
<?php require_once __DIR__.'/../vendor/autoload.php';
use Symfony'Component'Form'Forms;
use Symfony'Component'Form'Extension'Core'Type'MoneyType;
use Symfony'Component'Form'Extension'HttpFoundation'HttpFoundationExtension;
use Symfony'Component'Form'Extension'Validator'ValidatorExtension;
use Symfony'Component'HttpFoundation'Request;
use Symfony'Component'Translation'Translator;
use Symfony'Component'Validator'Validation;
use Symfony'Bridge'Twig'Form'TwigRenderer;
use Symfony'Bridge'Twig'Form'TwigRendererEngine;
use Symfony'Bridge'Twig'Extension'FormExtension;
use Symfony'Bridge'Twig'Extension'TranslationExtension;
// the Twig file that holds all the default markup for rendering forms
// this file comes with TwigBridge
$defaultFormTheme = 'form_div_layout.html.twig';
$appVariableReflection = new 'ReflectionClass(''Symfony'Bridge'Twig'AppVariable');
$vendorTwigBridgeDir = dirname($appVariableReflection->getFileName());
// the path to your other templates
$viewsDir = realpath(__DIR__.'/../views');
$twig = new Twig_Environment(new Twig_Loader_Filesystem(array(
$viewsDir,
$vendorTwigBridgeDir.'/Resources/views/Form',
)));
$formEngine = new TwigRendererEngine(array($defaultFormTheme));
$twig->addExtension(
new FormExtension(new TwigRenderer($formEngine))
);
$twig->addExtension(
new TranslationExtension(new Translator('en'))
);
$formEngine->setEnvironment($twig);
// Set up the Validator component
$validator = Validation::createValidator();
// create your form factory as normal
$formFactory = Forms::createFormFactoryBuilder()
->addExtension(new HttpFoundationExtension())
->addExtension(new ValidatorExtension($validator))
->getFormFactory();
$formBuilder = $formFactory->createBuilder();
$formBuilder->add("amount", MoneyType::class, [
'currency' => 'USD'
]);
$form = $formBuilder->getForm();
$request = Request::createFromGlobals();
$form->handleRequest($request);
if ($form->isValid()) {
die('valid form posted.');
}
$form->getErrors(true);
echo $twig->render('form.html.twig', array(
'form' => $form->createView(),
));
form.html.twig
{{ form_start(form) }}
{{ form_widget(form) }}
<input type="submit" />
{{ form_end(form) }}
composer.json
{
"require": {
"symfony/form": "^3.1",
"symfony/twig-bridge": "^3.1",
"symfony/translation": "^3.1",
"symfony/http-foundation": "^3.1"
"symfony/validator": "^3.1"
}
}
您必须将一个或多个约束附加到表单字段,如下所示:
use Symfony'Component'Validator'Constraints'Regex;
$formBuilder->add("amount", MoneyType::class, [
'currency' => 'USD',
'error_bubbling' => true,
'constraints' => [
new Regex(array('pattern'=>'/'d+('.'d+)?/','message'=>'must be numeric')),
]
]);
然后,如果违反约束,将显示消息"必须是数字",并且您的表单将无效。
内置约束定义如下:http://symfony.com/doc/current/reference/constraints.html
验证用法解释如下:http://symfony.com/doc/current/book/forms.html#using-a-form-without-a-class