5

ユーザーのアカウント領域をさまざまなフォームに分割してから、登録フォームのためにこれらのビットを次のようにまとめています。

class RegistrationFormType extends AbstractType
{

public function buildForm(FormBuilderInterface $builder, array $options)
{
    $builder
        ->add('email', 'email', array(
            'label' => '* Email address:'
        ))
        ->add('account_personal', 'my_personalinfo_form', array(
            'property_path' => 'account'
        ))
        ->add('account_contact', 'my_contactinfo_form', array(
            'property_path' => 'account'
        ))
    ;
}

問題は、 のエラー メッセージaccount_personalがフォームの上部に泡立っていることです。たとえば、個人情報フォームで名前が空白のままの場合は、「名前を入力してください」と入力します。「個人用」フォームと「連絡先」フォームは、それぞれのページの独自のフォームで正常に機能します。

のエラー メッセージaccount_contactは問題なく、正しいフィールドの横に表示されます。

->addただし、上記の2ビットを交換すると(account_contact最初に持っている)、問題は逆になります。workのエラー メッセージはaccount_personal対応するフィールドの横に正しく表示されるようになりましたが、account_contact取得のエラーが一番上に表示されます。

どんな提案でも大歓迎です!

- - - 編集 - - -

個人情報フォーム:

class PersonalInfoType extends AbstractType
{

public function buildForm(FormBuilderInterface $builder, array $options)
{
    $builder
        ->add('title', 'text')
        ->add('first_name', 'text', array(
            'required' => true,
            'label' => '* First name:'
        ))
        ->add('last_name', 'text', array(
            'required' => true,
            'label' => '* Surname:'
        ))
    ;
}

public function setDefaultOptions(OptionsResolverInterface $resolver)
{
    $resolver->setDefaults(array(
        'data_class' => 'My\UserBundle\Entity\Account',
        'validation_groups' => array('personalInfo')
    ));
}

public function getName()
{
    return 'my_personalinfo_form';
}

連絡先情報フォーム:

class ContactInfoType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
    $builder
        ->add('postcode', 'text', array(
            'required' => true
        ))
        ->add('address_1', 'text', array(
            'required' => true
        ))
        ->add('address_2', 'text', array(
            'required' => false
        ))
        ->add('address_3', 'text', array(
            'required' => false
        ))
        ->add('town', 'text')
        ->add('phone_daytime', 'text', array(
            'required' => true
        ))
        ->add('phone_mobile', 'text', array(
            'required' => true
        ))
    ;
}

public function setDefaultOptions(OptionsResolverInterface $resolver)
{
    $resolver->setDefaults(array(
        'data_class' => 'My\UserBundle\Entity\Account',
        'validation_groups' => array('contactInfo')
    ));
}

public function getName()
{
    return 'my_contactinfo_form';
}

および完了するための Account エンティティ:

/**
 * My\UserBundle\Entity\Account
 *
 * @ORM\Entity
 * @ORM\Table(
 *      name="accounts"
 * )
 */
class Account
{
/**
 * @ORM\Id
 * @ORM\Column(type="integer")
 * @ORM\GeneratedValue(strategy="AUTO")
 */
protected $id;

/**
 * @ORM\Column(type="string", length=25, nullable=true)
 * @Assert\Choice(choices = {"Mr", "Mrs", "Miss", "Ms", "Dr", "Prof"}, message = "Choose a valid title", groups={"personalInfo"})
 */
protected $title;

/**
 * @ORM\Column(type="string", length=150, nullable=true)
 * @Assert\NotBlank(message="Please enter your first name", groups={"personalInfo"})
 * @Assert\Length(max=150, maxMessage="null|Your first name must have less than {{ limit }} characters", groups={"personalInfo"})
 * @Assert\Regex(
 *     pattern="/\d/",
 *     match=false,
 *     message="Your name cannot contain a number"
 * )
 */
protected $first_name;

/**
 * @ORM\Column(type="string", length=150, nullable=true)
 * @Assert\NotBlank(message="Please enter your last name", groups={"personalInfo"})
 * @Assert\Length(max=150, maxMessage="null|Your last name must have less than {{ limit }} characters", groups={"personalInfo"})
 * @Assert\Regex(
 *     pattern="/\d/",
 *     match=false,
 *     message="Your name cannot contain a number"
 * )
 */
protected $last_name;

/**
 * @ORM\Column(type="string", length=255, nullable=true)
 * @MyAssert\Phone(message="Your daytime phone number is not valid", groups={"contactInfo"})
 */
protected $phone_daytime;

/**
 * @ORM\Column(type="string", length=255, nullable=true)
 * @MyAssert\MobilePhone(message="Your mobile phone number is not valid", groups={"contactInfo"})
 */
protected $phone_mobile;

/**
 * @ORM\Column(type="string", length=255)
 * @Assert\NotBlank(message="Please enter the first line of your address", groups={"contactInfo"}
 * @Assert\Length(max=250, maxMessage="null|The first line of your address must have less than {{ limit }} characters", groups={"contactInfo"})
 */
protected $address_1;

/**
 * @ORM\Column(type="string", length=255, nullable=true)
 * @Assert\Length(max=250, maxMessage="null|The second line of your address must have less than {{ limit }} characters", groups={"contactInfo"})
 */
protected $address_2;

/**
 * @ORM\Column(type="string", length=255, nullable=true)
 * @Assert\Length(max=250, maxMessage="null|The third line of your address must have less than {{ limit }} characters", groups={"contactInfo"})
 */
protected $address_3;

/**
 * @ORM\Column(type="string", length=45, nullable=true)
 * @Assert\NotBlank(message="Please enter your town", groups={"contactInfo"})
 * @Assert\Length(max=45, maxMessage="null|Your town name must have less than {{ limit }} characters", groups={"contactInfo"})
 */
protected $town;

/**
 * @ORM\Column(type="string", length=45, nullable=true)
 * @Assert\NotBlank(message="Please enter your postcode", groups={"contactInfo"})
 * @MyAssert\Postcode(message="Invalid postcode entered", groups={"contactInfo"})
 */
protected $postcode;

 ... etc
4

1 に答える 1

4

問題は、1 つのフォームで同じプロパティ パスを 2 回使用することにあります。ここで問題を提起しました:

https://github.com/symfony/symfony/issues/5578

このソリューションを投稿した場所:

仮想フィールドを使用して 2 つの埋め込みフォームを含む新しい FormType を作成する別の方法を思いつきました。

class RegistrationAccountFormType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
    $builder
        ->add('account_personal', 'my_personalinfo_form', array(
            'data_class' => 'My\UserBundle\Entity\Account',
            'virtual' => true
        ))
        ->add('account_contact', 'my_contactinfo_form', array(
            'data_class' => 'My\UserBundle\Entity\Account',
            'virtual' => true
        ))
    ;
}

public function setDefaultOptions(OptionsResolverInterface $resolver)
{
    $resolver->setDefaults(array(
        'data_class' => 'My\UserBundle\Entity\Account'
    ));
}

public function getName()
{
    return 'my_registration_account_form';
}
}

次に、メインの RegistrationFormType のこれらのフィールドを

->add('account', new RegistrationAccountFormType)

これは、これを行う「適切な」方法のように思えます。フォーム内で property_paths を一意に保ち、サブフォームでも property_path を変更する必要はありません。

于 2012-10-03T23:01:32.240 に答える