I have built out a form which submits fine, however subform values all end up as null on the receiving end when I look at them in the controller.
Here is my UserProfileType
form, based on the User
class. So specifically, the subforms we are looking at are subscriptionTier1
, subscriptionTier1
, and 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
)
);
}
}
Here is what my UserSubscriptionTierType
form type class looks like:
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,
));
}
}
As you can see in the picture below, the subform subscriptionTier1's name, price, and description values are all set on the front-end:
Here is what the twig code looks like for the subscriptionTier1
subform:
<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>
Here is the code on the receiving end, the controller:
public function saveProfileAction(Request $request)
{
$user = $this->getUser();
$form = $this->createForm(UserProfileType::class, $user);
$form->handleRequest($request);
dump($form->get('subscriptionTier1')->getData());
So in debugging, if I dump just the first form subscriptionTier1
, you can see that the values are all 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
}
Would anyone know why the values are not passing to the back-end (or getting nulled out)?
Since the data_class
option of UserProfileType
form type is set to User
class, the model data will be an instance of User
class and since the User
class doesn't have fields like subscriptionTier1
etc, these will not appear in your model data.
Instead, you could access unmapped fields in a form in a controller like this:
$subscriptionTier1 = $form->get('subscriptionTier1')->getData();
Documentation here
EDIT: You can only access the value of subscriptionTier1 etc, only after the form has been handled and only if the form has been submitted, otherwise it will be null:
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);
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With