Привет, я получил мою форму OrderType.
Вот мой код:
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));
}
);
}
Там нет ошибок, но ничего не происходит. Я не знаю, как этого добиться, после выбора клиента EventListener, PRE_SET_DATA загрузил адреса доставки, назначенные клиенту, в сущности ClientsShippings в зависимости от выбранного клиента.
Я прочитал это несколько раз на symfony.com, но я не могу полностью понять эти события.
Может ли кто-нибудь помочь мне запустить его, дайте мне пример того, как это работает. Может быть, я думаю об этом совершенно по-другому.
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()
]);
}
);
}
Форма Symfony имеет 2 основных использования:
Form::submit()
называется)Form::setData()
а также Form::Submit()
называются)Замечания: В обоих случаях, Form::handleRequest()
называется раньше Form::submit()
проверить, может ли быть подан запрос или нет.
У нас есть 2 основных категории форм мероприятий:
PRE_SET_DATA
PRE_SET_DATA
событие, получает значение данных, с которых вы начинаете (Order
объект в вашем случае), и отправляется непосредственно перед заполнением формы данными объекта-сущности.
Вы можете использовать это событие для:
POST_SET_DATA
Это событие происходит сразу после Form::setData()
Метод вызывается и может быть использован для:
И то и другое POST_SET_DATA
а также POST_SET_DATA
события отправляются во время предварительного заполнения данных формы.
PRE_SUBMIT
Это срабатывает, когда Form::submit()
или же Form::handleRequest()
называются. Это событие может быть использовано для:
ОТПРАВИТЬ
Это событие отправляется после PRE_SUBMIT
и во время Form::submit
(после нормализации данных модели и представления и перед денормализацией). Вы можете использовать это событие для:
POST_SUBMIT
это событие отправляется после Form::submit()
, Вы можете использовать это событие для:
Вы должны использовать 2 прослушивателя событий, один для PRE_SET_DATA
и один для 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);
}
);
}
}
Вы также должны сделать AJAX-вызов (немного JavaScript), чтобы обновить shipping
список, в соответствии с выбранным клиентом.
Других решений пока нет …