Reputation: 6379
I'm trying to add a stripe-data
attribute to a field generated with createBuilder
.
This is the code I'm using:
$form = $this->formFactory->createBuilder(FormType::class, [
'action' => $this->router->generate('storeSubscription', ['id' => $store->getId()]),
'method' => 'POST',
])
->add('plan', PremiumType::class, [
'data_class' => PremiumFeaturesEmbeddable::class,
'data' => $store->getPremium(),
]);
if (null === $store->getBranchOf()->getStripeCustomer() || null === $store->getBranchOf()->getStripeCustomer()->getDefaultSource()) {
$form->add('credit_card', CreditCardStripeTokenType::class)
->add('company_data', CompanyType::class, [
'data_class' => Company::class,
'data' => $store->getBranchOf()
]);
// Remove unused data
$form->get('company_data')
->remove('brand')
->remove('primaryEmail')
->remove('description')
->remove('phoneNumber')
->remove('faxNumber')
->remove('save');
// Set data-stripe
$form->get('company_data')
->get('legalName')->setAttributes(['attr' => ['data-stripe', 'name']]);
}
As you can see, the last line of this code gets the first the copmany_data
form type, then of this gets the field legalName
: on this I want to set the attribute stripe-data="name"
.
But this code doesn't work.
To add the attribute I have to use form_widget
in Twig:
<div class="form-group">
{{ form_errors(form.company_data.legalName) }}
{{ form_label(form.company_data.legalName) }}
{{ form_widget(form.company_data.legalName, {'attr': {'class': 'form-control input-sm', 'data-stripe': 'name'}}) }}
</div>
This way it works and attribute is correctly added. For sure, I may continue setting those attributes in Twig, but I'd like to add them in PHP but don't understand why it doesn't work. Is someone able to explain me how to solve the problem? Thank you!
What I tried
Test 1
// Set data-stripe
$form->get('company_data')
->get('legalName')->setAttributes(['data-stripe', 'name']);
Test 2
// Set data-stripe
$form->get('company_data')
->get('legalName')->setAttribute('data-stripe', 'name');
Test 3
// Set data-stripe
$form->get('company_data')
->get('legalName')->setAttributes(['attr' => ['data-stripe', 'name']]);
No one of those work. I don't know what to try more.
NOTE: I've opened an issue on GitHub too.
Upvotes: 5
Views: 11514
Reputation: 9585
If you need add/modify any option from any existing field, just do the following:
// to keep the current options
$options = $form->get('company_data')->get('legalName')->getConfig()->getOptions();
// add/change the options here
$options['attr']['data-stripe'] = 'name';
// re-define the field options
$form->get('company_data')->add('legalName', TextType::class, $options);
This doesn't alter the order of the fields, only change their options. Useful for conditional options on buildForm()
and listener/suscriber events.
However, if you change the approach this can be achieved in another way.
First, add a new default option 'add_stripe_name' => null
to CreditCardStripeTokenType
form type and pass this value to 'legalName'
field options definition:
// into CreditCardStripeTokenType::buildForm():
$legalNameOptions = array();
if ($options['add_stripe_name']) {
$legalNameOptions['attr']['data-stripe'] = $options['add_stripe_name'];
}
$builder->add('legalName', TextType::class, $legalNameOptions)
So the 'add_stripe_name'
option of CreditCardStripeTokenType
will be the flag to add the attribute to legalName
field:
$builder->add('credit_card', CreditCardStripeTokenType::class, [
'add_stripe_name' => 'name', // <---- \o/
]);
Upvotes: 7
Reputation: 1474
Based on the second @yceruto's approach I have a little inline optimisation which I can't say is definitely more readable but saves some lines and allows you to have continuous chain of the ->add() methods invoked from the $builder:
As he mentioned, first, add a new default option 'add_stripe_name' => null
to CreditCardStripeTokenType
form type and pass this value to 'legalName'
field options definition, using the array_merge_recursive()
function:
// into CreditCardStripeTokenType::buildForm():
$builder->add('legalName', TextType::class, array_merge_recursive([], // <---- here other options are stored if any, could be empty as well
$options['add_stripe_name'] !== null ? ['attr' => ['data-stripe' => $options['add_stripe_name']]] : []
);
So the 'add_stripe_name'
option of CreditCardStripeTokenType
will be the flag to add the attribute to legalName
field:
$builder->add('credit_card', CreditCardStripeTokenType::class, [
'add_stripe_name' => 'name', // <---- \o/
]);
Upvotes: 0
Reputation: 1457
When you create the embed form type company_data
you specify your attr
$builder->add('legalName', TextType::class, array(
'attr' => array('data-stripe' => 'name'),
));
Upvotes: 0