Flask: why isn't AJAX being called when form is submitted? - javascript

I'm making a web application with flask that takes a submitted value from a form and, sends it to a python function, and returns the response to html.
main.py:
app = Flask(__name__)
#app.route('/')
def index():
return render_template("index.html")
#app.route('/', methods=['POST'])
def search_form():
print(request.form)
x = request.form['searchinput']
a = Vbulletin(x)
#a.reg_ver()
def result_gen():
return a.reg_ver()
result_gen()
temp = []
for s in result_gen():
text = s
print(text)
I want to use ajax to send the form to flask. I know I can just use html to handle the form, but i want to figure out how to do it with ajax.
index.html:
<!DOCTYPE html>
<html>
<head>
<title>UserFind Home</title>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.0/jquery.min.js"></script>
<link rel="stylesheet" href="{{ url_for('static', filename='main.css') }}">
<script type="text/javascript" src="{{ url_for('static', filename='search.js') }}"></script>
</head>
<body>
<nav>
<ul id="navlist">
<h1>Userfind</h1>
<li><a class="btn" href="#home">Home</a></li>
<li><a class="btn" href="#contact">Contact</a></li>
<li><a class="btn" href="#about">About</a></li>
<form name=searchbar>
<ul id="navsearch">
<li class="search">
<input type="text" id="searchinput" name="searchinput" placeholder="Search for User here. Must be atleast 5 characters long.">
</li>
<li><button type="submit" class="btn-default">Submit</button></li>
</ul>
</form>
</ul>
</nav>
<p>{{ text }}</p>
<div class="footer">
<p>©2019 Userfind</p>
</div>
</body>
</html>
I know I can just add the method like:
<form method="POST" name=searchbar>
But im trying to learn how to do it with jquery/ajax.
search.js:
$(document).ready(function() {
$('form').on('submit', function(event) {
event.preventDefault();
$.ajax({
data : {
x : $('#searchinput').val(),
console.log(x)
},
type : 'POST',
url : '/'
.done(function(data) {
if (data.error) {
$('#errorAlert').text(data.error).show();
$('#successAlert').hide();
}
else {
$('#successAlert').text(data.x).show();
$('#errorAlert').hide();
}
});
});
});
I've tried several different ways but ajax is never call. When i inspect the html no ajax is present on the form either. It just sends a get request. So how can fix this so AJAX is called when I submit the form?

$('form').on('click', function(event) {
event.preventDefault();
$.ajax({
data: {
x: $('#searchinput').val()
},
type: 'POST',
url: '/',
success: function() {
if (data.error) {
$('#errorAlert').text(data.error).show();
$('#successAlert').hide();
} else {
$('#successAlert').text(data.x).show();
$('#errorAlert').hide();
}
}
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<!DOCTYPE html>
<html>
<head>
<title>UserFind Home</title>
<link rel="stylesheet" href="{{ url_for('static', filename='main.css') }}">
<script type="text/javascript" src="{{ url_for('static', filename='search.js') }}"></script>
</head>
<body>
<nav>
<ul id="navlist">
<h1>Userfind</h1>
<li><a class="btn" href="#home">Home</a></li>
<li><a class="btn" href="#contact">Contact</a></li>
<li><a class="btn" href="#about">About</a></li>
<form method="POST" name="searchbar">
<ul id="navsearch">
<li class="search">
<input type="text" id="searchinput" name="searchinput" placeholder="Search for User here. Must be atleast 5 characters long.">
</li>
<li><button type="button" class="btn-default">Submit</button></li>
</ul>
</form>
</ul>
</nav>
<p>{{ text }}</p>
<div class="footer">
<p>©2019 Userfind</p>
</div>
</body>
</html>

I had my code set up to click form instead of button.
I changed:
$('form').on('click', function(event)
to this:
$("#submit").click(function(e)
In flask I also had to change:
x = request.form['searchinput']
to:
x = request.form['id']
because that was what data was being passed to flask as.
In the end js looked like this:
$(document).ready(function(){
$("#submit").click(function(e){
e.preventDefault();
$.ajax({type: "POST",
url: "/",
data: { id: $("#searchinput").val()},
success:function(){
alert("POST was sent.");
}
})
});
});

Related

Can't get image upload to work with Flask and JQuery

The following code allows you to submit forms and return a variation of the text from Flask using AJAX and JQuery:
from flask import Flask, render_template, request, jsonify
app = Flask(__name__)
#app.route('/')
def index():
return render_template('form.html')
#app.route('/process', methods=['POST'])
def process():
email = request.form['email']
name = request.form['name']
if name and email:
newName = name[::-1]
return jsonify({'name' : newName})
return jsonify({'error' : 'Missing data!'})
if __name__ == '__main__':
app.run(debug=True)
<!DOCTYPE html>
<html>
<head>
<title>AJAX Example</title>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.0/jquery.min.js"></script>
<!-- Latest compiled and minified CSS -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" integrity="sha384-1q8mTJOASx8j1Au+a5WDVnPi2lkFfwwEAa8hDDdjZlpLegxhjVME1fgjWPGmkzs7" crossorigin="anonymous">
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js" integrity="sha384-0mSbJDEHialfmuBBQP6A4Qrprq5OVfW37PRR3j5ELqxss1yVqOtnepnHVP9aJ7xS" crossorigin="anonymous"></script>
<script src="{{ url_for('static', filename='js/form.js') }}"></script>
</head>
<body>
<div class="container">
<br><br><br><br>
<form class="form-inline">
<div class="form-group">
<label class="sr-only" for="emailInput">Email address</label>
<input type="email" class="form-control" id="emailInput" placeholder="Email">
</div>
<div class="form-group">
<label class="sr-only" for="nameInput">Name</label>
<input type="text" class="form-control" id="nameInput" placeholder="First Name">
</div>
<button type="submit" class="btn btn-default">Submit</button>
</form>
<br>
<div id="successAlert" class="alert alert-success" role="alert" style="display:none;"></div>
<div id="errorAlert" class="alert alert-danger" role="alert" style="display:none;"></div>
</div>
</body>
</html>
$(document).ready(function() {
$('form').on('submit', function(event) {
$.ajax({
data : {
name : $('#nameInput').val(),
email : $('#emailInput').val()
},
type : 'POST',
url : '/process'
})
.done(function(data) {
if (data.error) {
$('#errorAlert').text(data.error).show();
$('#successAlert').hide();
}
else {
$('#successAlert').text(data.name).show();
$('#errorAlert').hide();
}
});
event.preventDefault();
});
});
But when I slightly modify the code to do the same thing with a uploaded file's name it doesn't work. All I have done is changed the type of form so that it takes in files and then made it so that it reverses the filename rather than the inputted text from the previous version. Do you know what I am doing wrong here?
from flask import Flask, render_template, request, jsonify
app = Flask(__name__)
#app.route('/')
def index():
return render_template('form.html')
#app.route('/process', methods=['POST'])
def process():
filename = request.files['file'].filename
if filename:
newName = filename[::-1]
return jsonify({'name' : newName})
return jsonify({'error' : 'Missing data!'})
if __name__ == '__main__':
app.run(debug=True)
<!DOCTYPE html>
<html>
<head>
<title>AJAX Example</title>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.0/jquery.min.js"></script>
<!-- Latest compiled and minified CSS -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" integrity="sha384-1q8mTJOASx8j1Au+a5WDVnPi2lkFfwwEAa8hDDdjZlpLegxhjVME1fgjWPGmkzs7" crossorigin="anonymous">
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js" integrity="sha384-0mSbJDEHialfmuBBQP6A4Qrprq5OVfW37PRR3j5ELqxss1yVqOtnepnHVP9aJ7xS" crossorigin="anonymous"></script>
<script src="{{ url_for('static', filename='js/form.js') }}"></script>
</head>
<body>
<div class="container">
<br><br><br><br>
<form method="POST" action='/process' enctype="multipart/form-data">
<div>
<label for="file">Choose file to upload</label>
<input type="file" id="file" name="file">
</div>
<div>
<button type="submit" class="btn btn-default">Submit</button>
</div>
</form>
<br>
<div id="successAlert" class="alert alert-success" role="alert" style="display:none;"></div>
<div id="errorAlert" class="alert alert-danger" role="alert" style="display:none;"></div>
</div>
</body>
</html>
$(document).ready(function() {
$('form').on('submit', function(event) {
$.ajax({
data : {
file : $('#file')
},
type : 'POST',
url : '/process'
})
.done(function(data) {
if (data.error) {
$('#errorAlert').text(data.error).show();
$('#successAlert').hide();
}
else {
$('#successAlert').text(data.name).show();
$('#errorAlert').hide();
}
});
event.preventDefault();
});
});
If you use an object of the type FormData to serialize and transfer the data of the form it should work.
$(document).ready(function() {
$('form').submit(function(event) {
let formData = new FormData(event.target);
$.ajax({
data: formData,
type : 'POST',
url : '/process',
contentType: false,
processData: false
})
.done(function(data) {
if (data.error) {
$('#errorAlert').text(data.error).show();
$('#successAlert').hide();
} else {
$('#successAlert').text(data.name).show();
$('#errorAlert').hide();
}
});
event.preventDefault();
});
});

User Frontend Selection That Loads Images From Database With Django

I have a drop down bar with a multi selection tool. A user picks from titles of graphs stored in a model for the graphs they want to display. How can I use those selections to display these graphs? I am using Ajax to send the data to the backend. From that data I created a new context_dict full of the model objects we want displayed. I want to either display in the same template or link to another template that can use this context dict. I do not know the best way to do this. Here is some of my code below.
Models:
from django.db import models
class ChartPrac(models.Model):
title = models.CharField(max_length=256)
chart = models.ImageField()
def __str__(self):
return self.title
Views:
def querier(request):
if request.method == 'POST':
options_arr = request.POST.get('optionsArr')
options = options_arr.split(':')
options = options[1:]
print(options)
context_arr = []
context_graphs = {}
i = 0
for elements in options:
charts_to_display = ChartPrac.objects.get(title=elements)
context_arr.append(charts_to_display)
i += 1
context_graphs['titles'] = context_arr
return HttpResponse(options_arr)
else:
graph_titles = ChartPrac.objects.all()
context_dict = {'titles': graph_titles}
print(context_dict)
print(type(context_dict['titles']))
return render(request, 'graph_querier/base.html', context=context_dict)
Urls:
from django.urls import path
from graph_querier import views
app_name = 'graph_querier'
urlpatterns = [
path('', views.index, name='index'),
path('querier/', views.querier, name='querier'),
# path('graph/', views.graph, name='graph'),
]
Template:
<!DOCTYPE html>
{% load static %}
<html lang="en" dir="ltr">
<head>
<meta charset="UTF-8">
<title>Marketing Querier</title>
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/css/bootstrap.min.css" integrity="sha384-9aIt2nRpC12Uk9gS9baDl411NQApFmC26EwAOH8WgZl5MYYxFfc+NcPb1dKGj7Sk" crossorigin="anonymous">
<link rel="stylesheet" href="https://res.cloudinary.com/dxfq3iotg/raw/upload/v1569006288/BBBootstrap/choices.min.css?version=7.0.0">
<script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script>
<script src="https://res.cloudinary.com/dxfq3iotg/raw/upload/v1569006273/BBBootstrap/choices.min.js?version=7.0.0"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<link rel="stylesheet" href="{% static 'graph_querier\querier.css' %}">
</head>
<body>
<nav class="navbar navbar-expand-lg navbar-dark" style="background-color: rgba(0,96,155,255)";>
<div class="collapse navbar-collapse" id="navbarNav">
<ul class="navbar-nav">
<li class="nav-item">
<a class="nav-link" href="{% url 'main_dash:main_dash' %}">Main Dashboard</a>
</li>
<li class="nav-item">
<a class="nav-link" href="">Marketing Dashboard</a>
</li>
<li class="nav-item">
<a class="nav-link" href="">Sales Dashboard</a>
</li>
<li class="nav-item">
<a class="nav-link" href="">Input</a>
</li>
<li class="nav-item">
<a class="nav-link" href="">Input</a>
</li>
<li class="nav-item">
<a class="nav-link" href="">Input</a>
</li>
</ul>
</div>
</nav>
<div id="title">
<h1 id="graph-querier-text">Graph Querier</h1>
</div>
<div class="row d-flex justify-content-center mt-100" id='search'>
<div class="col-md-6"> <select class="select-option" id="choices-multiple-remove-button" placeholder="Select up to 10 Graphs" multiple>
{% for graphs in titles %}
<option class="option-rend" value={{ graphs.title }}>{{ graphs.title }}</option>
{% endfor %}
</select> </div>
</div>
<script>
$(document).ready(function(){
var multipleCancelButton = new Choices('#choices-multiple-remove-button', {
removeItemButton: true,
maxItemCount:10,
searchResultLimit:1000,
renderChoiceLimit:1000
});
});
</script>
<script src="{% static '\graph_querier\javascript\base.js' %}"></script>
<div id='render-graphs'>
<button type="button" class="btn btn-primary btn-lg" onclick='rendGraphs();'>Render Graphs</button>
{% csrf_token %}
</div>
</body>
</html>
JS:
function rendGraphs(){
var select = document.getElementById('choices-multiple-remove-button');
var csrf = $("input[name=csrfmiddlewaretoken]").val();
var optionsArr = [];
for (var x = 0; x < select.length; x++){
var temp = select.options[x].text;
optionsArr.push(temp);
}
var stringOptions = ''
for (var i= 0; i < optionsArr.length; i++){
var stringOptions = stringOptions.concat(":" + String(optionsArr[i]));
}
$.ajax({
url: '/query/querier/',
type: 'POST',
data: {'optionsArr': stringOptions,
'csrfmiddlewaretoken': csrf
}
}).done(function(response){
console.log(response)
});
}

Generate and render a Flask template when Bootstrap tab is changed

I have a Flask setup serving a template. The data for this can be nicely split across a few different "sets" which can all be rendered with the same template. I have inserted Bootstrap tabs which I would like to handle displaying the data for each separate set. The data my be non-existent or incomplete initially, but will be filled in over time. The hope is that when the user clicks a new Bootstrap tab, it triggers a request for Flask to return the most recent data pertaining to whichever tab was selected.
I have boiled it down to the small example below. I can successfully generate the Flask request when the tab is changed, but the result isn't triggering a new rendering of the template.
Flask route:
#app.route('/test_route', methods=['GET'])
def get_simple():
set_number_str = request.args.get('set', "mydata-1", type=str)
set_number = int(set_number_str.split('-')[-1])
ready = bool(random.getrandbits(1))
if ready:
# get_data_for_set(set_number)
return render_template('simple_template.html',valid=1, data_set=set_number, data_points=[1,2,3])
else:
return render_template('simple_template.html', valid=0, data_set=set_number, data_points=[0, 0, 0])
Html:
<html>
<head>
<link href="{{url_for('static', filename='js/bootstrap-3.3.7-dist/css/bootstrap.min.css')}}" rel="stylesheet" type="text/css" />
<script type="text/javascript" src="{{url_for('static', filename='js/jquery-3.3.1.min.js')}}"></script>
<script type="text/javascript" src="{{url_for('static', filename='js/bootstrap-3.3.7-dist/js/bootstrap.min.js')}}"></script>
</head>
<body>
<div class="my-tabs">
<ul class="nav nav-tabs" id="set-tabs">
<li class="active" id="data-1">
Set 1
</li>
<li class="" id="data-2">
Set 2
</li>
</ul>
<div id="my-tab-content" class="tab-content">
<div class="tab-pane" id="mydata-1">
<p>Placeholder 1</p>
</div>
<div class="tab-pane" id="mydata-2">
<p>Placeholder 2</p>
</div>
</div>
</div>
<script type="text/javascript">
if ({{valid}} == 0) {
$('#mydata'+'{{data_set}}').html("Waiting on scenario to start...");
} else {
$('#mydata'+'{{data_set}}').html("Have some data: " + "{{data_points}}");
}
</script>
<script type="text/javascript">
$('a[data-toggle="tab"]').on('shown.bs.tab', function (e) {
var set_id = $(e.target).attr("href");
$.ajax({
url: "/test_route",
type: "get",
data: {set: set_id},
success: function(response) {
$('#mydata-'+set_id).replaceWith(response);
},
error: function(xhr) {
console.log(xhr)
}
});
return false;
});
</script>
When I run, the only thing I see is the "Placeholder _" text.
Is this a limitation of Flask/Jinja2 templating or something I'm doing wrong? If it's the former, do you have any alternative approaches you would recommend? My key constraint is needing to re-retrieve the data from the server each time as it will change.

Angular js http get return all page

Why console.log(response.data); in http get, returns html of all page, but not the value of returnUrl('Home/Index').
I think that the problem is in await SignInAsync(user, model.RememberMe);.
Controller:
[HttpGet]
[AllowAnonymous]
public async Task<JsonResult> Login(string UserName, string Password, bool RememberMe, string returnUrl)
{
LoginViewModel model = new LoginViewModel();
model.Password = Password;
model.UserName = UserName;
model.RememberMe = RememberMe;
if (ModelState.IsValid)
{
var user = await UserManager.FindAsync(model.UserName, model.Password); if (user != null)
{
if (user.ConfirmedEmail == true)
{
await SignInAsync(user, model.RememberMe);
return Json(returnUrl, JsonRequestBehavior.AllowGet);
}
else
{
ModelState.AddModelError("", "Confirm Email Address.");
}
}
else
{
ModelState.AddModelError("", "Invalid username or password.");
}
}
// If we got this far, something failed, redisplay form
return Json(returnUrl, JsonRequestBehavior.AllowGet);
}
AngularJS:
$scope.answer = function (answer) {
$scope.returnUrl = '/Home/Index';
$http({
method: 'GET',
url: '/Account/Login',
params: {
UserName: $scope.model.UserName,
Password: $scope.model.Password,
RememberMe: $scope.model.RememberMe,
returnUrl: $scope.returnUrl
}
}).then(function (response) {
console.log(response.data);
}, function () {
console.log("Error occured");
});
html response
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>About - My ASP.NET Application</title>
<link href="/Content/site.css" rel="stylesheet"/>
<script src="/Scripts/modernizr-2.6.2.js"></script>
<script src="/Scripts/angular.js"></script>
<script src="/Scripts/Custom/Login.js"></script>
<script src="/Scripts/angular-material/angular-material.js"></script>
<script src="/Scripts/angular-animate/angular-animate.js"></script>
<script src="/Scripts/angular-aria/angular-aria.js"></script>
<script src="/Scripts/angular-messages.js"></script>
<script src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/t-114/svg-assets-cache.js"></script>
<link href="https://cdn.gitcdn.link/cdn/angular/bower-material/v1.0.8/angular-material.css" rel="stylesheet" />
<link href="https://material.angularjs.org/1.0.8/docs.css" rel="stylesheet" />
<link href="/Content/bootstrap.min.css" rel="stylesheet" />
</head>
<body>
<div class="navbar navbar-inverse navbar-fixed-top">
<div class="container">
<div class="navbar-header">
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse">
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="/">Application name</a>
</div>
<div class="navbar-collapse collapse">
<ul class="nav navbar-nav">
<li>Home</li>
<li>About</li>
<li>Contact</li>
<li><div ng-app="LoginApp" ng-controller="LoginCtrl"><input type="button" value="Login" ng-click="showAdvanced($event)" /></div></li>
</ul>
<form action="/Account/LogOff" class="navbar-right" id="logoutForm" method="post"><input name="__RequestVerificationToken" type="hidden" value="78GcsaZMHozpxPWZojKt_U4oOlCC91bdiNLnrM9bnGkHAwTdludG--qpyQSGXaurmBHnyYUiIlGpNsGfkskwnMHyc_BozsM2pdl4IWBoWos27DcNf3c57PLPRcmNBm-INZRgLICtO1PG4DcOWJRm6yj6Sr_kSDElCuPf-H8AD2BACTChafGXEic38UObx3PdnTDg-C6Iah7AyhjZvagKlw2" /> <ul class="nav navbar-nav navbar-right">
<li>
Hello Anton!
</li>
<li>Log off</li>
</ul>
</form>
</div>
</div>
</div>
<div class="container body-content">
<h2>About</h2>
<hr />
<footer>
<p>© 2016 - My ASP.NET Application</p>
</footer>
</div>
<script src="/Scripts/jquery-1.9.1.js"></script>
<script src="/bundles/bootstrap"></script>
</body>
</html>
Based on your code,
If login success it will return a json with returnUrl.
But if login fail it will return an html document with error messages.
So the reason you are getting back HTML is because you probably have error in login process.

Ajax call to Django function

I'm trying to delete a list of images selected via checkbox via Ajax, which have been uploaded via Django Ajax Uploader. I've successfully obtained a list of the images but I'm not sure how to pass it Django function via Ajax. Can anyone please advise on:
How can I pass the list of selected images to a Django function to delete the images?
How should I handle the CSRF for the ajax portion?
html
<!DOCTYPE html>{% load static from staticfiles %} {% load i18n %}
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>Demo</title>
<script src="{% static 'js/jquery.min.js' %}"></script>
<!-- Latest compiled and minified JavaScript -->
<script src="http://netdna.bootstrapcdn.com/bootstrap/3.1.1/js/bootstrap.min.js"></script>
<!-- Latest compiled and minified CSS -->
<link rel="stylesheet" href="http://netdna.bootstrapcdn.com/bootstrap/3.1.1/css/bootstrap.min.css" />
<!-- Optional theme -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.1/css/bootstrap-theme.min.css">
<style>
input.chk {
margin-left: 70px;
}
</style>
</head>
<body>
<div class="wrapper">
<div id="content" class="clearfix container">
{% load i18n crispy_forms_tags %}
<form method="post" action="." enctype="multipart/form-data">
{% csrf_token %} {% crispy form %} {% crispy formset formset.form.helper %}
<div class="image-upload-widget">
<div class="preview">
</div>
<div class="file-uploader">
<noscript>
<p>{% trans "Please enable JavaScript to use file uploader." %}</p>
</noscript>
</div>
<p class="help_text" class="help-block">
{% trans "Available file formats are JPG, GIF and PNG." %}
</p>
<div class="messages"></div>
</div>
<input type="submit" name="save" class="btn btn-primary pull-right" value="Submit">
<input type="button" id="delete" class="btn btn-primary pull-left" value="Delete Selected Files">
</form>
</div>
</div>
<script src="{% static 'js/fileuploader.js' %}"></script>
<link href="{% static 'css/fileuploader.css' %}" media="screen" rel="stylesheet" type="text/css" />
<script>
$(function() {
var uploader = new qq.FileUploader({
action: "{% url 'planner:ajax_uploader' %}",
element: $('.file-uploader')[0],
multiple: true,
onComplete: function(id, fileName, responseJSON) {
if (responseJSON.success) {
url = '<label for="' + fileName + '"><img src="' + {{MEDIA_URL}} + responseJSON.url + '" alt="" /></label>';
checkbox = '<p><input type="checkbox" class="chk" id="' + fileName + '" name="' + fileName + '" value="0" /></p>';
$('.preview').append(url);
$('.preview').append(checkbox);
} else {
alert("upload failed!");
}
},
onAllComplete: function(uploads) {
// uploads is an array of maps
// the maps look like this: {file: FileObject, response: JSONServerResponse}
alert("All complete!");
alert(checkbox);
},
params: {
'csrf_token': '{{ csrf_token }}',
'csrf_name': 'csrfmiddlewaretoken',
'csrf_xname': 'X-CSRFToken',
},
});
});
</script>
<script>
$("#delete").on('click', function() {
var allVals = [];
$(":checkbox").each(function() {
var ischecked = $(this).is(":checked");
if (ischecked) {
allVals.push(this.id);
}
});
});
</script>
</body>
</html>
Once you got the list of images to delete, you pass it on to an Ajax call that will be handled by a Django view, like so:
function submitData(data) {
var csrftoken = getCookie('csrftoken'); // from https://docs.djangoproject.com/en/1.7/ref/contrib/csrf/#ajax
$.ajax({
type: 'POST',
beforeSend: function(xhr, settings) {
if (!csrfSafeMethod(settings.type) && !this.crossDomain) {
xhr.setRequestHeader("X-CSRFToken", csrftoken);
}
},
data: JSON.stringify(data),
url: {% url 'image_handler' %}
}).done(function(data) {
console.log(data.deleted + ' images were deleted');
}).error(function(data) {
console.log('errors happened: ' + data);
});
}
Then, in your views.py:
def image_handler(request):
if request.method != 'POST':
return HttpResponseNotAllowed(['POST'])
str_body = request.body.decode('utf-8')
changes = json.loads(str_body)
for change in changes:
pass # `change` contains the id of the image to delete
data = {'status': 200,
'deleted': len(changes)}
return JsonResponse(data)
It works pretty nicely :)

Categories

Resources