是否有一种方法可以使用ajax异步填充Form ChoiceType(下拉列表)?
基本上是我要做什么:
简短说明:简单的预订系统。
详细说明:
当用户通过在“ preferredDate”中使用日期选择器(或其他方法)选择日期时, ajax调用将检查所选日期是否有可用的时隙,并用时间(例如:10:00、10:30、11:00、11:30等)填充“ availableTimes” ChoiceType(下拉列表)。
可用时间不在数据库中。
我的表单:
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('preferredDate', DateType::class, [
'widget' => 'single_text',
'input' => 'datetime',
'format' => 'dd.MM.yyyy',
])
->add('availableTimes', ChoiceType::class, ['required' => false]);
}
我的JS:
$(".reservation-date").change(function () {
$.ajax({
type: "GET",
dataType: "json",
url: "{{URL}}",
data: {},
success: function (data) {
$(".reservation-times").empty();
$.each(data, function (key, value) {
//populate availabletimes dropdown
let disabled = (value.disabled === true ? "disabled" : '');
$(".reservation-times").append('<option ' + disabled + ' value=' + value.time + '>' + value.time + '</option>');
})
}
,
error: function (error) {
console.log(error);
}
});
})
当我发送选定的时间时,它会正常工作抛出错误“此值无效”
我做错了什么?
您会如何做?
编辑:没有验证集,但由于某些原因,它仍然想验证ChoiceType ... EDIT2:读取所有旧的SF2答案,但所有这些都是使用事件发送2次以上的表单。
EDIT3:_profiler中的错误:
答案 0 :(得分:0)
我终于做到了。添加了EventListener,其他所有内容基本相同。
我的表单:
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('preferredDate', DateType::class, [
'widget' => 'single_text',
'input' => 'datetime',
'format' => 'dd.MM.yyyy',
])
->add('availableTimes', ChoiceType::class)
->addEventListener(FormEvents::PRE_SUBMIT, function (FormEvent $event) {
// get the form from the event
$form = $event->getForm();
$formOptions = $form->getConfig()->getOptions();
//helpers
$availableTimeHandler = $formOptions['availableTimeHelper'];
// get the form data, that got submitted by the user with this request / event
$data = $event->getData();
//get date
$preferredDate = $data['preferredDate'];
// get the availableTimes element and its options
$fieldConfig = $form->get('availableTimes')->getConfig();
$fieldOptions = $fieldConfig->getOptions();
/**
* Getting available times logic is here,
* not showing because it's irrelevant to the issue.
*
* $times array example:
* [
* ['time' => '10:00', 'disabled' => false],
* ['time' => '11:00', 'disabled' => true],
* ['time' => '12:00', 'disabled' => true],
* ]
*/
$choices = [];
foreach ($times as $time) {
$choices[] = [$time['time'] => $time['time']];
}
//update choices
$form->add('availableTimes', ChoiceType::class,
array_replace(
$fieldOptions, [
'choices' => $choices
]
)
);
});
}
我的JS:
$(".reservation-date").change(function () {
$.ajax({
type: "GET",
dataType: "json",
url: "{{URL}}",
data: {},
success: function (data) {
$(".reservation-times").empty();
$.each(data, function (key, value) {
//populate availabletimes dropdown
let disabled = (value.disabled === true ? "disabled" : '');
$(".reservation-times").append('<option ' + disabled + ' value=' + value.time + '>' + value.time + '</option>');
})
}
,
error: function (error) {
console.log(error);
}
});
})
建议或技巧将不胜感激。
答案 1 :(得分:0)
在这种情况下,如果还有其他开发人员被卡住,则对我有用的解决方案在这里说明:https://symfony.com/doc/current/form/dynamic_form_modification.html#dynamic-generation-for-submitted-forms
我做了类似的事情,并使用了两个事件PRE_SET_DATA和POST_SUBMIT,我没有使用原则,所以我的代码可能有些奇怪:
//The form
$builder
->add('Pays', ChoiceType::class, [
'choices' => $this->paysRepository,
'attr' => ['class' => 'select2'],
'mapped' => false,//Pays don't exist in Panneau Entity
'constraints' => [
new NotBlank([
'message' => 'Veuillez choisir un pays'
])
]
])
->add('NumVille', ChoiceType::class, [
'attr' => ['class' => 'select2'],
'placeholder' => 'Villes',
'constraints' => [
new NotBlank([
'message' => 'Veuillez choisir une ville'
])
]
]);
现在事件保存程序:
//The function that fill the dropdown
$formModifier = function (FormInterface $form,String $pays) {
//$choices = null === $ville ? [] : $ville->getAvailablePositions();
if( !empty($pays) ){
$choices = $this->villeRepository->findCities($pays);//findcities is a function that bring data , cuz i'm not using doctrine
}else{
$choices = [];
}
$form->add('NumVille', ChoiceType::class, [
'choices' => $choices,
]);
};
//PRE SET DATA EVENT
$builder->get('Pays')->addEventListener(
FormEvents::PRE_SET_DATA,
function (FormEvent $event) use ($formModifier) {
//Get Form DATA
$data = $event->getData();
if ($data) {
$formModifier($event->getForm(), $data);
}
}
);
//POST SUBMIT EVENT
$builder->get('Pays')->addEventListener(
FormEvents::POST_SUBMIT,
function (FormEvent $event) use ($formModifier) {
$data = $event->getForm()->getData();
$formModifier($event->getForm()->getParent(), $data);
}
);
NumVille下拉列表由前面的ajax填充。