Bootstrap modal to confirm deletion - django

When I loop over my images I have an icon that you can click to delete the image. Instead I'd like to have a modal pop up to confirm the deletion. The only problem is I don't want to repeate the code for the modal for each image. I need a way to pass the image id to the modal.
I was thinking I could pass the id in through an onClick but I'm not sure that will work with the Bootstrap modal.
Here's how I'm currently deleting:
{% for image in images %}
<img src="{{image.image.url}}">
<form method="POST" action="{% url 'products:delete_image>
{% csrf_token %}
<button type="submit" rel="tooltip" title="Remove">
<i class="material-icons">close</i>
</button>
</form>
{% endfor %}
Here's the modal code I'd like to integrate
<!-- Button trigger modal -->
<button type="button" class="btn btn-primary" data-toggle="modal" data-target="#exampleModalCenter">
Launch demo modal
</button>
<!-- Modal -->
<div class="modal fade" id="exampleModalCenter" tabindex="-1" role="dialog" aria-labelledby="exampleModalCenterTitle" aria-hidden="true">
<div class="modal-dialog modal-dialog-centered" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="exampleModalLongTitle">Modal title</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
...
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
<button type="button" class="btn btn-primary">Save changes</button>
</div>
</div>
</div>
</div>

Assign a click handler to the button inside each form and give each form a unique id. For example, give all the form buttons a class like confirm-delete. Assign a click handler (this is jQuery but you could also use vanilla JS)...
$('.confirm-delete').on('click', function(e) {
// prevent form submit
e.preventDefault();
// get the current image/form id
var id = $(this).attr("id")
// assign the current id to the modal and show the modal
$('#myModal').data('id', id).modal('show');
})
Then inside the modal, have a button that actually performs the delete using the id that is passed through data...
$('#btnDelete').click(function() {
// handle deletion here
var id = $('#myModal').data('id');
// submit the form
$('form'+id).submit();
// if needed, remove deleted image
// and form from DOM
$('#img'+id).remove();
$('#form'+id).remove();
// hide modal
$('#myModal').modal('hide');
})
Demo

Related

Laravel Livewire hiding bootstrap modal with click event

I am building a livewire-based application which I came to a point where I need wire:click event to fire a function in the livewire component class as well as open a Bootstrap Modal.
Without the wire:click event, the Bootstrap Modal opens.
Without the Bootstrap Modal id, the wire:click event works just fine.
With both the two, the Modal opens but hides (not dismissed) forever, until I reload the page before I could do anything.
By default when you create livewire using php artisan make:livewire --name, the view part comes with <div> //comment </div> tag. So, whenever the place the Modal inside the div tag the above problem occurs.
However, if the place the Modal in outside the div tag it works fine BUT NOT RECOGNIZING THE LIVEWIRE VARIABLES
I want to know;
If the livewire doesn't support Bootstrap Modal or having conflicts with the Modal scripts.
If one event can not be fired twice at the same time (wire:click and default click event).
Why except tags are enclosed inside the <div> </div> before livewire recognizes it.
<a href="#" wire:click="edit({{ $file->id }})" class="mr-1 edit" data-toggle="modal" data-target="#editFileModal">
<i class="align-middle fa fa-edit"></i>
</a>
By adding wire:ignore.self to the root element of my modal fixed it for me.
Modal trigger button.
<button wire:click="updateModal({{ $item->id }})" type="button" class="btn btn-sm btn-label-brand btn-bold" data-toggle="modal" data-target="#updateModal"> Update</button>
Example modal dialog.
<div wire:ignore.self class="modal fade" id="kt_modal_1" tabindex="-1" role="dialog" aria-labelledby="exampleModalLabel" aria-hidden="true">
<div class="modal-dialog modal-lg" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="exampleModalLabel">New message</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
</button>
</div>
<div class="modal-body">
<form>
<div class="form-group">
<label for="recipient" class="form-control-label">Recipient:</label>
<input type="text" class="form-control" id="recipient" wire:model="recipient">
</div>
<div class="form-group">
<label for="message" class="form-control-label">Message:</label>
<textarea class="form-control" id="message" wire:model="message"></textarea>
</div>
</form>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
<button type="button" class="btn btn-primary">Send message</button>
</div>
</div>
</div>
</div>
You could use Alpine.js (that comes with Livewire) to fire both the wire:click and the toggle of the modal. By doing this you could even listen for the wire:click call to complete before you open the modal, if that suits you better.
<a href="#" x-on:click="$wire.edit({{ $file->id }}); $('#editFileModal').modal('show');" class="mr-1 edit">
<i class="align-middle fa fa-edit"></i>
</a>
I was having the exact same issue, here is my solution:
Instead of using the attribute data-target="#myModal" to show myModal when the button is clicked, I just use wire:click function to do that. ie:
<button class="btn btn-sm btn-danger" wire:click.prevent="myFunction({{$some_id}})">...</button>
In myFunction, do whatever you want, after that, add:
$this->dispatchBrowserEvent('openModal', ['someParameter' => 'some value']);
In the view file, add:
<script>
window.addEventListener('openModal', event => {
$('#myModl').modal('show');
//alert('parameter: ' + event.detail.someParameter);
})
</script>
See https://laravel-livewire.com/docs/2.x/events#browser for more info

connecting button to modal with bootstrap

I need some help connecting a button which pops up a modal to submit form.
this is my html before the modal (works fine and another page is rendered after button is clicked)
<div class="container my-container">
<h3>
Let's get started
</h3>
<div class="row my-row">
<h4>1. CSV file</h4>
</div>
<div class="row my-row">
<h4>2. There should be only two columns</h4>
</div>
<div class="row my-row">
<form method="post" enctype="multipart/form-data">
{%csrf_token%}
<input type="file" name="document"><br>
<button type="submit"> Submit</button>
</form>
</div>
</div>
I have added the modal but I now have a couple of issues
<div class="container my-container">
<div class="row my-row">
<h3>
Let's get started
</h3>
</div>
<div class="modal fade" id="demo123">
<div class="modal-dialog">
<div class="modal-content">
<button type="button" class="close" data-dismiss="modal">
<span>
×
</span>
</button>
<div class="modal-header">
<h2 class="modal-title">
Confirm upload
</h2>
</div>
<div class="modal-body">
<p>this is the file name</p>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal">
Confirm
</button>
</div>
</div>
</div>
</div>
<div class="row my-row">
<h4>1. CSV file</h4>
</div>
<div class="row my-row">
<h4>2. There should be only two columns titled</h4>
</div>
<div class="row my-row">
<form method="post" enctype="multipart/form-data">
{%csrf_token%}
<input type="file" name="document"><br>
<button class="btn btn-primary" data-toggle="modal" data-target="#demo123">
Submit
</button>
</form>
</div>
</div>
First issue I have is the "submit" button automatically makes the upload(renders to another page). How can I make so only if "confirm" button is the one which actually submits the form (if "x" then pop-up closes). Also how can I display the filename in the pop-up?
I use django with bootstrap 4
You have to use Javascript and since Bootstrap uses jQuery, you'll have to create that logic using Javascript and jQuery.
Handle the dialog confirm button click and only then trigger a form submit event.
Handle modal show event show.bs.modal and set the dialog filename element if there is a file selected and enable the confirm button; if there is no file selected, message the user about it using the same filename element and disable the confirm button so the user can't click it.
You can run the code snippet and test the whole functionality. On form submission we cancel the event and print a message in the console just for demonstration.
Please read inline comments
jQuery(function($) {
// Handle form submit.
// This won't be necessary unless you want some custom behavior.
// Here we just cancel the form submission and just display a message for demonstration
$('#uploadForm').on('submit', function(e) {
console.log('The form is submitting; preventing event for demonstration');
e.preventDefault();
});
// Handle dialog confirm button click.
$('#confirmUpload').on('click', function(e) {
// Submit the form and hide the dialog when confirm clicked
$('#demoModal123').modal('hide');
$('#uploadForm').submit();
});
// When the dialog is about to show, check if the user has selected a file.
// If they have, update dialog filename element and enabled the confirm button,
// else message user that there is no file and disable the confirm button
$('#demoModal123').on('show.bs.modal', function() {
let files = document.getElementById('documentFile').files;
let fileSelected = files && files[0];
if (fileSelected) {
$('#demoModal123 .filename').text(fileSelected.name);
$('#confirmUpload').prop('disabled', false);
} else {
$('#demoModal123 .filename').text('No file selected');
$('#confirmUpload').prop('disabled', true);
}
});
// Update file input group control label on file selection
$('#documentFile').on('change', function() {
$('#documentFileName').text(this.files[0].name);
});
});
<script src="https://code.jquery.com/jquery-3.4.1.min.js"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/js/bootstrap.min.js" integrity="sha384-wfSDF2E50Y2D1uUdj0O3uMBJnjuUD4Ih7YwaYd1iqfktj0Uod8GCExl3Og8ifwB6" crossorigin="anonymous"></script>
<link href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-Vkoo8x4CGsO3+Hhxv8T/Q5PaXtkKtu6ug5TOeNV6gBiFeWPGFN9MuhOf23Q9Ifjh" crossorigin="anonymous">
<div class="container my-container">
<h3>Let's get started</h3>
<div class="row my-row">
<h4>1. CSV file</h4>
</div>
<div class="row my-row">
<h4>2. There should be only two columns</h4>
</div>
<div class="row my-row">
<form method="post" enctype="multipart/form-data" id="uploadForm">
<!-- {%csrf_token%} -->
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text" id="inputGroupFileAddon01">Upload</span>
</div>
<div class="custom-file">
<input type="file" class="custom-file-input" name="documentFile" id="documentFile">
<label class="custom-file-label" id="documentFileName" for="documentFile">Choose file</label>
</div>
</div>
<button class="btn btn-primary" type="button" data-toggle="modal" data-target="#demoModal123">Submit</button>
</form>
</div>
</div>
<!-- Modal -->
<div class="modal fade" id="demoModal123">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<h2 class="modal-title" id="exampleModalLabel">Confirm upload</h2>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
<p class="filename">this is the file name</p>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal">Cancel</button>
<button type="button" class="btn btn-primary" id="confirmUpload">Confirm</button>
</div>
</div>
</div>
</div>
To be able to act Confirm button as only submission, you'll have to add type="submit" in Confirm button and type="button" in Submit button. Like this:
<button type="button" class="btn btn-primary" data-toggle="modal" data-target="#demo123">
Submit
</button>
<button type="submit" class="btn btn-secondary" data-dismiss="modal">
Confirm
</button>

How to pass the values to bootstrap modal window and show the dynamic content

I need to pass the userName to the bootstrap modal window and show the passing name in modal window.
For example,
If i pass jawa the modal will show the content like 'This is jawa'
we need to add the attirbute data-id the in your button like as below,
<button type="button" data-toggle="modal" data-target="##myModal" data-id="jawa">Delete</button>
This JS function will be called before open boostrap modal window. And in that function we can able to get the data-id attribute value and then we can able to write a code based on getting value. See the below code,
<script type="text/javascript">
$('#myModal').on('show.bs.modal', function(event) {
var userName = $(event.relatedTarget).data('id');
$("#modalText").html("You are going to be deleted" + userName);
});
</script>
This is the modal window code,
<div id="myModal" class="modal fade" role="dialog" tabindex="-1">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h4 class="modal-title" id="cancelModal">Google Map</h4>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
<div id="modalText"></div>
</div>
<div class="modal-footer">
Open in new tab
</div>
</div>
</div>
</div>
Thanks,

Map Bootstrap modal button to Flask WTF submit

I have rendered a form in my Flask web app. For my specific use case, I would like to add a modal dialog window to "confirm" the user's choice. I can get the modal to display, but I can't figure out how to map the "confirm" button (in the modal) to the form action. The examples on the bootstrap docs do not include button mapping in the examples.
{% extends "base.html" %}
{% import "bootstrap/wtf.html" as wtf %}
<unrelated content>
...
</unrelated content>
...
<h4>Enter the email address of the employee receiving the unit</h4>
<div class="col-lg-3">
<div class="row">
<form class="form" id="emailForm" action="{{ url_for('main.transfer', serial=system.serial) }}" method="POST">
{{ mail_form.hidden_tag() }}
{{ mail_form.email }}
{{ mail_form.submit }}<!-- ###THIS IS WHAT I WANT THE MODAL CONFIRM TO TRIGGER -->
<!-- Button trigger modal -->
<button type="button" class="btn btn-primary" data-toggle="modal" data-target="#exampleModal">
Transfer
</button>
</form>
</div>
</div>
<!-- Modal -->
<div class="modal fade" id="exampleModal" tabindex="-1" role="dialog" aria-labelledby="exampleModalLabel" aria-hidden="true">
<div class="modal-dialog modal-dialog-centered" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="exampleModalLabel">Unit Transfer</h5>
<!--<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>-->
</div>
<div class="modal-body">
You are transferring a unit from {{ system.assignee.email }} to another user. Are you sure?
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal">Cancel</button>
<button type="button" class="btn btn-success success" type="submit" data-target="#emailForm.submit()">Confirm</button>
</div>
</div>
</div>
</div>
How do I tell the modal what I want to happen when the Submit button is clicked? All the documentation I can find talks about putting the entire form inside the modal, and that's not what I want.
Thanks in advance.
Make the following changes,
Change {{ mail_form.submit }} to {{ mail_form.submit(hidden='true', id='form-submit') }} to make the submit button hidden.
Change <button type="button" class="btn btn-success success" type="submit" data-target="#emailForm.submit()">Confirm</button> to <button type="button" class="btn btn-success success" id="modal-confirm">Confirm</button>
Add the below script after adding the jquery ,
<script>
$('#modal-confirm').click(function(){
// Perform the action after modal confirm button is clicked.
$('#form-submit').click(); // submitting the form
});
</script>
I hope this helps.

django bootstrap modal form closes on invalid form data

I am working on django + bootstrap modal where I am rendering ModelForm to the modal dialog.
The problem which I am facing is the modal form closes as soon as I click on submit button, it's showing errors on the modal form but it closes and the errors can be seen when the modal dialog is opened again.
I am not using any javascript or jquery, I am simply using html tag and handling post in the django view.
Please let me know what can be done to stop closing the dialog if the form is invalid.
modaldialog_modelform.html:
this file contain the code of the modal dialog with form which is rendered from view.
<div class="modal fade in" id="NewRecordModalForm" tabindex="-1" role="dialog" aria-labelledby="myModalLabel">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
<h3 class="modal-title" id="myModalLabel">Add New Transport</h3>
</div>
<div class="modal-body">
<form action="" method="post">{% csrf_token %}
{% if form.errors %}<p class="form_field_error">Please correct the following fields</p>{% endif %}
{{ form|crispy }}
</form>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
<input type="submit" alt="Add Transport" value="Add Transport" class="btn btn-primary" />
</div>
</div>
</div>
</div>
the above dialog is called from transport.html with below code:
<a class="btn btn-primary btn-xs" data-toggle="modal" data-target="#NewRecordModalForm" data-backdrop="static">
<i class="fa fa-plus"></i>
</a>
Seems page simply reloading and it's reloading in both cases ... you need ajax request (javaScript code) to your server by clicking on submit button, simplest way to do it using jQuery jQuery AJAX submit form