У меня есть форма Symfony, отправленная по запросу Ajax.Эта форма содержит 2 поля: дата (указатель даты) и количество дней (выбор типа).Я не могу инициализировать количество дней, в течение которых строится форма, поскольку она зависит от выбранной даты.Используя Javascript, я обновляю опции в select-picker.Это работает очень хорошо.Обычно параметр выглядит следующим образом: <option value="1">1 jours<\option>
.
Теперь, когда форма отправлена, мне нужно добавить эти поля в choiceType.
Я использовал метод isXmlHttpRequest, потому что форма отправляется с Ajax-запросом , ожидающим ответа. Если форма действительна, мне нужно сообщить Ajax-вызов (я не хочу отображать другой шаблон).В Контроллере я делаю следующее:
/**
* @param Request $request
* @return Response
* @Route("/ajout_favoris", name="ajoutFavoris")
*/
public function ajoutFavoris(Request $request){
$form = $this->creerFormulaire()->getForm();
$form->handleRequest($request);
if ($request->isXmlHttpRequest()){
if ($form->isValid() ) {
// actions ...
$reponse = ['statut' => 'success'];
}else {
$reponse = ['statut' => 'form-invalid'];
}
$reponse = new Response(json_encode($reponse));
$reponse->headers->set('Content-Type', 'application/json');
return $reponse;
}
return $this->render('@Carte/Reservation/reservation.html.twig', array(
"form" => $form->createView() ));
Вот как я строю форму:
public function creerFormulaire(){
$formulaire = $this->createFormBuilder()
->addEventListener(FormEvents::PRE_SUBMIT, function (FormEvent $event) {
$form = $event->getForm();
$data = $event->getData();
$optionList = $this->getValidChoicesForNbJours($data["nbJours"]);
$form->add('nbJours', 'choice', array(
'attr' => [ 'placeholder' => 'nombre de jours',
'class' => 'selectpicker',
],
'choices' => $optionsList,
));
})
->add('dateDebut', DateTimeType::class, [
'widget' => 'single_text',
'format' => 'dd/MM/yyyy',
'input' => 'datetime',
'label' => 'Date début',
'required' => true,
'attr' => ['class' => 'datepicker input-date',
'type' => 'text',
'placeholder' => 'JJ/MM/AAAA',
'readonly' => true,
'required' => true,]
])
->add('nbJours', 'choice', [
'label' => 'Nombre de jours',
'choices' => [],
'attr' => [ 'placeholder' => 'nombre de jours',
'class' => 'selectpicker',
'title' => 'Nombre de jours',
'readonly' => true,
'required' => false,]
])
->add('ajoutFavoris', SubmitType::class, [
'label' => 'Ajouter aux favoris',
'attr' => [ 'class' => 'btn btn-primary reserver' ]
]);
return $formulaire;
}
И вот как я заполняю опции:
public function getValidChoicesForNbJours($range){
$liste = [];
for ($i = 1; $i <= $range; $i++){
$liste[$i.' jours'] = strval($i);
}
return $liste;
}
и вот вызов ajax:
path_to_add_fav = ...
idPlan = ...
$("#form_ajoutFavoris").click(function (e) {
let dateDebut = document.getElementById('form_dateDebut').value;
let nbJours = document.getElementById('form_nbJours').value;
if (dateDebut && nombreJours){
let data = {
poste_id: idPoste,
plan_id: idPlan,
nbJours: nbJours ,
};
$.ajax({
url: path_to_add_fav,
type: "post",
data: JSON.stringify(data),
dataType: "json",
success: function (data) {
console.log(data.statut);
if (data.statut === "success") {
window.parent.$.fancybox.close();
}
}
});
}
});
В консоли Chrome нет ошибки.При первой отправке всегда отображается form-invalid
, на следующем иногда отображается form-invalid
, иногда ничего нет ...
Я прочитал много "похожих постов", но не смог достичьмой.Этот пост относится к этому one , но вопрос теперь другой.
Спасибо за чтение!
РЕДАКТИРОВАТЬ: Добавить HTML
{{ form_start(form) }}
<div class="card-deck maxheight">
{% include '@Carte/Carte/poste_card.html.twig' with {'poste':poste, 'connected':connected, 'showbtn':false } %}
<div class="card card-form" id="card-reserv">
<div class="card-body">
{{ form_errors(form) }}
<div id="warning-pecheurs" class="alert alert-warning padding alert-dismissible"
role="alert">
<button type="button" class="close float-right" data-dismiss="alert" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
warning message
</div>
<table id="table" class="largeur">
<colgroup>
<col span="1" class="col1">
<col span="1" class="col2">
</colgroup>
<tbody>
<tr>
<td>
<div class="input-group">
{{ form_label(form.dateDebut) }}
</div>
</td>
<td class="date">
{{ form_widget(form.dateDebut) }}
</td>
</tr>
<tr>
<td colspan="2">
{{ form_errors(form.dateDebut) }}
</td>
</tr>
<tr>
<td>
<div class="input-group">
{{ form_label(form.nbJours) }}
</div>
</td>
<td>
{{ form_widget(form.nbJours) }}
</td>
</tr>
<tr>
<td colspan="2">
{{ form_errors(form.nbJours) }}
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
<div class="row margin0">
<button type="button" class="btn btn-secondary" data-dismiss="modal"
onclick="window.parent.$.fancybox.close()" value="CloseFB">
Annuler
</button>
{{ form_widget(form.ajoutFavoris) }}
</div>
{{ form_end(form) }}
А вот как я заполняю селектор выбора в JS:
let new_options = "";
for (i = 0; i < nbOptions; i++, j++)
new_options += "<option value=" + j + ">" + j + " jours</option>";
$("#form_nbJours").html(new_options).selectpicker('refresh');
РЕДАКТИРОВАТЬ: Решение Виноват вызов метода Ajax! С этим вызовом он работает отлично!
$('form').submit(function (e) {
console.log("ok");
e.preventDefault();
let formSerialize = $(this).serialize();
$.post(path_to_add_fav, formSerialize, function(response) {
console.log(response.statut);
if (response.statut === "success") {
console.log("Réponse correcte !");
window.parent.$.fancybox.close();
}
}, 'JSON');
}