Dynamic Generation for Submitted Forms
您希望针对用户提交的数据自定义表单。例如,假设您有一个体育聚会的注册表。一些事件将允许您指定您在该领域的首选位置。例如,这将是一个选择字段。但是,可能的选择将取决于每项运动。您需要正确的选项才能通过验证。
以下示例创建一个包含两个字段的表单,country 和 state。 state 字段取决于 country 字段,如果未选择任何国家/地区,则将保持禁用状态。
表单类型
namespace AppBundle\Form;
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\Form\FormInterface;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormEvents;
use Symfony\Component\Form\FormEvent;
use Doctrine\ORM\EntityManagerInterface;
use AppBundle\Entity\Country;
use AppBundle\Entity\State;
class CountryStateType extends AbstractType
{
private $entityManager;
private $countryRepository;
private $stateRepository;
public function __construct(EntityManagerInterface $entityManager)
{
$this->entityManager = $entityManager;
$this->countryRepository = $entityManager->getRepository(Country::class);
$this->stateRepository = $entityManager->getRepository(State::class);
}
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->add('country', EntityType::class, [
'class' => Country::class,
'placeholder' => 'Select',
'choice_label' => 'name',
'label' => 'Country'
]);
$formModifier = function (FormInterface $form, $countryId = null) {
$country = null === $countryId ? null : $this->countryRepository->find($countryId);
$states = null === $country ? [] : $this->stateRepository->findAll();
$disabled = null === $country ? true : false;
$form->add('state', EntityType::class, [
'class' => State::class,
'placeholder' => 'Select',
'choice_label' => 'name',
'label' => 'State',
'choices' => $states,
'disabled' => $disabled
]);
};
$builder->addEventListener(
FormEvents::PRE_SET_DATA,
function (FormEvent $event) use ($formModifier) {
$data = $event->getData();
$data = null === $data ? [] : $data;
$countryId = array_key_exists('country', $data) ? $data['country'] : null;
$formModifier($event->getForm(), $countryId);
}
);
$builder->get('country')
->addEventListener(FormEvents::POST_SUBMIT,
function (FormEvent $event) use ($formModifier) {
$country = $event->getForm()->getData();
$countryId = null === $country ? null : $country->getId();
$formModifier($event->getForm()->getParent() , $countryId);
}
);
}
}
模板
{{ form_start(form) }}
{{ form_widget(form.country) }}
{{ form_widget(form.state) }}
<button type="submit">Submit</button>
{{ form_end(form) }}
<script src="https://code.jquery.com/jquery-3.5.1.min.js"></script>
<script>
var $country = $('#{{ form.country.vars.id }}');
$country.change(function () {
var $form = $(this).closest('form');
var data = {};
data[$country.attr('name')] = $country.val();
$.ajax({
url: $form.attr('action'),
type: $form.attr('method'),
data: data,
success: function (html) {
$('#{{ form.state.vars.id }}').replaceWith(
$(html).find('#{{ form.state.vars.id }}')
);
}
});
});
</script>