symfony 2.3を使用していますので、明らかにhereという 'allow_extra_fields'オプションは使用できません。フォームのサブスクライバと "このフォームには余分なフィールドを含めてはいけません"エラー
Iメインフォームタイプ、RegistrationStep1UserType有する:
/**
* Class RegistrationStep1UserType
* @package Evo\DeclarationBundle\Form\Type
*/
class RegistrationStep1UserType extends AbstractType
{
/**
* @param FormBuilderInterface $builder
* @param array $options
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('customer', new RegistrationStep1CustomerType(), [
'label' => false,
'data_class' => 'Evo\UserBundle\Entity\Customer',
'cascade_validation' => true,
])
->add('declaration', 'evo_declaration_bundle_registration_step1_declaration_type', [
'label' => false,
'cascade_validation' => true,
])
;
}
/**
* @param OptionsResolverInterface $resolver
*/
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'Evo\UserBundle\Entity\User',
'validation_groups' => false,
));
}
/**
* @return string
*/
public function getName()
{
return 'evo_declaration_bundle_registration_step1_user_type';
}
}
このフォームタイプはサービスとして登録( "宣言" フィールドに)埋め込みフォームタイプ、RegistrationStep1DeclarationTypeを含む:
/**
* Class RegistrationStep1DeclarationType
* @package Evo\DeclarationBundle\Form\Type
*/
class RegistrationStep1DeclarationType extends AbstractType
{
/**
* @var EntityManagerInterface
*/
private $em;
/**
* @var EventSubscriberInterface
*/
private $addBirthCountyFieldSubscriber;
/**
* RegistrationStep1DeclarationType constructor.
* @param EntityManagerInterface $em
* @param EventSubscriberInterface $addBirthCountyFieldSubscriber
*/
public function __construct(EntityManagerInterface $em, EventSubscriberInterface $addBirthCountyFieldSubscriber)
{
$this->em = $em;
$this->addBirthCountyFieldSubscriber = $addBirthCountyFieldSubscriber;
}
/**
* @param FormBuilderInterface $builder
* @param array $options
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('birthLastname', null, [
'label' => 'Nom de naissance',
'attr' => [
'required' => true,
],
])
->add('nationality', 'entity', [
'label' => 'Nationalité',
'class' => 'Evo\GeoBundle\Entity\Country',
'property' => 'nationalityFr',
'attr' => [
'required' => true,
'class' => 'selectpicker',
],
'preferred_choices' => $this->fillPreferredNationalities(),
])
->add('birthCountry', 'entity', [
'label' => 'Pays de naissance',
'class' => 'Evo\GeoBundle\Entity\Country',
'property' => 'nameFr',
'empty_value' => '',
'empty_data' => null,
'attr' => [
'required' => true,
'class' => 'trigger-form-modification selectpicker',
],
'preferred_choices' => $this->fillPreferredBirthCountries(),
])
->add('birthCity', null, [
'label' => 'Ville de naissance',
'attr' => [
'required' => true,
],
])
;
$builder->get("birthCountry")->addEventSubscriber($this->addBirthCountyFieldSubscriber);
}
/**
* @return array
*/
private function fillPreferredNationalities()
{
$nationalities = $this->em->getRepository("EvoGeoBundle:Country")->findBy(["isDefault" => true]);
return $nationalities;
}
/**
* @return array|\Evo\GeoBundle\Entity\Country[]
*/
private function fillPreferredBirthCountries()
{
$countries = $this->em->getRepository("EvoGeoBundle:Country")->findBy(["isDefault" => true]);
return $countries;
}
/**
* @param OptionsResolverInterface $resolver
*/
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
$resolver->setDefaults(array(
'required' => false,
'data_class' => 'Evo\DeclarationBundle\Entity\Declaration',
'validation_groups' => false,
));
}
/**
* @return string
*/
public function getName()
{
return 'evo_declaration_bundle_registration_step1_declaration_type';
}
}
をこの埋め込みフォームタイプは、「birthCountry」フィールドにサブスクライバ(EntityManagerの注入が必要なためサービスとしても登録されています)を追加します。
birthCountryの選択リストの値に応じて、追加のフィールド(「birthCounty」と呼ばれる)を動的に追加または削除することを目標にしています(ここでは、2つのフィールドは「birthCountry」と「birthCounty」です)。鑑み
/**
* Class AddBirthCountyFieldSubscriber
* @package Evo\CalculatorBundle\Form\EventListener
*/
class AddBirthCountyFieldSubscriber implements EventSubscriberInterface
{
/**
* @var EntityManagerInterface
*/
private $em;
/**
* AddBirthCountyFieldSubscriber constructor.
* @param EntityManagerInterface $em
*/
public function __construct(EntityManagerInterface $em)
{
$this->em = $em;
}
/**
* @return array
*/
public static function getSubscribedEvents()
{
return array(
FormEvents::POST_SET_DATA => 'postSetData',
FormEvents::POST_SUBMIT => 'postSubmit',
);
}
/**
* @param FormEvent $event
*/
public function postSetData(FormEvent $event)
{
$birthCountry = $event->getData();
$form = $event->getForm()->getParent();
$this->removeConditionalFields($form);
if ($birthCountry instanceof Country && true === $birthCountry->getIsDefault()) {
$this->addBirthCountyField($form);
}
}
/**
* @param FormEvent $event
*/
public function postSubmit(FormEvent $event)
{
$birthCountry = $event->getData();
$form = $event->getForm()->getParent();
if (!empty($birthCountry)) {
$country = $this->em->getRepository("EvoGeoBundle:Country")->find($birthCountry);
$this->removeConditionalFields($form);
if ($country instanceof Country && true === $country->getIsDefault()) {
$this->addBirthCountyField($form);
}
}
}
/**
* @param FormInterface $form
*/
private function addBirthCountyField(FormInterface $form)
{
$form
->add('birthCounty', 'evo_geo_bundle_autocomplete_county_type', [
'label' => 'Département de naissance',
'attr' => [
'required' => true,
],
])
;
}
/**
* @param FormInterface $form
*/
private function removeConditionalFields(FormInterface $form)
{
$form->remove('birthCounty');
}
}
、「birthCountry」選択リストの変更説明したように、それが要求を処理し、再びビューをレンダリングコントローラ(にAJAXリクエストをトリガする:ここ
が加入者であります)documentation about dynamic form submissionに:
$form = $this->createForm(new RegistrationStep1UserType(), $user);
if ($request->isXmlHttpRequest()) {
$form->handleRequest($request);
} elseif ("POST" == $request->getMethod()) {
[...]
}
問題は次のとおりです。
私はbirthCountry選択リストとセレク上の変更を行う場合にはtaの国が「birthCounty」フィールドを非表示になって、フォームが正しくそのフィールドなしでレンダリングしますが、それはエラーメッセージを示しています。
:私は多くの異なった解決策を試してみましたCe formulaire ne doit pas contenir des champs supplémentaires.
または
this form should not contain extra fields (in english)
を
- RegistrationStep1UserTypeとRegistrationStep1DeclarationTypeに 'validation_groups'オプションを追加します。
- AddSubmitイベントをAddBirに追加します。 birthCountyフィールドに
'mapped' => false,
を追加しても、preSetDataメソッドとpostSubmitメソッドのロジックを複製するthCountyFieldSubscriber - がエラーをトリガします。非常に驚くべき
私はちょうど\ symfonyの\ symfonyの\ SRC \ symfonyの\コンポーネント\フォーム\拡張\ Validatorは\ FormValidator \制約は、私が見ることができる$form->handleRequest($request);
後しかし、ベンダーにそれをダンプした場合であっても$form->getExtraData()
空であります余分なフィールドここ
array(1) {
["birthCounty"]=>
string(0) ""
}
:
// Mark the form with an error if it contains extra fields
if (count($form->getExtraData()) > 0) {
echo '<pre>';
\Doctrine\Common\Util\Debug::dump($form->getExtraData());
echo '</pre>';
die();
$this->context->addViolation(
$config->getOption('extra_fields_message'),
array('{{ extra_fields }}' => implode('", "', array_keys($form->getExtraData()))),
$form->getExtraData()
);
}
は私がについて何かを欠場動的な追加フィールドを作成しますか?
これはおそらく動作しますが、それは本当に回避策のように見えます。 – VaN
@VaN本当に回避策がわからない – DonCallisto