I have a form with a table inside which shows the results of a database query. That table has a radio control and two buttons: one for edit, another for delete. In order for me to modify a row, I have to select the radio of the corresponding row and then press either "delete" or "edit" button. What I want to do is to remove that radio button and make the buttons take me straight to editing the corresponding row. When I remove the radio button (it's kind of obvious) every buttom from every row only take me to edit/delete the first result.
This is my form:
<form method="POST" id="form2" action="{{ url_for('edit_or_delete') }}">
<table id="tableSelect">
<tr>
<th></th>
<th>Manejar</th>
<th>Cantidad</th>
<th>Concepto</th>
<th>Fecha</th>
<th>Updated</th>
</tr>
<!-- loop for results -->
{% for s in mov %}
<tr><label for="id"></label>
<td ><input type="radio" name="id" value="{{ s.id }}" required></td>
<td>
<button type="submit" name="choice" value="delete" >Borrar</button>
<button type="submit" name="choice" value="edit" >Editar</button>
</td>
<td>${{ s.cantidad }}</td>
<td>{{ s.concepto }}</td>
<td>{{ s.fecha }}</td>
<td>{{ s.udpated }}</td></label>
</tr>
{% endfor %}
</table>
<!-- end form-group -->
</form>
This is my route:
@app.route('/edit_or_delete', methods=['POST'])
def edit_or_delete():
id = request.form['id']
choice = request.form['choice']
movs = Movs.query.filter(Movs.id == id).first()
# two forms in this template
form1 = AddRecord()
form2 = DeleteForm()
return render_template('edit_or_delete.html', movs=movs, form1=form1, form2=form2, choice=choice)
CodePudding user response:
Let's say you have a route that displays the results of the database query in a table:
@app.route('/some_route')
def some_route():
result = Some_Database_Class.query.all()
return render_template('list.html', result=result)
list.html would look something like this:
<table >
<tr>
<th>Some Data</th>
<th>Edit</th>
<th>Delete</th>
</tr>
{% for row in result %}
<tr>
<td>{{ row.some_data }}</td>
<td>
<a href="{{ url_for('edit_row', row_id=row.id }}">
This links to an edit route with the row id included in the URL
</a>
</td>
<td>
<button data-row-id="{{ row.id }}">
<span aria-hidden="true"></span>
</button>
</td>
</tr>
{% endfor %}
</table>
When making an edit we redirect the user to a route which takes a parameter <row_id>, loads the corresponding row and displays all the necessary information in a form.
@app.route('/edit_row/<row_id>'), methods=['GET', 'POST'])
def edit_row(row_id):
row = Some_Database_Class.query.filter_by(id=row_id).first()
form = EditRowForm()
if request.method == 'GET':
form.some_form_field.data = row.some_data
if form.validate_on_submit():
row.some_data = form.some_form_field.data
db.session.commit()
return render_template('edit_row.html', form=form)
When deleting a row you could do the same, but then you would have a GET request deleting something on the server, which shouldn't happen. You can easily use jQuery to send a DELETE request:
$(document).ready(function () {
//Delete a row on button click
$('.delete_row').click(function () {
var row_id = $(this).attr('data-row-id')
var ajaxReq = $.ajax({
url: '/delete_row/' row_id,
type: 'DELETE',
statusCode: {
200: function () {
window.location.reload()
}
}
});
});
});
When the user now clicks the delete button a request now gets sent to a route that would look like this:
@app.route('/delete_row/<row_id>'), methods=['DELETE'])
def delete_row(row_id):
row = Some_Database_Class.query.filter_by(id=row_id).first()
if row is not None:
db.session.delete(row)
db.session.commit()
return Response(status=200)
return Response(status=404)
If the row is found it gets deleted and the window gets reloaded for the user.
I don't know if this is the standard or best way to do it, but it works for me.
