Значения подчиненной формы отображаются как нулевые на принимающей стороне после отправки формы

Я построил форму, которая отлично отправляет, однако все значения подчиненной формы заканчиваются нулевым значением на принимающей стороне, когда я смотрю на них в контроллере.

Вот моя форма UserProfileType, основанная на классе User. Итак, рассматриваемые нами субформы — это subscriptionTier1, subscriptionTier1 и subscriptionTier1:

class UserProfileType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add('firstName', TextType::class)
            ->add('lastName', TextType::class)
            ->add('email', EmailType::class)

            // etc... I'll keep out the unimportant fields

            // here are the subforms whose values show up as null on the back end
            ->add('subscriptionTier1', UserSubscriptionTierType::class, [
                'required' => false,
                'mapped' => false
                ])
            ->add('subscriptionTier2', UserSubscriptionTierType::class, [
                    'required' => false,
                    'mapped' => false
                ])
            ->add('subscriptionTier3', UserSubscriptionTierType::class, [
                    'required' => false,
                    'mapped' => false
                ])
            ->add('save', SubmitType::class, [
                'attr' => ['class' => 'save'],
            ])
        ;

public function configureOptions(OptionsResolver $resolver)
{
    $resolver->setDefaults(array(
            'data_class' => User::class,
            'mode' => null
        )
    );
}

}

Вот как выглядит мой класс типа формы UserSubscriptionTierType:

class UserSubscriptionTierType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add('name', TextType::class, [
                'attr' => [
                    'maxlength' => 25
                ]
            ])
            ->add('price', ChoiceType::class, [
                'choices' => [
                    '$10 per month' => 10,
                    '$20 per month' => 20,
                    '$30 per month' => 30
                ]
            ])
            ->add('description', TextareaType::class)
            ->add('messaging', CheckboxType::class, [
                'required' => false
            ])
        ;
    }

    public function configureOptions(OptionsResolver $resolver)
    {
        $resolver->setDefaults(array(
            'data_class' => UserSubscriptionTier::class,
        ));
    }
}

Как вы можете видеть на рисунке ниже, все значения имени, цены и описания подчиненной формы подпискиTier1 устанавливаются во внешнем интерфейсе:

Значения подчиненной формы отображаются как нулевые на принимающей стороне после отправки формы

Вот как выглядит код ветки для подформы subscriptionTier1:

    <div class = "row justify-content-center w-100 ml-0 mr-0 mt-3 tier tier-1" >
        <div class = "col-lg-6 mt-1">
            <div class = "form-group form-control-lg w-100">
                <label for = "firstname" class = "mb-2">Tier 1 Name</label>
                {{ form_widget(form.subscriptionTier1.name, { 'attr': {'class': 'form-control'}}) }}
            </div>
        </div>
        <div class = "col-lg-6 mt-1">
            <div class = "form-group form-control-lg w-100">
                <label for = "tier1price" class = "mb-2">Tier 1 Price</label>
                {{ form_widget(form.subscriptionTier1.price, { 'attr': {'class': 'form-control'}}) }}
            </div>
        </div>
        <div class = "col-lg-12 mt-3">
            <div class = "form-group form-control-lg w-100">
                <label for = "bio" class = "mb-2">Tier 1 Description
                    <sup class = "text-danger">*</sup>
                </label>
                {{ form_widget(form.subscriptionTier1.description, { 'attr': {'class': 'form-control border-box', 'rows':'8'}}) }}
            </div>
        </div>
        <div class = "col-lg-12">
            <div class = "form-group form-control-lg w-100">
                <div class = "form-check">
                    <label class = "form-check-label">
                        {{ form_widget(form.subscriptionTier1.messaging, { 'attr': {'class': 'form-control form-check-input'}}) }}
                        <span class = "form-check-sign"></span>
                        Enable Messaging
                    </label>
                </div>
            </div>
        </div>
    </div>

Вот код на принимающей стороне, контроллере:

public function saveProfileAction(Request $request)
{
    $user = $this->getUser();

    $form = $this->createForm(UserProfileType::class, $user);
    $form->handleRequest($request);

dump($form->get('subscriptionTier1')->getData()); 

Итак, при отладке, если я выгружу только первую форму subscriptionTier1, вы увидите, что все значения — null.

ProfileController.php on line 269:
Form {#2235 ▼
  -config: FormBuilder {#2236 ▶}
  -parent: Form {#2112 ▶}
  -children: OrderedHashMap {#2237 ▶}
  -errors: []
  -submitted: true
  -clickedButton: null
  -modelData: UserSubscriptionTier {#2280 ▼
    -id: null
    -posts: ArrayCollection {#2323 ▶}
    -subscriptions: null
    -name: null         // Don't understand why this is null 
    -price: null        // Don't understand why this is null 
    -description: null  // Don't understand why this is null 
    -tierNumber: null
    -versionNumber: null
    -messaging: false
    -user: null
    +"subsciptions": ArrayCollection {#2089 ▶}
  }
  -normData: UserSubscriptionTier {#2280 ▶}
  -viewData: UserSubscriptionTier {#2280 ▶}
  -extraData: []
  -transformationFailure: null
  -defaultDataSet: true
  -lockSetData: false
}

Кто-нибудь знает, почему значения не передаются на сервер (или обнуляются)?

Если его нет в объекте Request (вы также можете проверить необработанные данные $_POST), то вам следует проверить отображаемый HTML. Если данные не приходят с запросом, вы мало что можете сделать на стороне сервера.

Jakub Matczak 11.02.2019 09:09
JS - События опций формы
JS - События опций формы
В продолжение предыдущей статьи CSS - стили, связанные с вводом формы , в этой статье мы будем использовать JS для взаимодействия с формами, на этот...
CSS - Стили, связанные с вводом формы
CSS - Стили, связанные с вводом формы
Общими стилями ввода для форм являются Input (включая Text, Radio, checkbox), Select и Textarea, из которых Input относительно прост, поэтому в этой...
Создание многостраничной формы заявления о приеме на работу с помощью Angular
Создание многостраничной формы заявления о приеме на работу с помощью Angular
Наличие на корпоративном сайте форм заявлений о приеме на работу, или "трудовых анкет", экономит время и деньги как для соискателей, так и для...
6
1
127
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Поскольку параметр data_class типа формы UserProfileType установлен на класс User, данные модели будут экземпляром класса User, а поскольку класс User не имеет таких полей, как subscriptionTier1 и т. д., они не будут отображаться в ваших данных модели.

Вместо этого вы можете получить доступ к несопоставленным полям в форме в контроллере следующим образом:

$subscriptionTier1 = $form->get('subscriptionTier1')->getData();

Документация здесь

Обновлено: вы можете получить доступ только к значению subscribeTier1 и т. д., только после обработки формы и только в том случае, если форма была отправлена, иначе она будет нулевой:

public function saveProfileAction(Request $request)
{
    $user = $this->getUser();

    $form = $this->createForm(UserProfileType::class, $user);
    $form->handleRequest($request);

    if ($form->isSubmitted() && $form->isValid()) {
        $subscriptionTier1 = $form->get('subscriptionTier1')->getData();
        dump($subscriptionTier1);
    }

Привет irxs, спасибо, это было большой помощью. Теперь все значения формы равны нулю. Мне придется отредактировать вопрос. Но это все равно было большим подспорьем.

Brent Heigold 11.02.2019 17:13

Я отредактировал свой ответ, чтобы помочь вам лучше понять его

iiirxs 12.02.2019 08:36

Я не знаю, является ли это просто обходным путем или на самом деле это лучший способ сделать это, но вот как я заставил его работать:

У меня были следующие теги подчиненной формы: {{ form_start(form.subscriptionTier1) }} etc... {{ form_end(form.subscriptionTier1) }}

Это будет вкладывать теги формы. Очевидно, вам не разрешено вкладывать такие формы.

Таким образом, удаление {{ form_start(form.subscriptionTier1) }} , {{ form_end(form.subscriptionTier1) }} для всех subscriptionTier1, subscriptionTier1, subscriptionTier1, а затем проверка значений формы в объекте запроса сработали.

Другие вопросы по теме