1

我用 silex 框架构建了一个表单,其中包含一些复选框和一个文本字段。用户必须至少选中一个复选框或在文本字段中写一些东西。现在我不知道如何验证这样的依赖或更好地将验证逻辑放在哪里。我可以向单个字段添加约束,但是如何实现复选框或文本字段的依赖关系?

这是我在控制器类中的验证代码。

public function validateAction(Request $request, Application $app)
{
    $form = $app['form.factory']->create(new ApplicationForm());
    $form->bind($request);
    if ($form->isValid()) {
        return $app->json(array(
            'success' => true,
        ));
    }
}

ApplicationForm 类看起来像这样(简化):

class ApplicationForm extends AbstractType {
    public function buildForm(FormBuilderInterface $builder, array $options) {
        $builder
            ->add('crafts', 'choice', array(
                'choices' => array(
                    array('drywall'     => 'Drywall'),
                    array('painter'     => 'Painter'),
                    array('plasterer'   => 'Plasterer'),
                    array('carpenter'   => 'Carpenter'),
                    array('electrician' => 'Electrician'),
                    array('plumber'     => 'Plumber'),
                    array('tiler'       => 'Tiler'),
                    array('bricklayer'  => 'Bricklayer'),
                ),
                'multiple' => true,
                'expanded' => true,
                'required' => false,
            ))
            ->add('craftsOther', 'text', array(
                'attr' => array('class' => 'textinput', 'placeholder' => 'Other', 'maxlength' => 256),
                'constraints' => array(
                    new Assert\Length(array('max' => 256, 'maxMessage' => $this->_errorMessages['crafts_other_max'])),
                ),
                'required' => false,
            ));
    }
}

任何想法如何以优雅的方式做到这一点?

4

1 回答 1

0

您可以向表单本身添加约束,而不仅仅是单个字段。您可以在选项中传递一组约束:

这是一个工作示例,在提交时检查两个字段是否不相等。

<?php

require_once __DIR__.'/../vendor/autoload.php';

use Silex\Application;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\SubmitType;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Validator\Context\ExecutionContextInterface;
use Symfony\Component\Validator\Constraints as Assert;

$app = new Application();

$app['debug'] = true;
$app->register(new \Silex\Provider\FormServiceProvider());
$app->register(new Silex\Provider\TranslationServiceProvider(), array('translator.domains' => array(),));
$app->register(new Silex\Provider\ValidatorServiceProvider());
$app->register(new Silex\Provider\TwigServiceProvider());

class ExampleFormType extends AbstractType
{

    public function buildForm(\Symfony\Component\Form\FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add('apple')
            ->add('banana')
            ->add('submit', SubmitType::class);
    }

    public function configureOptions(\Symfony\Component\OptionsResolver\OptionsResolver $resolver)
    {
        $resolver->setDefaults([
            'constraints' => [
                new Assert\Callback(function (array $data, ExecutionContextInterface $context) {
                    if ($data['apple'] === $data['banana']) {
                        $context
                            ->buildViolation('Apple and Banana cannot be the same')
                            ->atPath('apple')
                            ->addViolation();
                    }
                }),
            ],
        ]);
    }
}

$app->match('/', function (Request $request, Application $app) {
    $form = $app['form.factory']->create(ExampleFormType::class)->handleRequest($request);
    if ($form->isValid()) {
        echo "Valid Submission";
    }

    return $app['twig']->createTemplate('{{ form(form) }}')->render([
        'form' => $form->createView(),
    ]);
})->method('GET|POST');

$app->run();
于 2016-03-13T07:44:16.687 回答