Using Ajax and Django conditions to display an html variable - ajax

I'm new to using Ajax calls with Django. Im trying to implement a simple Display or not display depending on the type of get called by Ajax:
Views:
def dynamic(request):
context = {}
if request.method == 'GET':
if 'backtest_type' in request.GET:
context['display_details'] = False
print ('Im not displaying')
elif 'change_val' in request.GET:
context['display_details'] = True
print ('Im displaying')
else:
context['display_details'] = False
return render(request, "demo/dynamic.html", context)
In my template:
{% extends 'demo/base.html' %}
{% block body %}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
<link rel="stylesheet" href="{% static 'css/dynamic.css' %}">
<script>
$(document).on('click','#id_backtest_type', function () {
console.log( $(this).val() );
$.ajax({
type: 'get',
data: {'backtest_type': 1},
success: function (data) {
console.log('data sent ' + data);
},
failure: function(data) {
alert('Got an error dude');
}
});
});
$(document).on('click','#btnClick', function () {
// console.log( $(this).val() );
$.ajax({
type: 'get',
data: {'change_val': 1},
success: function (data) {
console.log('data sent ' + data);
failure: function(data) {
alert('Got an error dude');
}
});
});
</script>
<div>
{% if display_details %}
<h1>I'm diplaying</h1>
{% endif %}
</div>
<div id="btnClick" class="col-sm-4">
<div class="btn-group btn-group-justified" role="group">
<div class="btn-group" role="group">
<button class="btn btn-secondary" type="button">Don't Display</button>
</div>
</div>
</div>
<div id="id_backtest_type" class="col-sm-4">
<div class="btn-group btn-group-justified" role="group">
<div class="btn-group" role="group">
<button class="btn btn-secondary" type="button">Display!</button>
</div>
</div>
</div>
{% endblock %}
From the console I'm sure that the get requests are being correctly sent using ajax (the get requests are being sent and the console prints the statements:
[09/Feb/2019 20:00:56] "GET /dynamic/?backtest_type=1 HTTP/1.1" 200
6530
Im displaying
However, even if the ajax call works correctly, the template doesn't end up rendering <h1>I'm diplaying</h1>. Am I misunderstanding anything about Ajax?
Thanks in advance!

Related

Django Python can not upload directory with large quantity of files

I am trying to upload a directory with large number of dicom files using Django and JQuery ajax. Each file size is not more than 600kb. I can upload 200 files at a time. If I increase the number of files (tried to upload 14000 files), it doesn’t work. The site gets stuck and it’s not showing any error. Can anyone please help me with this problem? I have attached my code below. Thanks in advance.
View.py:
def handle_uploaded_file(f,filePath):
with open(filePath+'/'+f.name, 'wb+') as destination:
for chunk in f.chunks():
destination.write(chunk)
def UploadScanView(request):
if request.method == 'POST':
form = create_scan_form(request.POST)
if form.is_valid():
scan = form.save(commit=False)
scan.project_id = form.cleaned_data.get('project_id')
directory_name = request.POST.get('directories')
json_to_dictionary = json.loads(directory_name)
print(json_to_dictionary)
for upload_file in request.FILES.getlist('file'):
file_path = settings.MEDIA_ROOT+'/'+os.path.dirname(json_to_dictionary[upload_file.name])
print(file_path)
if os.path.exists(file_path):
handle_uploaded_file(upload_file, file_path)
else:
os.makedirs(file_path)
handle_uploaded_file(upload_file,file_path)
return render(request, 'fileupload/basic_upload/scan_upload.html', {'form': form})
else:
form = create_scan_form()
return render(request, 'fileupload/basic_upload/scan_upload.html', {'form': form})
HTML and JQuery:
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.2/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery-cookie/1.4.1/jquery.cookie.min.js"></script>
<script>
/*fileupload div*/
$(document).ready(function(){
$("#my-file").on('change',function(e){ //submit(function(e){
$("#file-wrap p").text('Now click on Upload button');
});
$("#my-form").on('submit',function(e){ //submit(function(e){
files = document.querySelector("#my-file").files;
var directories = {}
for (var file of files) {
file.webkitRelativePath
directories[file.name] = file.webkitRelativePath
}
directories = JSON.stringify(directories);
document.querySelector("#directories").value = directories
var eventType = $(this).attr("method"); // get method type for #my-form
var eventLink = $(this).attr("action"); // get action link for #my-form
//alert(directories);
//////
var formData = new FormData(this);
formData.append('csrfmiddlewaretoken', '{{ csrf_token }}');
$.ajax({
headers: { "X-CSRFToken": '{{ csrf_token }}' },
type: eventType,
url: eventLink,
//data: new FormData(this), // IMPORTANt
data: formData,
cache: false,
contentType: false,
processData: false,
// this part is progress bar
xhr: function () {
var xhr = new window.XMLHttpRequest();
xhr.upload.addEventListener("progress", function (e) {
if (e.lengthComputable) {
var percentComplete = e.loaded / e.total;
percentComplete = parseInt(percentComplete * 100);
$('.myprogress').text(percentComplete + '%');
$('.myprogress').css('width', percentComplete + '%');
}
}, false);
return xhr;
},
success: function(getResult) {
$('#my-form')[0].reset(); // reset form
$("#file-wrap p").html('Drag and drop file here'); // change wrap message
}
});
e.preventDefault();
});
});
/*fileupload div*/
</script>
<form id="my-form" method="POST" action="{% url 'fileupload:upload_scan' %}" enctype="multipart/form-data"> <!--independentSub-->
{% csrf_token %}
<div id="user_form" class="container">
<div class="form-group col-sm-4" id="project_id">
{{ form.project_id|as_crispy_field }}
</div>
<!--fileupload div-->
<div id="independentSubDiv" class="row">
<div id="file-wrap" class="form-group col-sm-6" >
<p>Drag and drop file here</p>
<input id="my-file" type="file" name="file" multiple webkitdirectory directory draggable="true">
<input type="text" id="directories" name="directories" hidden />
</div>
</div>
<div style="padding-left: initial" id="independentSubDiv" class="form-group col-sm-7" >
<button type="submit" class="btn btn-primary btn-lg btn-block" name="submit_btn" id="submit_btn">Submit</button>
</div>
<div class="progress form-group col-sm-7" style="padding-left: initial" id="progressDiv" >
<div class="progress-bar progress-bar-success myprogress " role="progressbar">0%</div>
</div>
</div>
</form>

Using ng-repeat after $http call

I'm learning Angular (1.6.6), so I'm hoping/assuming I'm missing something basic.
I'm populating a drop-down menu on ng-init, which is working as expected. I'm returning JSON from the DB, and console.log() shows me that the JSON is pulling through as expected.
I'm stuck with ng-repeat, trying to display the data in another div.
My Controller
app.controller('RandomTownCtrl', [
'$scope',
'$http',
function($scope, $http){
window.MY_SCOPE = $scope;
$scope.getAllRegions = function() {
$http({
method: 'GET',
url: '/all-regions'
}).then(function successCallback(response) {
$scope.regions = response.data;
}, function errorCallback(response) {
console.log('error');
});
};
$scope.getRandomTown = function() {
var guidEntity = $scope.guidEntity;
if (typeof guidEntity === 'undefined') { return };
$http({
method: 'GET',
url: '/region-name?region-guid=' + guidEntity
}).then(function successCallback(response) {
$scope.randomTown = response.data;
console.log($scope.randomTown);
}, function errorCallback(response) {
});
};
}
]);
The Markup
<div class="column col-sm-5 content-column">
<form ng-controller= "RandomTownCtrl" ng-init="getAllRegions()" ng-submit="getRandomTown()">
<h3>Generate Random Town</h3>
<div class="form-group">
<select name="nameEntity"
ng-model="guidEntity"
ng-options="item.guidEntity as item.nameEntity for item in regions">
<option value="" ng-if="!guidEntity">Choose Region</option>
</select>
</div>
<button type="submit" class="btn btn-primary">Generate!</button>
</form>
</div>
<div class="column col-sm-5 content-column" id="output-column">
<div class="header">
<h4>Region Name:</h4>
</div>
<div ng-controller='RandomTownCtrl'>
<p ng-repeat="item in randomTown">
{{ item.name_region }}
</p>
</div>
</div>
You are mixing $scope and self together, you need also ng-repeat needs an array not an object.
$scope.randomTown = response.data;
Beginner Angular mistake: I didn't understand that the ng-controller directive created an isolate scope, and the output I was expecting wasn't happening because the data simply wasn't there in that scope.

Why ajax put FormData into request.data instead of request.files?

Flask, and I want to upload an image file through an AJAX call in HTML.
I wrote this Javascript:
function mysubmit(input){
var file_input = document.getElementById('file-input-left');
var form_data = new FormData();
var file = file_input.files[0];
alert(file);
form_data.append('file', file);
$.ajax({
type: 'POST',
url: '/calc_full_result',
data: form_data,
contentType: false,
cache: false,
processData: false,
async: false,
success: function(data){
alert('Success!');
},
});
}
And the HTML:
<div class="image-holder">
<form action="/calc_full_result" id="upload-form-left" name="form-left" method=post enctype=multipart/form-data>
<div class="image-holder-left">
<div class="image-upload">
{% if img_left %}
<label id="upload-left-label" for="file-input-left"><img id="left-image" src="data:image/png;base64, {{img_left}}"/></label>
{% else %}
<label id="upload-left-label" for="file-input-left"><img id="left-image" src="{{url_for('static', filename='upload_fill.png')}}" /></label>
{% endif %}
<input id="file-input-left" type=file name=file onchange="mysubmit(this)"/>
</div>
</div>
<form action="/calc_full_result" id="upload-form-right" name="form-right" method=post enctype=multipart/form-data>
<div class="image-holder-right">
<div class="image-upload">
{% if img_right %}
<label id="upload-right-label" for="file-input-right"><img id="right-image" src="data:image/png;base64, {{img_right}}"/></label>
{% else %}
<label id="upload-right-label" for="file-input-right"><img id="right-image" src="{{url_for('static', filename='upload_fill.png')}}"/></label>
{% endif %}
<input id="file-input-right" type=file name=file onchange="mysubmit(this)"/>
</div>
</div>
</form>
</div>
Then in app.py:
#app.route('/calc_full_result', methods=['POST'])
def calc_full_result():
if request.method == 'POST':
file = request.files['file']
return jsonify(result="suc")
But I cannot get the object file, it's always empty and cannot be saved. When I check the request I can see len(request.data) is almost the size of image file.
I wonder why request.files is empty and how to save the file in request.data? Is it possible?
Try:
data: new FormData(document.getElementById('upload-form-left'))

Laravel Image Upload using ajax 500 Internal Server Error

I am trying to upload image using ajax in laravel 5.2.but still i am getting error 500 Internal Server Error in route.
when i am trying to upload image using ajax request the browser shown correct route path but still i am not getting reason why it still showing error to me.
HTML
<!-- CHANGE AVATAR TAB -->
<div class="tab-pane" id="tab_1_2">
<div class="uploadimagediv"></div>
{{ Form::open(array('url' => 'admin/avatar','method'=>'post','files'=>'true','id'=>'updateprofileimage')) }}
<div class="form-group">
<div class="fileinput fileinput-new" data-provides="fileinput">
<div class="fileinput-new thumbnail" style="width: 200px; height: 150px;">
<img src="http://www.placehold.it/200x150/EFEFEF/AAAAAA&text=no+image" alt=""/>
</div>
<div class="fileinput-preview fileinput-exists thumbnail" style="max-width: 200px; max-height: 150px;">
</div>
<div>
<span class="btn default btn-file">
<span class="fileinput-new">
Select image </span>
<span class="fileinput-exists">
Change </span>
<p class="text-danger" id="error_image"></p>
<input type="file" id="picture" name="picture"/>
{{--{{ Form::file('picture') }}--}}
</span>
<span class="error alert-danger">{{ $errors->first('picture') }}</span>
<a href="javascript:;" class="btn default fileinput-exists" data-dismiss="fileinput">
Remove </a>
</div>
</div>
<div class="clearfix margin-top-10">
</div>
</div>
<div class="margin-top-10">
{{Form::hidden('id', 2, ["id"=>"id"])}}
{{ Form::button('Upload',['id'=> 'updatepicture','class'=>'btn green-haze']) }}
{{--{{ Form::submit('Submit',['class' => 'btn green-haze','name'=>'changeImage']) }}--}}
<a href="javascript:;" class="btn default">
Cancel </a>
</div>
{{ Form::close() }}
</div>
<!-- END CHANGE AVATAR TAB -->
Route
Route::group(['prefix' => 'admin'], function ()
{
Route::controller('/','DashboardController');
});
Ajax
$(document).on('click', '#updatepicture', function($e)
{
$e.preventDefault();
// send an ajax request
$("#error_image").empty();
$.ajax(
{
url: 'avatar',
processData: false,
contentType: false,
type: "post",//use for update
data: new FormData($("#updateprofileimage")[0]),
success: function(data)
{
if(data.status)
{
$("#uploadimagediv").html('<div class="alert alert-success"><button type="button" class="close">×</button>'+data.message+'</div>');
window.setTimeout(function()
{
$(".alert").fadeTo(500, 0).slideUp(500, function()
{
$(this).remove();
});
}, 5000);
$('.alert .close').on("click", function(e)
{
$(this).parent().fadeTo(500, 0).slideUp(500);
});
//console.log(data);
//$("#updateprofileimage")[0].reset();
//window.location.href = "http://localhost/laravel/admin/profile";
}
else
{
errors = data.errors;
for(error in errors)
{
$("#error_"+error.title).html(error.message);
}
}
},
error: function(xhr)
{
if(xhr.status == 422)
{
errors = xhr.responseJSON;
for(error in errors)
{
$("#error_"+error).html(errors[error][0]);
}
}
}
});
});
Error is :"NetworkError: 500 Internal Server Error - http://localhost/laravel/admin/avatar"
please suggest me where i am getting wrong.
Controller is
public function postAvatar(ImageUploadRequest $request)
{
---
}
Add the below line inside <head>
<meta name="csrf-token" content="{{ csrf_token() }}">
And add the below lines before your ajax call in javascript function
$.ajaxSetup({
headers: {
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
}
});
And don't forget to give permission to your storage folder
sudo chmod -R 777 storage
In your ajax setup you have to provide x-csrf-token with the request. For your ajax request , also there is a problem with your url:
$(document).on('click', '#updatepicture', function($e)
{
$e.preventDefault();
// send an ajax request
$("#error_image").empty();
$.ajax(
{
url: "{{url('avatar')}}",
processData: false,
contentType: false,
type: "post",//use for update
data: new FormData($("#updateprofileimage")[0]),
headers: {
'X-CSRF-TOKEN': "{{ csrf_token() }}"
},
success: function(data)
{
if(data.status)
{
$("#uploadimagediv").html('<div class="alert alert-success"><button type="button" class="close">×</button>'+data.message+'</div>');
window.setTimeout(function()
{
$(".alert").fadeTo(500, 0).slideUp(500, function()
{
$(this).remove();
});
}, 5000);
$('.alert .close').on("click", function(e)
{
$(this).parent().fadeTo(500, 0).slideUp(500);
});
//console.log(data);
//$("#updateprofileimage")[0].reset();
//window.location.href = "http://localhost/laravel/admin/profile";
}
else
{
errors = data.errors;
for(error in errors)
{
$("#error_"+error.title).html(error.message);
}
}
},
error: function(xhr)
{
if(xhr.status == 422)
{
errors = xhr.responseJSON;
for(error in errors)
{
$("#error_"+error).html(errors[error][0]);
}
}
}
});
});

Confirm delete dialog using ajax and bootstrap

I'd like to display a confirm delete dialog using Bootstrap v3 before deleting an entity.
My code works fine, but without confirm dialog. How can I do that?
{% for travel in pagination %}
<div class="col-sm-6 col-md-4" id="item-{{ travel.id }}">
//......
<a title="delete" href data-entity-id="{{ travel.id }}" class="button btn-mini red remove_item">Delete</a>
</div>
{% endfor %}
<script>
$(document).ready(function () {
$(".remove_item").click(function () {
var entityId = $(this).attr('data-entity-id');
var itemId = 'item-' + entityId;
$.ajax({
type: 'POST',
dataType: 'json',
url: Routing.generate('travel_delete', {'id': entityId}),
success: function () {
//hide the block of item after delete success
$('#' + itemId).fadeOut();
}
});
return false;
});
});
</script>
Edited
I tried this code. I'd like when clicking on delete link, pass the value of attr entity-id which is in the delete link, to the attr data-entity-id in delete button in the modal. How can I do that ?
error console:
Failed to load resource: the server responded with a status of 404 (Not Found)
<a title="delete" href data-toggle="modal" data-target="#myModal" entity-id="{{ travel.id }}" class="button btn-mini uppercase red">Sup ajax</a>
<div class="modal fade" id="myModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel">
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
<button data-entity-id="" type="button" class="btn btn-primary remove_item">Delete</button>
</div>
<script>
$(document).ready(function () {
$('#myModal').on('show.bs.modal', function () {
var entityId = $(this).attr('entity-id');
// set new value of attr data-entity-id but doesn't work
$('.remove_item').attr('data-entity-id', entityId);
});
$(".remove_item").click(function () {
var entityId = $(this).attr('data-entity-id');
var itemId = 'item-' + entityId;
$.ajax({
type: 'POST',
dataType: 'json',
url: Routing.generate('frontend_travel_delete_favorite', {'id': entityId}),
success: function () {
$('#' + itemId).fadeOut();
}
});
return false;
});
});
</script>
Try to do this:
<a id="delete-btn" title="delete" href data-toggle="modal" data-target="#myModal" data-entity-id="{{ travel.id }}" class="button btn-mini uppercase red">Sup ajax</a>
<div class="modal fade" id="myModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel">
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
<button data-entity-id="" type="button" class="btn btn-primary remove_item">Delete</button>
</div>
<script>
$(document).ready(function () {
$('#delete-btn').on('click', function () {
var entityId = $(this).attr('data-entity-id');
$('.remove_item').attr('data-entity-id', entityId);
});
$(".remove_item").click(function () {
var entityId = $(this).attr('data-entity-id');
var itemId = 'item-' + entityId;
$.ajax({
type: 'POST',
dataType: 'json',
url: Routing.generate('frontend_travel_delete_favorite', {'id': entityId}),
success: function () {
$('#' + itemId).fadeOut();
}
});
return false;
});
});
</script>

Resources