I am trying to make a loading screen when submitting a form. When I submit a form the page starts to load until the backend responds by downloading an excel file. The idea is to have the effect of "load screen" only until the file manages to download.
html:
<form action="{% url 'downloadStatusPickingCustomerByCollection' %}" method="POST">{% csrf_token %}
<div class="pnl-collection">
<div>
<div class="tituloPnl">
<h3>Estado Ordenes de Venta por Colección</h3>
</div>
<div class="btnExport">
<button onclick="loadDisplay()" class="btn btn-light" type="submit">Exportar</button>
</div>
</div>
<div class="filtro">
<div>
<div class="title-select"><span>Colección</span></div>
</div>
<div>
<select class="form-select form-select-sm form-down-report" name="collection-StatusCustomer-name" id="" required>
<option value="">- SELECCIONE COLECCIÓN -</option>
{% if collections %}
{% for collection in collections%}
<option value="{{collection.Name}}">{{collection.Name}}</option>
{% endfor %}
{% endif %}
</select>
</div>
</div>
</div>
</form>
javascript:
function loadDisplay() {
if (document.querySelector(".form-down-report").value != "") {
document.getElementById("preloader-camion").style.display = 'block';
jquery(window).load(
function () {
document.getElementById("preloader-camion").style.display = 'none';
});
}
}
I have the bakcend developed in django so in the form route you can see a django "url tag".
Related
I'm working on a quiz app and want to generate a number of input fields representing the answers based on the value that the user types.
I'm using a button named "create" to do that Using JavaScript, but when clicking the button it submits the form.
Please Check the two images below.
Input
Output
HTML Code
{% load static %}
{% block body %}
<button class="btn btn-primary new">Add a question</button>
<form class="question" method="POST" style="display: none">
{% csrf_token %}
<div class="form-group">
<label for="exampleInputEmail1">Title</label>
<input type="text" class="form-control" id="title" placeholder="Question title">
</div>
<div class="form-group" id="answers_num">
<label for="exampleInputPassword1">Number of answers</label>
<input type="number" class="form-control" id="ans_number">
<button class="create_answers">Create</button>
</div>
<div class="form-group">
{% comment %} Generated input fields {% endcomment %}
</div>
<button type="submit" class="btn btn-primary">Submit</button>
</form>
{% block script %}
<script src="{% static 'mcq/index.js' %}"></script>
{% endblock %}
{% endblock %}```
JS code
document.querySelector(".new").addEventListener("click", ()=> {
document.querySelector(".question").style.display = 'block';
document.querySelector("#create_answers").addEventListener("click", ()=> {
answers = this.value;
console.log(answers);
// Create input fields
for (let i = 0; i < answers; i++) {
input = document.createElement("input");
input.classList.add('form-control');
answersDiv = document.querySelector("#answers").appendChild(input);
}
})
})```
You need to explicitly set the type of the button, like
<button class="create_answers" type="button">Create</button>
in order to avoid submitting the form upon click.
I have a form which when submitted creates a graph using Plotly. I am trying to use Ajax to submit the form without page refresh. While the form is submitted successfully, the form div is duplicated on the screen. I am not sure how to rectify this problem. I am using the Django web framework. Here is my code.
template
<form action="{% url 'home' %}" method='post' id='year-form'>
{% csrf_token %}
<select class="form-select form-select-lg mb-3 dropdown-btn" aria-label="Default select example"
name="year">
<option selected>Select Year</option>
<option value="2017">2017</option>
<option value="2018">2018</option>
<option value="2019">2019</option>
<option value="2020">2020</option>
</select>
<div class="d-grid gap-2">
<button class="btn btn-primary btn-lg" type="submit">Button</button>
</div>
</form>
<div id="message"></div>
<div class="graph center" id='graph'>
{% if graph %}
{{ graph.0|safe }}
{% else %}
<p>No graph was provided.</p>
{% endif %}
</div>
ajax jQuery
<script type="text/javascript">
var frm = $('#year-form');
frm.submit(function () {
$.ajax({
type: frm.attr('method'),
url: frm.attr('action'),
data: $(this).serialize(),
success: function (data) {
$("#graph").html(data);
},
error: function (data) {
$("#message").html("Something went wrong!");
}
});
return false;
});
</script>
This is what the page looks like before the form submit
this is what it looks like after the form is submitted
I think I am not feeding the correct data in the success part of the Ajax call.
You should use a different endpoint/view to return the graph template. At the moment you are getting the current page and loading it again but with a graph this time.
Your home template should be:
<form action="{% url 'home' %}" method='post' id='year-form'>
{% csrf_token %}
<select class="form-select form-select-lg mb-3 dropdown-btn" aria-label="Default select example"
name="year">
<option selected>Select Year</option>
<option value="2017">2017</option>
<option value="2018">2018</option>
<option value="2019">2019</option>
<option value="2020">2020</option>
</select>
<div class="d-grid gap-2">
<button class="btn btn-primary btn-lg" type="submit">Button</button>
</div>
</form>
<div id="message"></div>
<div class="graph center" id='graph'>
<p>No graph was provided.</p>
</div>
Then you have a second template used at a different view which you get via ajax to get the graph like so:
{% if graph %}
{{ graph.0|safe }}
{% else %}
<p>No graph was provided.</p>
{% endif %}
Based on the following image, I am trying to make the fields category and current points non-editable when the status of the task is Finalized or Cancelled, otherwise the fields should be editable.
Below is the code from my html file.
{% extends "base.html" %} {% load widget_tweaks %}
{% block content %}
<div id="form-group">
<form method="POST" action="." enctype="multipart/form-data">
{% csrf_token %}
<label>Select your category</label>
{{ form.category|add_class:"card" }}
<label>What's the status of the task?</label>
{{ form.status|add_class:"card" }}
<label>Current points:</label>
{{ form.points|add_class:"card" }}
<label>Finalized date:</label>
{{ form.ending_date|add_class:"card" }}
<button type="submit" class="btn btn-success">Send</button>
</form>
</div>
Below is the code from my forms.py file.
class TaskModelForm(forms.ModelForm):
class Meta:
model= Task
fields = ['category', 'status', 'points']
def __init__(self, *args, **kwargs):
super(TaskModelForm, self).__init__(*args, **kwargs)
self.fields['status'].required = False
self.fields['points'].required = False
When I want to edit the contents of this form I need to verify if the status is Finalized, so the fields are non-editable, otherwise the fields should be editable and I am thinking something about:
{% extends "base.html" %} {% load widget_tweaks %}
{% block content %}
{% if form.status.value == 'Active' %} <!--make the fields editable -->
<div id="form-group">
<form method="POST" action="." enctype="multipart/form-data">
{% csrf_token %}
<label>Select your category</label>
{{ form.category|add_class:"card" }}
...
<button type="submit" class="btn btn-success">Send</button>
</form>
</div>
{% endif %}
{% if form.status.value == 'Finalized' %} <!--make the fields non-editable -->
<div id="form-group">
<form method="POST" action="." enctype="multipart/form-data">
{% csrf_token %}
<label>Select your category</label>
{{ form.category|add_class:"card" }}
...
<button type="submit" class="btn btn-success">Send</button>
</form>
</div>
{% endif %}
However, I believe my approach might not work because this could be a more front-end problem rather than back-end one (just a guess). Can you point me out to the right direction to solve this problem?
Since the status is something that the user selects, you can't address your requirement with Python (Django) running on the server. You have to address it with a JavaScript running in the web page that displays the form. Something like this will definitely do the trick.
{% extends "base.html" %} {% load widget_tweaks %}
{% block content %}
<body onload="makeReadOnly();">
<div id="form-group">
<form method="POST" action="." enctype="multipart/form-data">
{% csrf_token %}
<div class="tweet-composer">
<label>Insert your task</label>
{{ form.task|add_class:"card js-keeper-editor" }}
</div>
<label>Select your category</label>
{{ form.category|add_class:"card" }}
<label>Current points:</label>
{{ form.points|add_class:"card" }}
<button type="submit" class="btn btn-success">Send</button>
</form>
</div>
</body>
{% endblock content %}
<script type="text/javascript">
{% block jquery %}
function makeReadOnly()
{
if (document.getElementById('id_status').value == 'Finalized'){
document.getElementById('id_task').readOnly=true;
document.getElementById('id_category').readOnly=true;
}else if (document.getElementById('id_status').value == 'Active'){
document.getElementById('id_task').readOnly=true;
document.getElementById('id_category').readOnly=false;
}
}
document.getElementById('id_status').addEventListener('change', makeReadOnly);
{% endblock %}
</script>
With the "view page source" you can see the HTML structure that Django generates out of your form, so that you can identify the right bits with JQuery selectors. Alternatively you can do
f = SomethingForm()
f.as_p()
in the ./manage.py shell console.
At the Django end, you may need custom form validation to handle the inter-dependency between the value of status and whether the other fields are required or not.
I have a following code in jQuery:
$(".edit-trigger").on("click", function () {
url = $(this).data('url');
$.get(url, function(data) {
$("#modal .modal-content").html(data);
});
});
and it is loading following code (data) into modal window:
<form id="personal_info_form" class="modal-form">
<input type="hidden" value="{{ csrf_token }}" name="csrfmiddlewaretoken">
<div class="modal-content">
{% for field in form %}
<div class="row">
<div class="input-field col s12">
{{ field }}
<label for="{{ field.id }}" data-error="wrong">{{ field.label }}</label>
</div>
</div>
{% endfor %}
</div>
<div class="modal-footer">
<button class="modal-action modal-close">Anuluj</button>
<button type="submit">Akceptuj</button>
</div>
</form>
<script>
M.updateTextFields();
</script>
The issue is that script in loaded code is not always executed. Is it possible to ensure execution of that script?
I am new to django forms and while trying to design an HTML form, I notice that the django form blocks are not displaying. Below are the codes:
<body> tag of index.html:
<div class="container">
<div class="row">
<div class="col-md-6 col-md-offset-3">
<div class="panel panel-login">
<div class="panel-heading">
<div class="row">
<div class="col-xs-6">
Login
</div>
<div class="col-xs-6">
Register
</div>
</div>
<hr>
</div>
<div class="panel-body">
<div class="row">
<div class="col-lg-12">
{% block login_content %}
{% endblock %}
{% block register_content %}
{% endblock %}
</div>
</div>
</div>
</div>
</div>
</div>
</div>
login.html which goes into the {% block login_content %}
{% extends 'index.html' %}
{% block login_content %}
<form id="login-form" action="{% url 'authentication:user_login' %}" role="form" style="display: block;" method="POST">
{% csrf_token %}
<label for="username">Username:</label>
<input id="username" type="text" name="username" placeholder="Enter Username" tabindex="1" class="form-control">
<label for="password">Password:</label>
<input id="password" type="password" name="password" tabindex="=2" class="form-control" placeholder="Password">
<button type="submit" class="btn btn-success">Login</button>
</form>
{% endblock %}
register.html that goes into the {% block register_content %}
{% extends 'index.html' %}
{% block register_content %}
<form id="register-form" role="form" style="display: none;" enctype="multipart/form-data" method="POST">
{% csrf_token %}
{{ user_form.as_p }}
{{ profile_form.as_p }}
<input type="submit" name="" value="Register">
</form>
{% endblock %}
On my UI, the {{ user_form.as_p }} and the {{ profile_form.as_p }} does not appear at all.
When i inspect the console of my UI, the html does not even pick up the following line from the register.html:
<form id="register-form" role="form" style="display: none;" enctype="multipart/form-data" method="POST">
Here is the login.js which is responsible for the UI interactivity:
$(function() {
$('#login-form-link').click(function(e) {
$("#login-form").delay(100).fadeIn(100);
$("#register-form").fadeOut(100);
$('#register-form-link').removeClass('active');
$(this).addClass('active');
e.preventDefault();
});
$('#register-form-link').click(function(e) {
$("#register-form").delay(100).fadeIn(100);
$("#login-form").fadeOut(100);
$('#login-form-link').removeClass('active');
$(this).addClass('active');
e.preventDefault();
});
});
EDIT:
Here is my views.py:
def user_login(request):
if request.method == "POST":
username = request.POST.get('username')
password = request.POST.get('password')
user = authenticate(username=username, password=password)
if user:
if user.is_active:
login(request, user)
return HttpResponseRedirect(reverse('homepage')) # main page if login is successful
else:
return HttpResponse("ACCOUNT NOT ACTIVE")
else:
print('Someone tried to log in and failed')
print('Username: {}, password, {}'.format(username, password))
return HttpResponse('Invalid login details supplied')
else:
return render(request, 'authentication/login.html', {})
def register(request):
registered = False
if request.method == "POST":
user_form = UserForm(data=request.POST)
profile_form = UserProfileInfoForm(data=request.POST)
if user_form.is_valid() and profile_form.is_valid():
user = user_form.save()
user.set_password(user.password)
user.save()
profile = profile_form.save(commit=False)
profile.user = user
if 'profile_pic' in request.FILES:
profile.profile_pic = request.FILES['profile_pic']
profile.save()
registered = True
else:
print(user_form.errors, profile_form.errors)
else:
user_form = UserForm()
profile_form = UserProfileInfoForm()
return render(request, 'authentication/register.html',
{
'user_form': user_form,
'profile_form': profile_form,
'registered': registered
})
Okay, it seems like it is impossible to have a single page display both the templates. Is there anyway to get it done?
In your register.html,
<form id="register-form" role="form" style="display: none;" enctype="multipart/form-data" method="POST">
You are setting style="display: none;", so obviously the form won't show up.
EDIT: I am not sure about the feasibility of showing two different forms in the same page.