Hi i got my OrderType form.
Here is my code:
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('client', EntityType::class, array(
'data' => $options['client'],
'mapped' => false,
'attr' => ['class' => 'chosen-select','data-placeholder'=>'Wybierz klienta'],
'class' => UserDetails::class,
'choice_label' => function ($client) {
return ''.$firma.' '.$client->getJson()["client"]["imie"] .' '. $client->getJson()["client"]["nazwisko"].'';
},
'label' => 'Wybierz klienta'))
->add('save', SubmitType::class, [
'label' => 'Zapisz',
'attr' => ['class' => 'btn btn-primary pull-right']]) ;
$builder->addEventListener(
FormEvents::PRE_SET_DATA,
function (FormEvent $event) {
$form = $event->getForm();
$client =$form->get('client')->getData();
$shipping = null === $client ? array() : $client->getClientsShippings()->getJson()["clients_shippings"]["name"];
$form->add('shipping', EntityType::class, array(
'class' => ClientsShippings::class,
'placeholder' => '',
'choices' => $shipping));
}
);
}
There are no errors, but nothing happens either. I do not know how to achieve that, after selecting the EventListener client, PRE_SET_DATA loaded the shipping addresses assigned to the client in the ClientsShippings entity depending on the chosen client. I read this one a few times on symfony.com, but I can not completely understand these events.
Could someone help me run it, let me have an example of how it works. Maybe I think about it completely in a different way.
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('client', EntityType::class, array(
'data' => $options['client'],
'mapped' => false,
'attr' => ['class' => 'chosen-select','data-placeholder'=>'Wybierz klienta'],
'class' => UserDetails::class,
'choice_label' => function ($client) {
if(isset($client->getJson()["client"]["firma"]))
{
$firma = $client->getJson()["client"]["imie"];
}
else {
$firma = "";
}
return ''.$firma.' '.$client->getJson()["client"]["imie"] .' '. $client->getJson()["client"]["nazwisko"].'';
},
'label' => 'Wybierz klienta'
))
->add('product', EntityType::class, array(
'data' => $options['product'],
'mapped' => false,
'multiple' => true,
'class' => Products::class,
'attr' => ['class' => 'chosen-select','data-placeholder'=>'Wybierz produkt'],
'choice_label' => function ($product) {
return ''.$product->getJson()["products"]["name"] .' | Stan Magazynowy: '.$product->getJson()["products"]["stock"].'';
},
'label' => 'Wybierz produkty'
))
->add('save', SubmitType::class, [
'label' => 'Zapisz',
'attr' => ['class' => 'btn btn-primary pull-right']])
;
$builder->get('client')->addEventListener(
FormEvents::POST_SUBMIT,
function (FormEvent $event)
{
$form = $event->getForm();
$form->getParent()->add('shipping', EntityType::class, [
'class' => ClientsShippings::class,
'placeholder' => 'Wybierz adres dostawy',
'choices' => $form->getData()->getclientsShippings()
]);
}
);
}
A Symfony form has 2 main usages:
Form::submit()
is called)Form::setData()
and Form::Submit()
are called)Note: In both cases, Form::handleRequest()
is called before Form::submit()
to check if the request can be submitted or not.
We have 2 main category of form events:
PRE_SET_DATA
The PRE_SET_DATA
event, gets the value of data that you're starting with (Order
object in your case), and gets dispatched right before the form is populated with the data of entity object.
You may use this event to:
POST_SET_DATA
This event is fired right after the Form::setData()
method is called and can be use to:
Both POST_SET_DATA
and POST_SET_DATA
events are dispatched during pre-populating form data.
PRE_SUBMIT
This is fired when Form::submit()
or Form::handleRequest()
are called. This event can be used to:
SUBMIT
This event is dispatched after PRE_SUBMIT
and during Form::submit
(after the model and view data normalization, and before denormalization). You may use this event to:
POST_SUBMIT
this event is dispatched after the Form::submit()
. You may use this event to:
You should use 2 event listeners, one for PRE_SET_DATA
and one for POST_SUBMIT
:
OrderType
class OrderType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('client', EntityType::class, array(
'class' => UserDetails::class
))
->add('save', SubmitType::class)
;
$modifier = function (FormInterface $form, Client $client = null) {
$shippings = null === $client ? array() : $client->getClientsShippings();
$form->add('shipping', EntityType::class, array(
'class' => ClientsShippings::class,
'choices' => $shippings,
));
};
$builder->addEventListener(
FormEvents::PRE_SET_DATA,
function (FormEvent $event) use ($modifier) {
$orderData = $event->getData();
$modifier($event->getForm(), $orderData->getClient());
}
);
$builder->get('client')->addEventListener(
FormEvents::POST_SUBMIT,
function (FormEvent $event) use ($modifier) {
$client = $event->getForm()->getData();
$modifier($event->getForm()->getParent(), $client);
}
);
}
}
You should also make an AJAX call (some JavaScript) to update the shipping
list, according to the selected client.