Reputation: 550
i am setting up a flask application (just started on flask this week, i am also inexperienced in html/javascript so don't shoot at me) and want to be able to delete data from database, but want to be able to have a modal showing up asking for the confirmation (because i think it looks nice and neat).
I have been trying for the past two days to make that modal confirmation work and haven't been able to achieve that. I have looked into similar question posted here already and wasn't able to make it work. So my attempt is a combination of what i found in those posts so far.
My table which is created using jinja(i think) looks like below and when a user clicks on the delete button, i want to show the confirmations modal and to be able to pass to the modal at least the "issuer.Id" value.
Would you be able to shed some light on what i do wrong or any advice how to approach it or any other idea to resolve this?
My code is here:
{% extends 'layout.html' %}
{% block body %}
<h2>Issuer Mappings</h2>
<a class="btn btn-success" href="add-issuer-mapping">Add mapping</a>
<hr>
<input type="text" class="form-control" id="allocationCodeInput" onkeyup="myFunction()" placeholder="Search for allocation codes.." title="Type in a allocation code">
<hr>
<table class="table table-striped table-sm ", id="IssuerMappingTable">
<tr>
<th>Allocation Code</th>
<th>Issuer</th>
<th>Backing</th>
<th>Country</th>
<th>Region</th>
<th>Sector</th>
<th width="150">Asset Class (Adj)</th>
<th>PM (Adj)</th>
<th>PM Initials</th>
<th>Strategy (Adj)</th>
<th>OffPiste</th>
<th>Liquidity</th>
<th></th>
<th></th>
</tr>
{% for issuer in issuer_mappings %}
<tr>
<td><a href="issuer-mappings/{{issuer.Id}}">{{issuer.AllocationCode}}</a></td>
<td>{{ issuer.Issuer }}</td>
<td>{{ issuer.Backing }}</td>
<td>{{ issuer.Country }}</td>
<td>{{ issuer.Region }}</td>
<td>{{ issuer.Sector }}</td>
<td>{{ issuer.AssetClass_ADJ }}</td>
<td>{{ issuer.PM_ADJ }}</td>
<td>{{ issuer.PM_Initials }}</td>
<td>{{ issuer.Strategy_ADJ }}</td>
<td>{{ issuer.OffPiste }}</td>
<td>{{ issuer.Liquidity }}</td>
<td><a href="issuer-mappings/edit-issuer-mapping/{{ issuer.Id }}" class="btn btn-warning btn-sm pull-right">Edit</a></td>
<td>
<a class="btn btn-danger btn-sm pull-right" data-toggle="modal" data-target="#IssuerMappingDeleteModal" data-id="{{ issuer.Id }}">Delete</a>
</td>
</tr>
{% endfor %}
</table>
<div id="IssuerMappingDeleteModal" class="modal fade" role="dialog">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h3 class="modal-title">Delete Issuer Mapping?</h3>
<button type="button" class="close" data-dismiss="modal">×</button>
</div>
<div class="modal-body" id="issMapId">
<!-- display some how the id here-->
<p>The selected issuer mapping is about to be deleted.<br>Do you want to proceed?</p>
</div>
<div class="modal-footer">
<form method="POST"> <!-- to add the delete action later -->
<input type="hidden" name="_method" value="DELETE">
<input type="submit" value="Yes" class="btn btn-danger" >
</form>
<button type="button" class="btn btn-default" data-dismiss="modal">No</button>
</div>
</div>
</div>
</div>
<script type="text/javascript">
$(document).on("click", ".btn-danger", function () {
var issuerMappingId = $(this).data('id');
$(this).find('#issMapId').html($('<b> Issuer Mapping id: ' + issuerMappingId + '</b>'))
});
</script>
{% endblock %}
Upvotes: 0
Views: 2334
Reputation: 550
ok, so i have tried a few more things (also went through a javascript tutorial, wished i had done that earlier). An answer by @therecluse26 (much appreciated for the thorough answer) suggested to use ajax (as opposed to a form) to send my delete request. However, as i am very new to this and I am not confident user yet I kept my solution with a form.
so i have updated my js function as below:
<script type="text/javascript">
function deleteButtonClicked(issMapId, issMapName) {
document.getElementById("issMapId").innerHTML = "Allocation Code " + issMapName + " (id:" + issMapId + ") will be deleted. <br>Do you want to proceed?";
var element = document.getElementById("deleteForm");
element.setAttribute("action", "issuer-mappings/delete-issuer-mapping/" + issMapId)
}
</script>
and i have updated my modal code as below and it currently works.
<div class="modal-body">
<!-- display some how the id here-->
<p id="issMapId"></p>
</div>
<div class="modal-footer">
<form id="deleteForm" method="POST"> <!-- to add the delete action later -->
<input type="hidden" name="_method" value="DELETE">
<input type="submit" value="Yes" class="btn btn-danger" >
</form>
<button type="button" class="btn btn-default" data-dismiss="modal">No</button>
</div>
and this is the button that shows the modal
<td>
<a class="btn btn-danger btn-sm pull-right"
onclick="deleteButtonClicked({{ issuer.Id}},'{{ issuer.AllocationCode }}')"
data-toggle="modal" data-target="#IssuerMappingDeleteModal">Delete</a>
</td>
Upvotes: 0
Reputation: 88
$(this).find('#issMapId').html($('<b> Issuer Mapping id: ' + issuerMappingId + '</b>'))
Your context of this
is still the button... that's why it can't find #issMapId
Try $(document).find('#issMapId').html($('<b> Issuer Mapping id: ' + issuerMappingId + '</b>'))
Upvotes: 1
Reputation: 89
First of all, you'll want to submit your data using an Ajax request rather than a form submission on the page, which will cause the page to refresh/redirect. Ajax will allow you to send a request to the server without having to refresh the page every time. jQuery.ajax() documentation
There are a few ways you could tackle this problem. I'd say that probably the easiest and best way would be to ditch the modal altogether define a wrapper function that sends the DELETE
request to the remote server and replaces the modal functionality with a confirm()
function (this returns true when confirmed).
For example:
function deleteIssuer(id){
if (confirm("The selected issuer mapping is about to be deleted. Do you want to proceed?")){
/*** Ajax request to server to delete goes here ***/
} else {
return;
}
}
If you're absolutely sure however that you want to use a Bootstrap modal to accomplish this, you could define two separate functions to do something like:
function deleteIssuer(id){
// This populates a hidden input field (you will need to create somewhere in the page) with the issuer ID
$("#hiddenIdField").val(id);
// Shows your modal
$("#IssuerMappingDeleteModal").modal("show");
}
function sendDeleteRequest(){
var id = $("#hiddenIdField").val(); // Pass this id to Ajax function
/*** Ajax request to server to delete goes here ***/
}
Finally, you'll also need to replace the <input type="submit" value="Yes" class="btn btn-danger" >
button on your modal with something like <button type="button" onClick="sendDeleteRequest()" class="btn btn-danger" data-dismiss="modal">Yes</button>
In both cases, you'll be calling the deleteIssuer(id)
function from the Delete button you've created, so replace your <a>
tag with: <button class="btn btn-danger btn-sm pull-right" onClick="deleteIssuer({{ issuer.Id }})">Delete</button>
This should get you pretty close to what you need, you'll just need to define the $.ajax()
request and server-side delete handler and you should be all set. It'd also be good to add some csrf protection if you can, to avoid certain types of exploits.
Upvotes: 1