I have a problem and I'm not sure how to handle it. I'm inserting a form into a table row (tr) via AJAX, and then I want to submit it via AJAX as well. The first part works correctly, the request is sent and the form is created. The problem arises when I try to submit it - the request is sent, but the form data is not being included. As a result, the controller bypasses the "isSubmitted" and "isValid" checks and simply reloads the form without saving the information. What could be wrong? I'm working with Symfony 6.2.10
Here is the JS code:
$( document ).ready(function() {
var elementosClickable = document.getElementsByClassName('editable-row');
Array.prototype.forEach.call(elementosClickable, function(elemento) {
elemento.addEventListener('click', handleClick);
});
function handleClick(event) {
event.preventDefault();
var elemento = this;
var fila = elemento.closest('tr');
var idBasedatos = elemento.getAttribute('data-id-basedatos');
var url = '{{ path('admin_ataques_editar_ajax',{'id' : "ReplaceMeWithCorrectValue"}) }}';
url = url.replace('ReplaceMeWithCorrectValue', encodeURIComponent(idBasedatos));
$.ajax({
url: url,
type: 'GET',
success: function(response) {
$(fila).html(response);
},
error: function(xhr, status, error) {
console.error(error);
}
});
}
$("body").on("click", ".row-save", function(e){
e.preventDefault();
e.stopImmediatePropagation();
var elemento = this;
var fila = elemento.closest('tr');
var idBasedatos = elemento.getAttribute('data-id-basedatos');
var formulario = $('[name="ataque"]');
var data = new FormData(formulario[0]);
var promise = $.ajax({
type : formulario.attr( 'method' ),
url : formulario.attr( 'action' ),
enctype : 'multipart/form-data',
data : data,
processData: false,
contentType: false,
cache: false,
timeout: 600000,
beforeSend: function() {},
});
promise.done(function(data) {
if(data.error){
$.each(data.message, function (i, el) {
console.error(el);
});
}else{
fila.innerHTML = data;
}
});
})
Here is the controller function:
public function editarAjax($id){
$this->establecerParametros();
$em = $this->em;
$translator = $this->translator;
$request = $this->request;
$objecte = $em->getRepository($this->getPathEntidad().$this->getEntidad())->find($id);
$rutaEntity = $this->getPathEntidad().$this->getEntidad();
$formulario = $this->createForm($this->getFormType(), $objecte);
$formulario->handleRequest($request);
if($formulario->isSubmitted() && $formulario->isValid()){
try {
$em->getRepository($rutaEntity)->add($objecte, true);
$this->addFlash('success', $this->getMensajeOkActualizacion());
} catch ( \Exception $e ) {
$this->addFlash('danger', $this->getMensajeErrorActualizacion().' '.$e->getMessage());
}
return $this->render($this->getPlantillaCarpeta().'includes/tr_ajax.html.twig',
array(
$this->getNombreObjeto()=>$objecte
)
);
}
return $this->render($this->getPlantillaCRUD().'Ajax.html.twig',
array(
'pathEliminar'=>$this->getRutaEliminar(),
'pathLista' =>$this->getRutaLista(),
'pathEditar'=>$this->getRutaEditar(),
$this->getNombreObjeto()=>$objecte,
'nombreTablaSingular'=>$translator->trans($this->getNombreObjeto()),
'formulario'=>$formulario->createView(),
'accion' =>'editar'
)
);
}
Here is the template that creates the form:
{{ form_start(formulario, {'action': path('admin_ataques_editar_ajax', {'id': objeto.id}), 'method':'POST'}) }}
<td>{{ form_widget(formulario.nombre) }}</td>
<td>{{ form_widget(formulario.fuerza) }}</td>
<td>{{ form_widget(formulario.descripcion) }}</td>
<td>{{ form_widget(formulario.estadoAlterado) }}</td>
<td>{{ form_widget(formulario.caEstadoAlterado) }}</td>
<td><a class="btn btn-white btn-xs"><i class="fas fa-save row-save" data-id-basedatos="{{ objeto.id }}"></i></a></td>
{{ form_rest(formulario) }}
{{ form_end(formulario) }}
And here is the HTML generated by the first AJAX function:
<form name="ataque" method="post" action="/admin/ataques/editar/ajax/1">
<td>
<input type="text" id="ataque_nombre" name="ataque[nombre]" required="required" class="form-control" value="Test"/>
</td>
<td>
<input type="number" id="ataque_fuerza" name="ataque[fuerza]" required="required" class="form-control" value="1"/>
</td>
<td>
<textarea id="ataque_descripcion" name="ataque[descripcion]" required="required" class="form-control">test</textarea>
</td>
<td>
<select id="ataque_estadoAlterado" name="ataque[estadoAlterado]" class="form-control">
<option value="">...</option>
</select>
</td>
<td>
<input type="number" id="ataque_caEstadoAlterado" name="ataque[caEstadoAlterado]" class="form-control" value="2"/>
</td>
<td>
<a class="btn btn-white btn-xs">
<i class="fas fa-save row-save" data-id-basedatos="1"></i>
</a>
</td>
<button type="submit" class="row-save" style="display: block;">asdf</button>
<input type="hidden" id="ataque__token" name="ataque[_token]" value="fb195b94c53d6d7a01f33eea1cf9.2ykuGCwhDDsM46y_4EsymPVmwjIL7ZJ7v5wU1GmuYfw.7n5EcEkTW0hLueOJ0zhB8600lUtUv_0r2M9dulDlJZWSeH4hemtDdGq7mA"/>
</form>
What could be wrong?
I have tried changing the way of selecting the form in every way I can think of, but I can't get the form data to pass to the controller.