I am trying to submit a HTML Form using Ajax, But I am not getting any alert success or failure.
index.html
<form method="post" class="needs-validation" enctype="multipart/form-data" action="/upload/" id="fupload">
<div class="custom-file">
<input type="file" class="custom-file-input" id="data_files" name="data_files" multiple required>
<label class="custom-file-label" for="data_files">Choose files</label>
</div>
<button type="submit">Upload files</button>
</form>
<script type="text/javascript">
var frm = $('#fupload');
frm.submit(function () {
$.ajax({
type: frm.attr('method'),
url: frm.attr('action'),
data: frm.serialize(),
success: function (data) {
alert('Form Submitted');
},
error: function(data) {
alert('Form submission failed');
}
});
return false;
});
views.py
#csrf_exempt
def upload(request):
if request.method == 'POST':
return HttpResponse()
Any guesses why it doesn't work
Try changing the following:
Remove the action.
Change the button to type="button" and add an event listener
<form method="post" class="needs-validation" id="fupload">
<div class="custom-file">
<input type="file" class="custom-file-input" id="data_files" name="data_files" multiple required>
<label class="custom-file-label" for="data_files">Choose files</label>
</div>
<button type="button" id="upload-files-btn">Upload files</button>
</form>
<script type="text/javascript">
var frm = $('#fupload');
var btn = $('#upload-files-btn');
btn.bind('click', handleClick);
var formData = new FormData(); // Use FormData instead
formData.append('file', frm.files[0], frm.files[0].name) // The first argument is the 'key' of the form data so change it to whatever works.
var handleClick = function (event) {
event.preventDefault();
$.ajax({
type: frm.attr('method'),
url: '/upload/',
data: formData,
contentType: false, // add this to indicate 'multipart/form-data'
success: function (data) {
alert('Form Submitted');
},
error: function(data) {
alert('Form submission failed');
}
});
}
</script>
Related
I am trying to build a dependant dropdown in a django form, but it is not working. I have followed videos and tutorials, but got no luck.
I would like to select a brand of a car (make) and then a model of a car. The model depends on the car's brand, of course.
I have followed this tutorial https://python.plainenglish.io/python-and-django-create-a-dependent-chained-dropdown-select-list-b2c796f5a11
Status: The "Make" dropdown works fine. The "Model" dropdown is never showing anything.
It just does not work, but no error is shown... :S
models.py
from django.db import models
from django import forms
class Vehicle(models.Model):
make = forms.CharField(max_length=30)
model = forms.CharField(max_length=30)
...omitted
forms.py
from django import forms
from .models import Vehicle
import json
def readJson(filename):
with open(filename, 'r') as fp:
return json.load(fp)
def get_make():
""" GET MAKE SELECTION """
filepath = '/Users/alvarolozanoalonso/desktop/project_tfm/tfm/JSON/make_model_A.json'
all_data = readJson(filepath)
all_makes = [('-----', '---Select a Make---')]
for x in all_data:
if (x['make_name'], x['make_name']) in all_makes:
continue
else:
y = (x['make_name'], x['make_name'])
all_makes.append(y)
# here I have also tried "all_makes.append(x['make_name'])
return all_makes
class VehicleForm(forms.ModelForm):
make = forms.ChoiceField(
choices = get_make(),
required = False,
label='Make:',
widget=forms.Select(attrs={'class': 'form-control', 'id': 'id_make'}),
)
...omitted
class Meta:
model = Vehicle
fields = ['make', 'is_new', 'body_type', 'fuel_type', 'exterior_color', 'transmission', 'wheel_system', 'engine_type',
'horsepower', 'engine_displacement', 'mileage', 'transmission_display', 'year', 'fuel_tank_volume',
'city_fuel_economy', 'highway_fuel_economy', 'maximum_seating']
model.HTML
{% block javascript %}
<script>
$("#id_make").change(function () {
var makeId = $(this).val();
$.ajax({
type: "POST",
url: "{% url 'get-model' %}",
data: {
'csrfmiddlewaretoken': '{{ csrf_token }}',
'make': makeId,
},
success: function (data) {
console.log(data.models);
let html_data = '<option value="">-------</option>';
data.models.forEach(function (data) {
html_data += `<option value="${data}">${data}</option>`
});
$("#id_model").html(html_data);
}
});
});
</script>
{% endblock javascript %}
<form class="" action="" method="post">
{% csrf_token %}
{% for error in errors %}
<div class="alert alert-danger mb-4" role="alert">
<strong>{{ error }}</strong>
</div>
{% endfor %}
<div class="form-row">
<div class="form-group col-md-6">
<label>Status:</label>
{{ form.make }}
</div>
<div class="form-group col-lg-6">
<label >Model:</label>
<select id="id_model" class="form-control" name="state">
<option value="-----">Select Model</option>
</select>
</div>
...omitted
<div class="form-group col-md-6">
<button type="submit" class="btn btn-primary">Calculate</button>
</div>
</form>
views.py
def model(request):
context = {}
if request.method == 'GET':
form = VehicleForm()
context['form'] = form
return render(request, 'model.html', context)
if request.method == 'POST':
form = VehicleForm(request.POST)
if form.is_valid():
return render(request, 'model.html', context)
def getModel(request):
make = request.POST.get('make')
models = return_model_by_make(make)
return JsonResponse({'models': models})
Your change handler for id_make is attached before the select is created in the DOM, so your event handler does not fire.
You can use event delegation to set up an event handler before an element is created
$(document).on('change', "#id_make", function () {
var makeId = $(this).val();
$.ajax({
type: "POST",
url: "{% url 'get-model' %}",
data: {
'csrfmiddlewaretoken': '{{ csrf_token }}',
'make': makeId,
},
success: function (data) {
console.log(data.models);
let html_data = '<option value="">-------</option>';
data.models.forEach(function (data) {
html_data += `<option value="${data}">${data}</option>`
});
$("#id_model").html(html_data);
}
});
});
I have this form and on addmorefield button click I'm appending two more fields with same name and
<form method="post" id="sampleform" action="#">
<div class="input_fields" style="text-align:center">
<input type="text" name="first_name" id="first_name" placeholder="first name"/>
<input type="text" name="last_name" id="last_name" placeholder="Last Name"/>
<button class="add_button">Add More Fields</button>
<button type="submit">Submit</button>
</div>
<script>
$(document).ready(function() {
var max_fields = 10;
var wrapper = $(".input_fields");
var add_button = $(".add_button");
var x = 1;
$(add_button).click(function(e){
e.preventDefault();
if(x < max_fields){
x++;
$(wrapper).append(
'<div class="form-group" style="margin-top:5px"><input type="text" name="first_name" placeholder="first name" required/><input type="text" name="last_name" placeholder="last name" required/>Remove</div>'
);
}
});
$(wrapper).on("click",".remove_field", function(e){
e.preventDefault(); $(this).parent('div').remove(); x--;
})
});
</script>
i'm making post request with DRF api in this format {"first_name":"value","last_name":"value"}. so what i want to achieve here to covert this form input into this format [{"first_name":"value","last_name":" value"},{"first_name":"value","last_name":" value"}]
<script>
$('#sampleform').submit(function(e){
e.preventDefault();
var form = $(this);
$.ajax({
url:"http://localhost:8000/api/",
type:"post",
data: $('#sampleform').serialize(),
//dataType:'json',
success: function(data){
console.log(data)
},
});
});
</script>
You can loop through the div which has required inputs , get the value for first_name and last_name and put that in array .
Demo Code :
$(document).ready(function() {
var max_fields = 10;
var wrapper = $(".input_fields");
var add_button = $(".add_button");
var x = 1;
$(add_button).click(function(e) {
e.preventDefault();
if (x < max_fields) {
x++;
//added one extra class values
$(wrapper).append(
'<div class="form-group values" style="margin-top:5px"><input type="text" name="first_name" placeholder="first name" required/><input type="text" name="last_name" placeholder="last name" required/>Remove</div>'
);
}
});
$(wrapper).on("click", ".remove_field", function(e) {
e.preventDefault();
$(this).parent('div').remove();
x--;
})
$('#sampleform').submit(function(e) {
e.preventDefault();
var values = new Array();
//looping through div class=values
$(".values").each(function() {
//getting value of inputs
var first_name = $(this).find("input[name=first_name]").val();
var last_name = $(this).find("input[name=last_name]").val();
item = {}
item["first_name"] = first_name;
item["last_name"] = last_name; //adding values
values.push(item); //adding item to array
});
console.log(values)
$.ajax({
url: "http://localhost:8000/api/",
type: "post",
data: JSON.stringify(values), //pass value to your server
//dataType:'json',
success: function(data) {
console.log(data)
},
});
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<form method="post" id="sampleform" action="#">
<div class="input_fields values" style="text-align:center">
<input type="text" name="first_name" id="first_name" placeholder="first name" />
<input type="text" name="last_name" id="last_name" placeholder="Last Name" />
<button class="add_button">Add More Fields</button>
<button type="submit">Submit</button>
</div>
I'd like to fill / update a div area in index.html with the result from the python function, but I don't know how to do this. I know there are several other questions with a similar topic but I couldn't succeed with them because they were too specific. I'm pulling my hair out over this.
Would be someone so nice and guide me?
This is a function in main.py:
#app.route('/')
def index():
return render_template('index.html')
#app.route('/stat/')
def stat():
a = 2
b = 10
return(str(a) + ' is not ' + str(b))
this is the index.html:
<body>
<form action="/stat/">
<button type="submit" id="btn1" class="btn btn-primary btn-sm">check stat</button>
</form>
<div id="stat_content"></div>
</body>
As #S3DEV points out, you will need to pass the string to the template via an additional argument. For example, we might do something like this:
#app.route('/stat/', methods=['GET', 'POST']) # EDIT
def stat():
a = 2
b = 10
text = f"{a} is not equal to {b}"
return render_template("index.html", text=text)
In the code above, we set text to be the string to be passed to the template. In the template, we will be able to access this string variable as text.
Now when index.html is rendered, it will be looking for the text variable that is passed in from the Flask application. This is taken care of by Jinja 2, which is the rendering engine used by Flask.
<div id="stat_content">
{% if text %}
<h2>No text to show</h2>
{% else %}
<h2>{{ text }}</h2>
{% endif %}
</div>
Using Jinja 2 syntax with curly braces, we first check if the text variable exists or not; if it does not exist, we render the message, "No text to show." This will happen when we first route into "/", or the default home route of the Flask app.
Once the user fills out the form, however, they will be redirected to "/stat/", at which point we will now have generated text and passed it back to index.html via the render_template("index.html", text=text) function call. Then, when Jinja 2 renders index.html, it will see that text was passed over from the Flask app and display that message, namely that 2 is not equal to 10.
You want this initiated from the button right? Here's how to achieve that with ajax...
<body>
<form action="/stat/">
<button type="submit" onclick="GetData();" id="btn1" class="btn btn-primary btn-sm">check stat</button>
</form>
<div id="stat_content"></div>
</body>
<script type="text/javascript">
function GetData() {
var xmlhttp = new XMLHttpRequest();
xmlhttp.onreadystatechange = function() {
if (xmlhttp.readyState == XMLHttpRequest.DONE) { // XMLHttpRequest.DONE == 4
if (xmlhttp.status == 200) {
document.getElementById("stat_content").innerHTML = xmlhttp.responseText;
}
else if (xmlhttp.status == 400) {
alert('There was an error 400');
}
else {
alert('something else other than 200 was returned');
}
}
};
xmlhttp.open("GET", "/stat/", true);
xmlhttp.send();
}
</script>
to update the content of that div, i think (based on your logic) you need to perform an ajax call to your stat function with the two parameters a and b submitted via POST request:
<form class="form-stat needs-validation" novalidate role="form">
<div class="form-group">
<input type="text" class="form-control" name="a" value="">
<div class="invalid-feedback"></div>
</div>
<div class="form-group">
<input type="text" class="form-control" name="b" value="">
<div class="invalid-feedback"></div>
</div>
<button type="submit" id="btn1" class="btn btn-primary btn-sm">check stat</button>
</form>
<div id="stat_content">Output: ?</div>
put the javascript code below after jquery call
<script>
$(document).ready(function() {
"use strict";
$('.form-stat').submit(function(e) {
e.preventDefault();
$.ajax({
url: "{{ url_for('stat') }}",
type: 'POST',
cache: false,
dataType: 'json',
data: $('.form-stat').serialize(),
success: function(data) {
// console.log(data);
$('.form-stat input[name=a]').val(''); // reset field
$('.form-stat input[name=b]').val(''); // reset field
$('#stat_content').html(data); // update div with the returned vlue
}
});
});
});
</script>
and you have to make little change to your stat function so you can submit dynamically the two parameters via POST like so :
from flask import Flask, request, make_response
import json
#app.route('/stat', methods=['POST'])
def stat():
if request.method == 'POST':
a = request.form['a']
b = request.form['b']
# check if inputs are valid to work with ..
res = str(a) + ' is not ' + str(b) if a != b else str(a) + ' and ' + str(b) + ' are equal.'
resp = make_response(json.dumps(res))
resp.status_code = 200
return resp
I'm new in Flask and I try to upload images using ajax. I still got ImmutableMultiDict([]) from request.files even if I add the name form my input file. I tried many solutions but no one worked for me.
**js-ajax **
$(document).ready(function () {
//alert('ya allah');
$('#upload-file').on('submit', function (event) {
var formDataRaw = $('#upload-file')[0];
var form_data = new FormData(formDataRaw);
$.ajax({
data: {
normal: +'',
anormal: +'',
r: +'',
form_data
},
type: 'POST',
url: '/process',
contentType: false,
cache: false,
processData: false,
async: false
})
.done(function (data) {#....some code
});
event.preventDefault();
});
});
I add the name in the input file also.
html side
<form id="upload-file" method="POST" enctype=multipart/form-data>
<fieldset style="border: none">
<div class="mt-2">
<label class="file btn btn-outline-gs m-2 my-sm-0 px-4 d_upload">
Upload IMG!
<input type="file"
id="imgInp"
name="photo"
class="i_upload"
hidden/>
</label>
</div>
</fieldset>
<fieldset style="border: none">
<div class="mb-2">
<input id="test"
type="submit"
value="Predect"
class="btn btn-outline-gs"
onclick="load(this)"/>
</div>
</fieldset>
</form>
and I think the code is clean but still got ImmutableMultiDict([]) from request.files, or just those brackets with request.files['input name']:
if 'photo' in request.files:
photo = request.files['photo']
if photo.filename != '' and allowed_file(photo.filename):
photo.save(os.path.join('static/uploads', photo.filename))
print(photo.filename)
f=secure_filename(photo.filename)
The problem is in my jQuery (ajax) code, this one:
data: {
normal: +'',
anormal: +'',
r: +'',
form_data
},
I pass other attribute with form_data, and this is incorrect. It should be just like this:
data: form_data
and instead of this data.name it should be data['name'].
I have a Python function which returns different messages in different scenarios. I want to style different messages differently, but I don't know how to do it.
This is my function:
def checkans(request, spanish_id):
random_spanish_question = get_object_or_404(Spanish, pk=spanish_id)
query = request.GET.get('ans')
coreng = random_spanish_question.english_set.get()
if query == str(coreng):
message = {
'message' : "Correct!"
}
return JsonResponse(message)
else:
message = {
'message' : "Incorrect. The correct answer is " + str(coreng)
}
return JsonResponse(message)
This is the HTML page:
<div class="flexcontainer" style="justify-content: center;">
<div class="sectiontitle">Quiz time
</div>
<div class="question_card">
<div class="question_word">{{ random_spanish_question }}</div>
<div id="msg"></div>
<form action="/checkans/{{random_spanish_question.id}}/" method="get">{% csrf_token %}
<label for="ans">Answer:</label>
<input type="text" name="ans"autofocus autocomplete="off" id="ansfield"/>
<input type="submit" value="Submit"/ id="submitbtn">
</form>
<input type="submit" value="Skip"/>
<button onclick="location.reload();">Next</button>
</div>
</div>
And this is the JS and AJAX code:
$('form').on('submit', function(e){
e.preventDefault();
var form = $(this);
var url = form.attr('action');
$.ajax({
type: 'GET',
url: url,
data: form.serialize(),
success: function(data){
$("#msg").html(data.message);
}
});
disable();
})
function disable(e){
$('#submitbtn').prop('disabled', true);
$('#ansfield').prop('disabled', true)
}
For example, I want to make the "Correct!" message green, while if it returns "Incorrect...", I want it to be red, and underline the answer, "str(coreng)". Please tell me how I can do it. Thanks in advance!
def checkans(request, spanish_id):
random_spanish_question = get_object_or_404(Spanish, pk=spanish_id)
query = request.GET.get('ans')
coreng = random_spanish_question.english_set.get()
if query == str(coreng):
message = {
'message' : "<span class=\"result-correct\">Correct!</span>"
}
return JsonResponse(message)
else:
message = { =
'message' : "<span class=\"result-incorrect\">Incorrect. The correct answer is " + str(coreng)</span>
}
return JsonResponse(message)
where those classes are defined in css:
.result-correct{
color:#00aa00; // or any shade of green you like
}
.result-incorrect{
color:#aa0000; // or any shade of red you like
}