Send data to another django template/view after specific process using ajax - javascript

I have a page where I load 2 files. After a click to the load button, this page reload to display a major part of the data, allowing the user to modified it. After a click to lunch button, I want to launch the process and I want to send to another page the path of results files to allow the user to download it.
My problem is after clicking on lunch button and send data to the other page. I have 2 versions :
The first one, send data to the result page, but I do not find a way to take back in the view the data modified by the user, the ajax seems to be ignored because of the type "summit" for the button launch :
<body>
<section class="bg-light py-5 border-bottom">
<div class="container px-5 my-5 px-5">
<div>
<h1 class="display-5 fw-bolder mb-2"> Convert to Dose </h1>
<br>
</div>
<form id="formCTD" action="{% url 'json:convertToDose' %}" method="POST" enctype="multipart/form-data">
{% csrf_token %}
##here some fields to modified one of them following
<div class="row gx-5 justify-content-center">
<div class="col-lg-4 col-xl-4">
{% if factors %}
<input name="img_path" readonly
class="form-control" {{ pathAnalyseForm.img_path }}>
{% else %}
<input id="btn-submit-form-jsonfile"
class="btn btn-lg" {{ formImgFile.imgFile }}>
{% endif %}
</div>
</div>
<div class="text-center">
<div class="d-grid">
{% if factors %}
<button class="btn btn-primary btn-lg" id="launchButton" type="submit">
Launch
</button>
{% else %}
<button class="btn btn-primary btn-lg" id="submitButton" type="submit">
Load
</button>
{% endif %}
/div>
</div>
</form>
</div>
</section>
</body>
And the js block :
<script type="text/javascript">
$(document).ready(function () {
$("#launchButton").on('submit', function(e) {
e.preventDefault();
var form = $("#formCTD").get(0) //recup en html
// Est-ce que le formulaire est valide ?
console.log("valid? ")
if (form.checkValidity()) {
console.log("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ")
nam = $("input[name='img_path']").val()
json = $("input[name='json_path']").val()
console.log(nam)
data = {"img_path" : nam,
"json_path": json}
console.log("bef ajax")
$.ajax({
url: "/filmchromique/convertToDose/",
type: "POST",
data: data,
beforeSend: function (xhr, settings) {
xhr.setRequestHeader("X-CSRFToken", $('input[name="csrfmiddlewaretoken"]').val());
},
success: function (response) {
console.log("ok")
},
error: function(xhr, status, error) {
alert(xhr.responseText);
}
})
console.log("after ajax")
}
});
});
</script>
And the view :
def launchCtd(request):
if request.method == 'POST':
#2 after click load
if bool(request.FILES.get('calibrationFile', False)) == True and bool(request.FILES.get('imgFile', False)) == True :
#do some test ok
context = {
'factors': True,
'factorsCalib': factorsCalib,
'formCtd': formCtd,
'formJsonFile': formJsonFile,
'formImgFile': formImgFile,
'pathAnalyseForm': pathAnalyseForm,
'doseRect': doseRect,
'ctrlRect': ctrlRect,
}
return render(request, 'convertToDose.html', context)
after click lunch
else:
if request.is_ajax:
print ("here")#check
img_path = request.POST.get("img_path")
doseRectStr = request.POST.getlist('form[]')
json_pactrlRectth = request.POST.get("json_path")
method = request.POST.get("analyse_type")
if method == 'rb':
#init var
if method == 'multi':
#init var
img_out_path, json_pactrlRectth = functionTOLaunch()
context = {
'filename': img_out_path,
'protocol_file': json_pactrlRectth,
}
return render(request, 'result.html', context)
#1 load init
else:
formCtd = CtdForm()
formJsonFile = JsonFileForm()
formImgFile = ImgFileForm()
context = {
'factors': False,
'formCtd': formCtd,
'formJsonFile': formJsonFile,
'formImgFile' : formImgFile,
}
return render(request, 'convertToDose.html', context)
and the result page is a basic TemplateView.
In this first case, console.log in the ajax are not printed, I do not understand why and I supposed the function is not called (and so the ajax part)
in the second version, views are identical but I modified this on the html :
<button class="btn btn-primary btn-lg" id="launchButton" type="button">
Launch</button>
and this in the js part :
$("#launchButton").on('click', function(e) {....}
Data are sended to the view, I can read it but when I do the render to display the result page with out process data, nothing append... I supposed I have to implement something in the succes ajax part, but I do not understand what I have to do. I supposed I have to implement a new ajax request, to send the new context to the result page but how I take back the context sended by the render in the success ajax ... I'am totaly new and lost on this tech
Thanks for reading :)

Related

can't refresh the data in a DIV python Django nor the page after a jquery

Let me start by saying I have 2 variables in an HTML template(messages and users) and I have multiple buttons that when one of them is clicked it calls a jquery code that sends a post request to a Django server and it returns an update to a variable(messages)
however, it's not updating the loop, I also tried to return a new HTML page that contains the new variable updated but the jquery is not updating the whole page with the new HTML
if I can update the variable alone it would be better and if I can't do that how can I make jquery use the new HTML page
the python code i used to return the update to the varialbe messages:
if request.method == 'POST':
send=Message.objects.filter(from_id=request.POST.get('userId'),to_id=2)
rec=Message.objects.filter(from_id=2,to_id=request.POST.get('userId'))
messages=sorted(chain(rec, send),key=lambda instance: instance.id,reverse=True)
print(messages)
return HttpResponse(list(messages))
and the code i used to return new HTML template:
m = Message.objects.filter(to_id=2).order_by('-id')
users = {}
for i in m:
if users.get(i.from_id.username) == None:
users[i.from_id.username] = User.objects.get(id=i.from_id.id)
users = list(users.values())
send=Message.objects.filter(from_id=users[0].id,to_id=2)
rec=Message.objects.filter(from_id=2,to_id=users[0].id)
messages=sorted(chain(rec, send),key=lambda instance: instance.id,reverse=True)
if request.method == 'POST':
send=Message.objects.filter(from_id=request.POST.get('userId'),to_id=2)
rec=Message.objects.filter(from_id=2,to_id=request.POST.get('userId'))
messages=sorted(chain(rec, send),key=lambda instance: instance.id,reverse=True)
print(messages)
return render(request,'psych.html',{"users":users, "messages":list(messages)})
return render(request,'psych.html',{"users":users, "messages":list(messages)})
the HTML code and jquery code that uses the variable and try to update it
function newUser(id){
$.ajax({
type: 'POST',
url:'/psych.html/',
data:{
userId:id,
},
success: function(data){
console.log(data);// the data returnd are correct and as needed
//but i cant make it update the messages
$('#messageDiv').load(document.URL + ' #messageDiv');
}
})
}
{% for i in users %}
<li class="">
<button type="button" class="btn" onClick="newUser({{i.id}})">
<div class="d-flex bd-highlight">
<div class="img_cont">
<!-- here was an image ----------------------------------------------->
</div>
<div class="user_info">
<span>{{i.id}}</span>
</div>
</div>
</button>
</li>
{% endfor %}
<!-- The varialbe that i'm trying to update is called messages bottom -->
{% for o in messages %}
{% if o.to_id.id != 2 %}
<div class="d-flex justify-content-start mb-4">
<div class="img_cont_msg">
<!-- here was an image-->
</div>
<div class="msg_cotainer">
{{o.message}}
<!-- <span class="msg_time">{{o.time}}</span> -->
</div>
</div>
{% else %}
<div class="d-flex justify-content-end mb-4">
<div class="msg_cotainer_send">
{{o.message}}
<!-- <span class="msg_time_send">{{o.time}}</span> -->
</div>
<div class="img_cont_msg">
<!-- here was an image-->
</div>
</div>
{% endif %}
{% endfor %}
if it helps i did it before and updated the messages from jquery but i used form and there was only 1 variable i will add the code to that too
$(document).on('submit','#submitMessage', function (e){
e.preventDefault();
$.ajax({
type: 'POST',
url:'/psych.html/',
data:{
message:$('#messageHolder').val(),
csrfmiddlewaretoken: $('input[message=csrfmiddlewaretoken]').val(),
},
success: function(data){
// it work like charm here
$('#messageDiv').load(document.URL + ' #messageDiv');
}
})
})
{% for o in messages %}
{% if o.to_id.id == 2 %}
<div class="d-flex justify-content-start mb-4">
<div class="img_cont_msg">
<!-- here was an image-->
</div>
<div class="msg_cotainer">
{{o.message}}
<!-- <span class="msg_time">{{o.time}}</span> -->
</div>
</div>
{% else %}
<div class="d-flex justify-content-end mb-4">
<div class="msg_cotainer_send">
{{o.message}}
<!-- <span class="msg_time_send">{{o.time}}</span> -->
</div>
<div class="img_cont_msg">
<!-- here was an image-->
</div>
</div>
{% endif %}
{% endfor %}
<form id="submitMessage" >
{% csrf_token %}
<div class="card-footer">
<div class="input-group">
<div class="input-group-append"></div>
<input name="message" class="form-control type_msg" placeholder="Type your message..." id="messageHolder">
<div class="input-group-append">
<button type="submit" class="btn">
<span class="input-group-text send_btn" ><i class="fas fa-location-arrow"></i></span>
</button>
</div>
</div>
</div>
</form>
Try this
$("#messageDiv").load(location.href+" #messageDiv>*");
i figured the problem and it was because i didn't know that
$("#messageDiv").load(location.href+" #messageDiv>*");
would make a GET request so all I did was adding the necessary data to the URL and then change the URL too(so if the client refreshed the page it would stay in the same spot) without refreshing the page and then do the command app there
if it could help anyone please look at the code below:
function newUser(id){
var url = document.URL;
url = url.split('/');
url[url.length-2] = id;
url = url.join('/');
window.history.pushState("object or string", "my website name", url);
$('#messageDiv').load(url + ' #messageDiv');
}
sadly i don't know how to do post requst then load the page please if you know comment down bellow so someone else might get help from it

Implement Ajax in a Django Project not working properly

I am trying to implement a like button to my blog post using Ajax, I am facing an error which I am unable to fix so I started from scratch more than once with the following steps:
Created Post model and Like model
Added the views which is currently working perfectly fine when I click like and unlike
I took the like section from the post_detail.html and added it in a separate html like_section.html
added the ajax with the correct values
Now my problem is that when I press the like button a new page is opened with ajax output
{"form": "....(html and ajax codes repeated)......"}
My question is how do I fix this error so that I can submit a like without refreshing the page?
Here are the models for Posts.py
class Post(models.Model):
---------other attributed like: title, content, author, date_posted, slug-----
likes = models.IntegerField(default=0)
class Like(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE)
post = models.ForeignKey(Post, on_delete=models.CASCADE)
Here are the views:
def like_post(request):
user = request.user
if request.method == 'POST':
post = request.POST.get('post_id')
post_obj = Post.objects.get(id=post)
current_likes = post_obj.likes
if user in post_obj.liked.all():
post_obj.liked.remove(user)
current_likes = current_likes - 1
else:
post_obj.liked.add(user)
current_likes = current_likes + 1
post_obj.likes=current_likes
post_obj.save()
like, created = Like.objects.get_or_create(user=user, post_id=post)
if not created:
if like.value == 'Like':
like.value = 'Unlike'
else:
like.value = 'Like'
like.save()
context = {
'post': post,
}
if request.is_ajax:
html = render_to_string('blog/like_section.html',context, request=request)
return JsonResponse({'form': html})
Here is the post details.html
<!-- Like -->
<div id="like-section">
{% include 'blog/like_section.html' %}
</div>
<!-- Like -->
Here are the like-section.html
<form action="{% url 'blog:like-post' %}" method="POST" class="like-form" id="{{post.id}}">
{% csrf_token %}
<input type="hidden" name="post_id" value='{{post.id}}'>
{% if user not in post.liked.all %}
<button id="like" value='{{post.id}}' class="bwhite sm-button" style="color: grey; background-color: Transparent; background-repeat:no-repeat; border: none; cursor:pointer; overflow: hidden; outline:none;">
<i class="far fa-thumbs-up" type="submit"></i>
</button>
{% else %}
<button id="like" value='{{post.id}}' class="bwhite sm-button" >
<i class="far fa-thumbs-up" type="submit"></i>
</button>
{% endif %}
<div class="like-count{{post.id}}">{{ post.num_likes }} Likes</div>
</form>
Here is the ajax:
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script type="text/javascript"></script>
<script>
$(document).ready(function(event){
$(document).on('click', '#like', function(event){
event.preventDefault();
var pk = $(this).attr('value');
$.ajax({
type: 'POST',
url: '{% url "blog:like-post" %}',
data: {'post_id':pk, 'csrfmiddlewaretoken': '{{ csrf_token }}'},
dataType: 'json',
success: function(response){
$('#like-section').html(response['form'])
console.log($('#like-section').html(response['form']));
},
error: function(rs, e){
console.log(rs.responseText);
},
});
});
</script>
Here is the urls.py
path('blogs/like', like_post, name='like-post'),
You are returning an HTML page as response from your view, I think that might be causing it. First just try returning something like {"msg","worked"} and see if its works

Django forms are not receiving form data using ajax call

I am writing a simple AJAX site using a Django back-end where you can create articles. Each article has an edit button, which can be used to modify that pre-existing article on the page. This button pops up an edit form (the issue at hand) in a Bootstrap Modal.
The edit form has only 3 fields: headline, subheading, and a date (for now). Whatever the field inputs are, they are not sent back to Django properly and the is_valid() method returns False every single time. This is what form.errors gives me as output every single time:
<ul class="errorlist"><li>headline<ul class="errorlist">
<li>This field is required.</li>
</ul>
</li>
<li>subheading<ul class="errorlist">
<li>This field is required.</li></ul></li>
<li>date<ul class="errorlist"><li>This field is required.</li></ul></li></ul>
The "This field is required" is likely because the model does not have blank=True, so the form must be sending empty fields.
Below is all my code in question, including the form in HTML, the AJAX call, and the Django form.
views.py:
# Handles editing articles
class ArticleEdit(View):
def post(self, request, id):
editForm = ArticleForm(request.POST)
if editForm.is_valid():
print("Debug: Form is valid")
# No Logic here yet
return JsonResponse({'edited' : 'OK'}, status=200)
else:
print(editForm.errors)
return JsonResponse({'edited' : 'FAIL'}, status=200)
forms.py
class ArticleForm(ModelForm):
class Meta:
model = Article
fields = ['headline', 'subheading', 'date']
widgets = {
'headline' : forms.TextInput(attrs={'class': 'form-control'}),
'subheading' : forms.TextInput(attrs={'class': 'form-control'}),
'date' : forms.TextInput(attrs={'class': 'form-control'}),
}
articles.html
<!-- Bootstrap Modal -->
<div id="editModal" class="modal fade" role="dialog">
<div class="modal-dialog">
<!-- Modal content-->
<div class="modal-content">
<div class="modal-header">
<h4 class="modal-title">Edit Article</h4>
<button type="button" class="close" data-dismiss="modal">×</button>
</div>
<div class="modal-body">
<!-- Edit Form -->
<form class="form-group" method="post" id="editArticleForm">
{% csrf_token %}
{{ editForm }}
<button type="button" class = "btn btn-outline-success my-3" id="finishEditButton">Finish</button>
</form>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
</div>
</div>
</div>
</div>
articles.js
function finishEdit()
{
editData = $('#editArticleForm').serialize();
console.log(editData);
$.ajax
({
url: '/' + currentlyEditing.data('id') + '/edited/',
data: {csrfmiddlewaretoken: $('input[name=csrfmiddlewaretoken]').val(), data: editData, id: currentlyEditing.data('id')},
type: 'post',
success: function(data)
{
if (data.edited == "OK")
{
console.log("EDIT::RESPONSE OK");
}
else
{
console.log("EDIT::RESPONSE FAIL");
}
}
});
I've tried deleting the modal, and having the form as a simple element instead. I've also tried to rewrite my Ajax request but that hasn't worked either. Plus, the serialized data created from the form displays the information typed into the input fields, but it doesn't end up in Django.
In conclusion, my whatever my data is in my form in articles.html is not sent properly to Django, no matter what I type, and I cannot seem to figure out the problem. I would really appreciate some help with this.
Thank you all in advance.

Filepond with Django returns empty filelist

I am trying to use file pond with my Django but after the images are preview and it displays them as green and I see the POST request, after clicking submit n my form when I print request.files it returns an empty list.
This is my Django view:
#login_required
def post_create(request):
data = dict()
if request.method == 'POST':
form = PostForm(request.POST)
if form.is_valid():
post = form.save(False)
post.author = request.user
post.save()
if request.FILES is not None:
images = request.FILES.getlist('filepond')
print(images)
for i in images:
image_instance = Images.objects.create(image=i,post=post)
image_instance.save()
data['form_is_valid'] = True
data['post'] = render_to_string('home/posts/new_post.html',{'post':post},request=request)
else:
data['form_is_valid'] = False
else:
form = PostForm
context = {
'form':form,
}
data['html_form'] = render_to_string('home/posts/post_create.html',context,request=request)
return JsonResponse(data)
Andd this is my html with script:
<form method="POST" data-url="{% url 'home:post-create' %}" class="post-create-form" enctype="multipart/form-data">
{% csrf_token %}
<div class="modal-header text-center">
<h5 class="modal-title col-12 text-center">Create a Post
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</h5>
</div>
<div class="modal-body" style="height:400px;overflow-y: auto; margin:0;">
{{ form|crispy }}
<div class="pt-3" style="margin-bottom: -100px !important;">
<input type="file" class="filepond" accept="image/*">
</div>
</div>
<div class="modal-footer col-12" style="margin-top: -20px;">
<button type="submit" class="btn btn-primary" style="border-radius: 20px; width: 100%;">Post</button>
</div>
</form>
<script>
$.fn.filepond.registerPlugin(
FilePondPluginImagePreview,
FilePondPluginImageCrop,
FilePondPluginImageEdit,
FilePondPluginImageEdit,
FilePondPluginFileValidateType,
);
$(function () {
var csrf_token="{{ csrf_token }}";
$('.filepond').filepond({
allowMultiple: true,
className: "d-flex",
maxFiles: 4,
allowFileTypeValidation: true,
acceptedFileType:['image/png', 'image/jpeg'],
dropOnPage: true,
server: {
process: {
headers: {"X-CSRFToken":csrf_token,},
url: '/home/post/create/',
method: 'POST',
},
revert: {
headers: {
"X-CSRFToken":csrf_token,
},
url: '/home/post/create/',
method: 'DELETE',
},
fetch: null,
load: null,
},
labelIdle: '<span class="filepond--label-action">Add Photos</span>',
imagePreviewHeight: 250,
});
})
</script>
What is causing this issue as I can see the files being uploaded and I set the server URL to which handles the POST request how am I suppose to fix this? I have already tried renaming input field but nothing is being returned in Django when I print the files.
The files are already uploaded. You won't receive another files list, you'll receive an array of file ids (the id's returned by this endpoint '/home/post/create/).
You can then move files from the temp directory, where the process end point should put files, to a more final location.

Django UpdateView form displaying in modal but not updating

So I have this update view:
class UpdateRules(UpdateView):
model = BlackList
form_class = AddRules
template_name= 'blacklist_form.html'
success_url = reverse_lazy('posts:list')
which displays this template blacklist_form.html:
<form class="well contact-form" method="post" action="">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal">x</button>
<h3>Editing Number</h3>
</div>
<div class="modal-body">
{% csrf_token %}
{{form.as_p}}
</div>
<div class="modal-footer">
<input class="btn btn-primary" type="submit" value="Save" />
</div>
</form>
Then in the template where the modal is called/rendered I have this link for each object to be edited:
<a class="contact" href="#" data-form="{% url 'posts:update_rules' obj.pk %}"
title="Edit">
And this div to display the modal:
<div class="modal" id="contactModal">
</div>
Lastly, the jQuery:
$(document).ready(function() {
$(".contact").click(function(ev) { // for each edit contact url
ev.preventDefault(); // prevent navigation
var url = $(this).data("form"); // get the contact form url
console.log(url);
$("#contactModal").load(url, function() { // load the url into the modal
$(this).modal('show'); // display the modal on url load
});
return false; // prevent the click propagation
});
$('.contact-form').on('submit',function() {
$.ajax({
type: $(this).attr('method'),
url: this.action,
data: $(this).serialize(),
context: this,
success: function(data, status) {
$('#contactModal').html(data);
}
});
return false;
});
});
My problem is this: I'm able to get the update view form to display in the modal when I click the edit link for each object, but the submit button doesn't do anything. When I save the form from the actual updateview template, it works just fine, so I'm thinking it must be something wrong with the jQuery. I'm not getting any errors, the modal just disappears and the page doesn't reload. Any pointers on what going on?

Categories

Resources