I have the following html code with a form
<form id="msg-form-nota">
<input type="hidden" name="id_nota" id="id_nota" value="${project.id}">
<label for="textfield">Calificación obtenida:</label>
<input type="text" name="nota" id="nota" value="${project.nota}" placeholder="Introducir calificación"><br>
<input type="submit" name="submit" id="submit" value="Añadir/modificar calificación">
</form>
and then I use the following javascript/ajax code to manage the form
$('#msg-form-nota').submit(e => {
e.preventDefault();
const postData = {
nota: $('#nota').val(),
id: $('#id_nota').val()
};
const url ='accion.php';
$.post(url, postData, (response) => {
toastr.success('añadidas!', 'Actualización ', {"hideDuration": 1500});
});
});
The problem that I detect and I don't know how to solve is that, for example, when using a while, 5 forms are created with the same name id, if I use the first form that loads me it works without problem, but if I use the rest, the form does not It works if not that all the content of the form goes to the url as if the method were a get, what can I do? Thank you
CodePudding user response:
The issue, as your question implies, is because you're repeating the same id
attribute multiple times as the HTML is generated in a loop.
The best way to fix this is to use common class
attributes on the elements instead. Then you can target the specific instance which from the target
property of the event which is raised and passed as an argument to the event handler function. You can also use DOM traversal methods to find the related elements and retrieve their values.
Also note that I wrapped the input
within the label
element. This removes the need for the for
and id
attributes on those elements, but retains the same functionality.
$('.msg-form-nota').on('submit', e => {
e.preventDefault();
let $form = $(e.target);
const postData = {
nota: $form.find('.nota').val(),
id: $form.find('.id_nota').val()
};
console.log(postData);
/* make your AJAX request here... */
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<form >
<input type="hidden" name="id_nota" value="ID_001">
<label>
Calificación obtenida:
<input type="text" name="nota" value="Nota_001" placeholder="Introducir calificación">
</label>
<input type="submit" name="submit" value="Añadir/modificar calificación">
</form>
<form >
<input type="hidden" name="id_nota" value="ID_002">
<label>
Calificación obtenida:
<input type="text" name="nota" value="Nota_002" placeholder="Introducir calificación">
</label>
<input type="submit" name="submit" value="Añadir/modificar calificación">
</form>
<form >
<input type="hidden" name="id_nota" value="ID_003">
<label>
Calificación obtenida:
<input type="text" name="nota" value="Nota_003" placeholder="Introducir calificación">
</label>
<input type="submit" name="submit" value="Añadir/modificar calificación">
</form>
CodePudding user response:
If you wanted to completely remove the ID attributes from your forms/elements you can quite easily simplify the entire code by using a FormData
object with a reference to the form
supplied as the single argument. The FormData
object would collate the various input elements for use in the ajax request - thus negating the need to even try to identify the individual input elements explicitly.
document.querySelectorAll('[type="submit"]').forEach(input => input.addEventListener('click',e=>{
e.preventDefault();
/*
The `submit` button raised the event so the `event.target` refers to that button.
From the button we know the `form` is the parentNode - but you can use `closest`
to find the parent form.
*/
let fd = new FormData( e.target.parentNode );
fetch( 'accion.php', { method:'post', body:fd })
.then(r=>r.text())
.then(data=>{
console.log(data);
// call your success function.
toastr.success('añadidas!', 'Actualización ', {
"hideDuration": 1500
});
});
}))
<form data-id='msg-form-nota'>
<input type='hidden' name='id_nota' value='123' />
<label>
Calificación obtenida:
<input type='text' name='nota' class='form-control form-control-sm' value='Geronimo' placeholder='Introducir calificación' />
</label>
<input type='submit' class='btn btn-success btn-sm' value='Añadir/modificar calificación' />
</form>
<form data-id='msg-form-nota'>
<input type='hidden' name='id_nota' value='456' />
<label>
Calificación obtenida:
<input type='text' name='nota' class='form-control form-control-sm' value='Fred Flintsone' placeholder='Introducir calificación' />
</label>
<input type='submit' class='btn btn-success btn-sm' value='Añadir/modificar calificación' />
</form>
<form data-id='msg-form-nota'>
<input type='hidden' name='id_nota' value='789' />
<label>
Calificación obtenida:
<input type='text' name='nota' class='form-control form-control-sm' value='Spitfire' placeholder='Introducir calificación' />
</label>
<input type='submit' class='btn btn-success btn-sm' value='Añadir/modificar calificación' />
</form>
In the PHP script accion.php
there will be 2 POST parameters sent by the fetch
request. These two parameters have the same names as the form input elements. For instance:-
<?php
#accion.php
if( $_SERVER['REQUEST_METHOD']=='POST' && isset(
$_POST['id_nota'],
$_POST['nota']
)){
// ... etc do whatever
}
?>