My situation is that I have several modals (4 to be exact) which should be accessible in every single view in my app. I will use just one as an example. Let's take a look at how I am displaying this on the home screen view:
base.html
...abbreviated...
<a data-toggle="modal" href="#exampleModal">Shipment</buton>
<!-- Modal -->
<div class="modal fade" id="exampleModal" tabindex="-1" role="dialog" aria-labelledby="exampleModalLabel" aria-hidden="true">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="exampleModalLabel">Create Shipment</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<form method="POST">
{% csrf_token %}
<div class="modal-body">
{{shipmentForm|crispy}}
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
<button type="submit" name="shipment" class="btn btn-primary">Save changes</button>
</form>
</div>
</div>
</div>
</div>
And here is the view which passes shipmentForm to that template
views.py
def HomeView(request):
if request.method == 'POST':
shipment_form = CreateShipmentForm(request.POST)
if shipment_form.is_valid():
new_shipment = shipment_form.save()the user to the success page
return redirect('ShipmentListView')
shipmentForm = CreateShipmentForm()
context = {
'shipmentForm': shipmentForm,
}
return render(request, 'home.html', context)
This works perfectly fine, but the problem is, I would need to include this code from HomeView in every single view in my app. That would be a lot of repeating myself. I have included the html for the modal in my base.html so that I don't have to repeat that. But instead of what I have above, I'd like to make the button which launches the modal look/do something like this.
base.html
<a data-toggle="modal" href="{% url 'CreateShipmentView' %}>Shipment</buton>
Put the html for the modal form in a separate file:
modal.html
<!-- Modal -->
<div class="modal fade" id="exampleModal" tabindex="-1" role="dialog" aria-labelledby="exampleModalLabel" aria-hidden="true">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="exampleModalLabel">Create Shipment</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<form method="POST">
{% csrf_token %}
<div class="modal-body">
{{shipmentForm|crispy}}
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
<button type="submit" name="shipment" class="btn btn-primary">Save changes</button>
</form>
</div>
</div>
</div>
</div>
Then have a view like this:
def CreateShipmentView(request):
if request.method == 'POST':
shipment_form = CreateShipmentForm(request.POST)
if shipment_form.is_valid():
new_shipment = shipment_form.save()the user to the success page
return redirect('ShipmentListView')
shipmentForm = CreateShipmentForm()
context = {
'shipmentForm': shipmentForm,
}
return render(request, 'modal.html', context)
How is this possible without using django-modal-bootstrap package? I tried that but it seemed to be very very touchy and I did not like it so would prefer to avoid that. Can anyone point me in the direction of how I could make this work please?
Related
I am working on an application that has a page with a table that is a list of users. Each user has a button which pops up a modal that does something. I am trying to create the modal that will get the user information when the button in clicked, additionally, I need in that modal some logic based on the user information and some more data. I am thinking that it makes sense to create a separate view for it but since each view must be on a different url, the concept of the modal does not makes sense (for me), because I want it to be on the same url.
Is it possible to have a modal with a different view that will have a separate logic? Since the modal is included in the template and it is basically just one template, then, can one template have 2 views?
What is the best way to implement the modal using django? And how to pass data to it, I need the data from the row that was selected + some more data from db. I have the data from the context but manipulating that using JQuery for me is a bad idea - because I am using a python session on the backend that communicates with another api, so when user clickes the modal save button, a python request needs to be done, this means I need a view for it.
Here is my try
Modal
{% block modal %}
{% load static %}
{% load authorization_tags %}
<!-- Modal -->
<div class="modal fade" id="{{modal_id}}" tabindex="-1" role="dialog" aria-labelledby="exampleModalLabel" aria-hidden="true">
<div class="modal-dialog modal-lg" role="document">
<div class="modal-content">
<div class="row">
<div class="col-lg-5">
<img class="d-block w-100"
src="{% static 'app/assets/images/security-shield1.png' %}"
alt="First slide">
Use access control to deauthorize user
</div>
<div class="col-lg-7">
<h2 class="h2-responsive product-name">
<strong>{{user.real_name}}</strong>
</h2>
<h4 class="h4-responsive">
<span class="green-text">
{{user.username}}
</span>
</span>
</h4>
<div class="accordion md-accordion" id="accordion1" role="tablist" aria-multiselectable="true">
<div class="card">
<div class="card-header" role="tab" id="heading2">
<a data-toggle="collapse" data-parent="#accordion1" href="#collapse1" aria-expanded="true"
aria-controls="collapse1">
<h5 class="mb-0">
Current Authorizations <i class="fas fa-angle-down rotate-icon"></i>
</h5>
</a>
</div>
<div id="collapse1" class="collapse show" role="tabpanel" aria-labelledby="heading1"
data-parent="#accordion1">
<div class="card-body">
{% for right in people_rights|user_active_rights:user.id %}
{{right.room}}
{% endfor %}
</div>
</div>
</div>
</div>
<div class="accordion md-accordion" id="accordion2" role="tablist" aria-multiselectable="true">
<div class="card">
<div class="card-header" role="tab" id="heading2">
<a data-toggle="collapse" data-parent="#accordion2" href="#collapse2" aria-expanded="true"
aria-controls="collapse2">
<h5 class="mb-0">
Available Authorizations <i class="fas fa-angle-down rotate-icon"></i>
</h5>
</a>
</div>
<div id="collapse2" class="collapse show" role="tabpanel" aria-labelledby="heading2"
data-parent="#accordion2">
<div class="card-body">
</div>
</div>
</div>
</div>
<div class="card-body">
<div class="text-center">
<button type="button" class="btn btn-lg" data-dismiss="modal"><span>Close</span></button>
<button class="btn btn-lg"><span>Authorize</span></button>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
{% endblock modal %}
a piece of table and the modal included in the same template
{% include 'app/admin/users/user_authorize.html' with modal_id="authModal" user=row areas=areas rooms=rooms people_rights=people_rights %}
{%if row.empno %}
<td class="txt-oflo">{{ row.empno }}</td>
{% else %}
<td class="txt-oflo">-</td>
{% endif %}
<td>
{% with "#"|add:row.id as buttonId %}
<button id={{buttonId}} class="btn btn-lg" data-toggle="modal" data-target="#authModal">
<span>Authorize</span>
</button>
{% endwith %}
</td>
</tr>
You can try the following steps to solve the issue.
Create a separate view for the modal on a separate url.
Take the modal data out of this html file and place it in another html file. The empty modal in the original html should look something like this.
<div id="SampleTable" class="modal fade" tabindex="-1" role="dialog">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">sample title</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body" id="sample_datatable">
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
</div>
</div>
</div>
Render that new html from the new view that was created. The ajax request that will be activated from the button that gives us the modal table might look something like this.
#app.route('/sample_data', methods=['GET', 'POST'])
def modal_table():
try:
data = request.args.get('arg')
database_data = Table.query.filter(Table.data == data).all()
result_dict = [u.__dict__ for u in database_data]
except Exception as e:
traceback.print_exc()
return render_template('modal_table.html', data=enumerate(result_dict))
The button in the original html that results in the modal table should be configured in a way using ajax requests that it renders data from the new html into the old modal data like this.
function get_sample_data() {
$.ajax({
url:"/sample_data", //the page containing python script
type: "GET", //request type,
data: {},
async:true,
beforeSend: function(){
$('#sample_datatable').html('Loading..');
},
success:function(result){
$('#sample_datatable').html(result);
}
});
}
You can call this javascript function from the button that is supposed to show the modal table.
Im trying to create note detail in modal popup window.
Here is the modal invoke anchor tag
<a class="fa fa-pencil" data-toggle="modal" href="{% url 'post_detail_view' %}" data-id="{{ todo_item.content }}" data-target="#modal" title="edit item" data-tooltip></a>
here is the view function in views.py:
def post_detail_view(request, content):
all_items1 = TodoItem.objects.get(content=content)
return render(request, 'todo.html', {'all_items1': all_items1})
here is my urls.py :
path('post_detail_view/<str:content>/', views.post_detail_view, name='post_detail_view'),
This is my modal code in todo.html
<div class="modal-dialog" role="document">
<div class="modal-content">
<form action="/addTodo/" method="post" enctype="multipart/form-data">
{% csrf_token %}
<div class="modal-header">
<h5 class="modal-title" id="exampleModalLabe2">Edit Info</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
{% if all_items1 %}
<label for="content">Title :</label><br>
<p>{{ all_items1.content }}</p>
<p>{{ all_items1.data }}</p>
<input type="text" id='c' name="content" value="{{ all_items1.content }}"/><br>
<label for="data">Description :</label><br>
<textarea id="data" rows="4" cols="50" value="">{{ all_items1.data }}</textarea>
<br>
<label for="tags">Tags :</label><br>
<input type="tags" name="tags" value="{{ all_items1.tags }}"/><br>
<a href="{{ all_items1.file.url }}">
{% load static %}
<img src="{% static 'ico.png' %}" style="width:30px;height:30px" alt="download">
</a>
<button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
{% endif %}
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
<button type="submit" class="btn btn-primary">Save changes</button>
</div>
</form>
</div>
</form>
</div>
This code is not working. I can see modal is popping up but no data is displayed. I'm still learning Django. Can someone please help.
I think, your parameter is not passing to view layer. try this:
<a class="fa fa-pencil" data-toggle="modal" href="{% url 'post_detail_view' todo_item.content %}" data-target="#modal" title="edit item" data-tooltip></a>
I am new to programming. I found nice bootstrap modal for registration, so i put it to my html code and it looks nice but nothing can be pressed or post.
Before i was using django and UserCreationForm without modals. So help me to concatenate these two things:
so this is my bootstrap modal that i found
<!-- Modal -->
<div class="modal fade" id="elegantModalForm" tabindex="-1" role="dialog" aria-labelledby="myModalLabel"
aria-hidden="true">
<div class="modal-dialog" role="document">
<!--Content-->
<div class="modal-content form-elegant">
<!--Header-->
<div class="modal-header text-center">
<h3 class="modal-title w-100 dark-grey-text font-weight-bold my-3" id="myModalLabel"><strong>Войти</strong></h3>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<!--Body-->
<form type="post" action="{% url 'common:login' %}">
<div class="modal-body mx-4">
<!--Body-->
<div class="md-form mb-5">
<input type="email" name="useremail" id="Form-email1" class="form-control validate">
<label data-error="wrong" data-success="right" for="Form-email1">Ваша почта</label>
</div>
<div class="md-form pb-3">
<input type="password" id="Form-pass1" class="form-control validate">
<label data-error="wrong" data-success="right" for="Form-pass1">Пароль</label>
<p class="font-small blue-text d-flex justify-content-end">Забыли <a href="#" class="blue-text ml-1">
пароль?</a></p>
</div>
<div class="text-center mb-3">
<button type="button" class="btn blue-gradient btn-block btn-rounded">ок</button>
</div>
<p class="font-small dark-grey-text text-right d-flex justify-content-center mb-3 pt-2"> или войти
с помощью:</p>
<div class="row my-3 d-flex justify-content-center">
<!--Facebook-->
<button type="button" class="btn btn-white btn-rounded mr-md-3 z-depth-1a"><i class="fab fa-facebook-f text-center"></i></button>
<!--Twitter-->
<button type="button" class="btn btn-white btn-rounded mr-md-3 z-depth-1a"><i class="fab fa-twitter"></i></button>
<!--Google +-->
<button type="button" class="btn btn-white btn-rounded z-depth-1a"><i class="fab fa-google-plus-g"></i></button>
</div>
</div>
</form>
<!--Footer-->
<div class="modal-footer mx-5 pt-3 mb-1">
<p class="font-small grey-text d-flex justify-content-end">Первый раз? <a href="{% url 'common:signup' %}" class="blue-text ml-1">
Зарегистрируйся</a></p>
</div>
</div>
<!--/.Content-->
</div>
</div>
<!-- Modal -->
and this is my views.py before using modal:
def signup(request):
if request.method == 'POST':
form = UserCreationForm(request.POST)
if form.is_valid():
form.save()
return redirect('index')
else:
form = UserCreationForm()
return render(request, 'registration/signup.html', {'form': form})
So help me to show how it should work. Actually i used to use {{form.as_p}} but how should i do in this case?
I think what you are looking for is Django Forms
official doc- https://docs.djangoproject.com/en/2.2/topics/forms/
other- ( https://www.tutorialspoint.com/django/django_form_processing)
First, you need to create a form model and define the fields which you are taking as input.
Here is a sample-
from django import forms
class LoginForm(forms.Form):
user = forms.CharField(max_length = 100)
password = forms.CharField(max_length =100)
Then, you need to modify the view according to form. Here is a sample-
def login(request):
username = "not logged in"
if request.method == "POST":
#Get the posted form
MyLoginForm = LoginForm(request.POST)
if MyLoginForm.is_valid():
username = MyLoginForm.cleaned_data['username']
else:
MyLoginForm = Loginform()
return render(request, 'loggedin.html', {"username" : username})
and if you are sending data through POST, don't forget to add csrf token just in Html file.
form type="post" action="{% url 'common:login' %}">
{% csrf_token %}
Does anyone face this issue.. I have a very strange behavior with Flask and Bootstrap modal. On my dev server http://127.0.0.1:5000/ I have a modal which appears after user is typing wrong login credentials:
HTML code in Index page:
<div class="modal fade" id="ExistsModal" tabindex="-1" role="dialog" aria-labelledby="exampleModalLabel" aria-hidden="true">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="exampleModalLabel">This email already exists!</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
If you have forgotten your password, .......
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal">Continue</button>
</div>
</div>
</div>
</div>
But on my production 'http://flask-env.xxx.us-west-1.elasticbeanstalk.com I can see the modal only if I manually refresh a page!
For return function I'm using
return redirect(url_for('index',_anchor='login')) and in index() I passed arguments!
{% if email_exists %}
<script>
$("#ExistsModal").modal('show');
</script>
{% endif %}
My question is - why modal show up after manual refresh on production? But on dev its works fine!
This is some code from my index.html. My issue is that the action on the form in the modal is not working (no error, just doing nothing) yet the form outside the model is working fine (commented test button). The model is opening fine and seems correctly formatted, yet the 'yes' button does nothing but closes the modal. The problem does not seem to be in the URL. Any help would be much appreciated. I am using django by the way
{% for patient in all_patients %}
<div class="col-lg-12">
<div class="panel panel-default">
<div class="panel-body">
<!-- Name -->
<h4>{{ patient }}</h4>
<!-- View Details -->
View Details
<!-- Edit Details -->
Edit Details
<!-- Delete Patient -->
<input type="hidden" name="patient_id" value="{{ patient.id }}" />
<button type="submit" class="btn btn-default btn-sm" data-toggle="modal" data-target="#patient_id">
<span class="glyphicon glyphicon-trash"></span>
</button>
<!-- Modal -->
<div class="modal fade" id="patient_id" role="dialog">
<div class="modal-dialog">
<!-- Modal content-->
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal">×</button>
<h4 class="modal-title">Confirm delete</h4>
</div>
<div class="modal-body">
<p>Are you sure you want to delete {{ patient }}?</p>
</div>
<div class="modal-footer">
<button type="submit" class="btn btn-default" data-dismiss="modal">No</button>
<form action="{% url 'patients:patient-delete' patient.id %}" method="post" style="display: inline;">
{% csrf_token %}
<button type="submit" class="btn btn-danger" data-dismiss="modal">Yes</button>
</form>
</div>
</div>
</div>
</div>
<!-- test button -->
<form action="{% url 'patients:patient-delete' patient.id %}" method="post" style="display: inline;">
{% csrf_token %}
<button type="submit" class="btn btn-danger" data-dismiss="modal">Delete</button>
</form>
</div>
</div>
</div>
{% cycle '' '' '' '' '' '<div class="clearfix visible-lg"></div>' %}
{% endfor %}