1

いくつかのチェックボックスとテキストフィールドを含む silex フレームワークを使用してフォームを作成しました。ユーザーは、少なくとも 1 つのチェックボックスをオンにするか、テキストフィールドに何かを書き込む必要があります。今、そのような依存関係を検証する方法や、検証ロジックをどこに置くべきかがわかりません。単一のフィールドに制約を追加することはできますが、チェックボックスまたはテキストフィールドが検証されるという依存関係を実装するにはどうすればよいですか?

これは、コントローラー クラスの検証コードです。

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 に答える