foreign key showing undefined django ajax - javascript

in this scenario when put the name of foreign key in p tag with js, it is showing undefined but its getting the inpuput as the proper user but not not able to show it because it is saying undefined
js code
$(document).ready(function(){
// $('#submit').onclick(function(){
// $('#message').val=''
// })
$(document).on('submit','#post_form',function(e){
e.preventDefault();
$.ajax({
type: 'POST',
url:"{% url 'create' %}",
data:{
message: $('#message').val(),
csrfmiddlewaretoken:$('input[name=csrfmiddlewaretoken]').val(),
},
success:function(){
window.location = url;
}
});
});
setInterval(function()
{
$.ajax({
type:'GET',
url:"{% url 'comments' %}",
success:function(response){
$('.display').empty();
for(var key in response.comments){
this is where it shows undefined, is there any way to convert it to string
console.log(response.comments[key].user);
var temp = "<div class='message_area'><p id='messagetext'>"+response.comments[key].message+"</p></div>"
$(".display").append(temp);
}
},
error:function(response){
console.log("no data found")
}
});
}, 500);
});
views.py
def create(request):
if request.method == "POST":
author = request.user
message = request.POST['message']
message = comments(user=author,message=message)
message.save()
models
class comments(models.Model):
userId = models.AutoField(primary_key=True)
user = models.ForeignKey(User,on_delete=models.CASCADE)
message = models.CharField(max_length=100,blank=False)
date = models.TimeField(auto_now_add=True)
def __str__(self):
return f'{self.user} comments'

using Django template syntax in the js codes is not wrong but it could be better if we don't do that.
instead of data:{ message: $('#message').val(); csrfmiddlewaretoken:$('input[name=csrfmiddlewaretoken]').val(),},
it could be writing in the html, inside the form part. and the js could be:
<form id="form_id" ......>
{% csrf_token %}
<!-- other fields of the form -->
</form>
$.ajax({
type: 'POST',
url:"{% url 'create' %}",
data:$("#form_id").serialize();
success:function(){
window.location = url;
}
});
well, thats not enough for your case, you have problem in another part of the code. you didn't provide the views function which returns the comments and it seems that the problem is there, at this time you could use console.log(response.comments[key]); to figure out what data is returned then use the information to correct the code

Related

Ajax returning empty string in Django view

I am developing a web application through Django and I want to get information from my javascript to a view of Django in order to access to the database.
I am using an ajax call as this post shows.
I am calling the js in html by an onclick event :
sortedTracks.html
...
<form action="{% url 'modelReco:sortVideo' video.id %}">
<input type="submit" value="Validate" onclick="ajaxPost()" />
</form>
...
clickDetection.js
//defined here
var tracksSelected = [];
//function that fill tracksSelected
function tagTrack(track_num){
if(tracksSelected.includes(track_num)){
var index = tracksSelected.indexOf(track_num);
tracksSelected.splice(index, 1);
}else{
tracksSelected.push(track_num);
}};
//ajax function
function ajaxPost(){
$.ajax({
method: 'POST',
url: '/modelReco/sortedTracks',
data: {'tracksSelected': tracksSelected},
success: function (data) {
//this gets called when server returns an OK response
alert("it worked! ");
},
error: function (data) {
alert("it didnt work");
}
});
};
So the information I want to transfer is tracksSelected and is an array of int like [21,150,80]
views.py
def sortedTracks(request):
if request.is_ajax():
#do something
print(request)
request_data = request.POST
print(request_data)
return HttpResponse("OK")
The ajax post works well but the answer I get is only an empty Query Dict like this :
<QueryDict: {}>
And if I print the request I get :
<WSGIRequest: GET '/modelReco/sortedTracks/?tracksSelected%5B%5D=25&tracksSelected%5B%5D=27&tracksSelected%5B%5D=29'>
I have also tried to change to request_data=request.GET but I get a weird result where data is now in tracksSelected[]
I've tried to know why if I was doing request_data=request.GET, I get the data like this tracksSelected[] and get only the last element of it.
And I found a way to avoid to have an array in my data (tracksSelected) on this link
This enables me to have :
in views.py
def sortedTracks(request):
if request.is_ajax():
#do something
print(request)
request_data = request.GET.getlist("tracksSelected")[0].split(",")
print(request_data)
and in clickDetection.js
function ajaxPost(){
tracksSelected = tracksSelected.join();
$.ajax({
method: 'POST',
url: '/modelReco/sortedTracks',
data: {'tracksSelected': tracksSelected},
success: function (data) {
//this gets called when server returns an OK response
alert("it worked! ");
},
error: function (data) {
alert("it didnt work");
}
});
};
This little trick works and I am able to get the array data like this,
print(request_data) returns my array such as [21,25,27]
Thank you for helping me !
According to me to access the data which is sent in the ajax request can be directly accessed .
For Example:
def sortedTracks(request):
if request.method == 'POST':
usersV = request.POST.get('tracksSelected')[0]
for users in usersV:
print users
return HttpResponse("Success")
else:
return HttpResponse("Error")
The correct syntax is data: {tracksSelected: tracksSelected},

jquery elements with django forms

I am using jquery elements that a user can drag and drop. I post the order of the elements to django using ajax.
Inside the django view I am able to work with the data that is posted from ajax.
Django views:
#this is the view where the jquery elements are being ordered by the user
def inside_exam(request):
if request.method=='POST':
form = MyForm(request.POST)
if form.is_valid():
#here I am able to retrieve the data from ajax and save it to a django model, code not shown here
return redirect('exam_results')
#the view redirected to from the inside_exam view
def exam_results(request):
#here I set the score for the exam and set the context, code not shown here
print(“all is set”)
return render(request, 'quizresults.html', context)
The print(“all is set”) is executed and I am able to print the html for quizresults.html in the browser. No errors are in the terminal window and this is shown in the terminal: "GET /exam_results/ HTTP/1.1" 200 8981.
But the same template is still shown, it is not showing the quizresults.html template. Any idea why the render(request, 'quizresults.html', context) is not working as expected?
By the way: when I use a django form without the jquery, everything works fine and the quizresults.html template is shown.
Since I want to show the user another template, but not update the current template, is ajax maybe not the correct way to send the jquery data in this case? If not, what would be a better way?
Edit, ajax code:
function dataToSend() {
{% load static %}
var node2 = document.getElementById('sortable');
var idsInOrder = $("#sortable").sortable('toArray');
console.log("the ids");
console.log(idsInOrder);
var fd = new FormData();
for(var i=0; i<idsInOrder.length; i++) {
j = i+1
fd.append('a'+j, idsInOrder[i]);
}
$.ajax({
type: 'POST',
data: fd,
cache: false,
processData: false,
contentType: false
}).done(function(data) {
//The data from the quizresults.html template is printed out here, but that template is not shown, the template in the browser is still the insidequiz.html template.
console.log("the data");
console.log(data);
});
}
window.onload = function init() {
function getCookie(name) {
var cookieValue = null;
if (document.cookie && document.cookie !== '') {
var cookies = document.cookie.split(';');
for (var i = 0; i < cookies.length; i++) {
var cookie = jQuery.trim(cookies[i]);
if (cookie.substring(0, name.length + 1) === (name + '=')) {
cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
break;
}
}
}
return cookieValue;
}
var csrftoken = getCookie('csrftoken');
function csrfSafeMethod(method) {
return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method));
}
$.ajaxSetup({
beforeSend: function(xhr, settings) {
if (!csrfSafeMethod(settings.type) && !this.crossDomain) {
xhr.setRequestHeader("X-CSRFToken", csrftoken);
}
}
});
};
Using redirect shortcut method in Django will return a HttpResponseRedirect object back to the AJAX, which it will be processed as a 302 Found status code, which then will make another request to the redirected resource and get the content. This does not seem to be the right way to do it, even though you get the content.
You can use the method exam_results to do the other work and return the required context, which shall be used to return the HttpResponse object using render method.
Then, with the data you get, you can replace the document with the template you receive.
Solution:
# views
#this is the view where the jquery elements are being ordered by the user
def inside_exam(request):
if request.method=='POST':
form = MyForm(request.POST)
if form.is_valid():
#here I am able to retrieve the data from ajax and save it to a django model, code not shown here
context = exam_results(request)
return render(request, 'quizresults.html', context)
# method to set the score for the exam
# return context from this method
def exam_results(request):
#here I set the score for the exam and set the context, code not shown here
# build context
return context
# javascript
$.ajax({
type: 'POST',
data: fd,
cache: false,
processData: false,
contentType: false
}).done(function(data) {
//The data from the quizresults.html template is printed out here, but that template is not shown, the template in the browser is still the insidequiz.html template.
console.log("the data");
console.log(data);
// replace the page with the new template
var newDoc = document.open("text/html", "replace");
newDoc.write(data);
newDoc.close();
// update the url
window.history.pushState('', 'title', "newurl");
});
Ref: History API MDN
I figured that ajax makes things complicated when it comes to redirecting. What I ended up doing was to create an HTML form (that is hidden) and then post that form to a url using javascript. No need for ajax.
HTML code:
<form id="form1" action='{% url 'inside_exam' %}' method="post" style="display:none;">
{% csrf_token %}
</form>
<p> <button type='submit' style="visibility" class="button button-long button-primary" onclick="sendData(this);">Send</button></p>
javascript code:
function sendData() {
var idsInOrder = $("#sortable").sortable('toArray');
var form = document.getElementById('form1');
for(var i=0; i<idsInOrder.length; i++) {
j = i+1
var hiddenField = document.createElement("input");
hiddenField.setAttribute("type", "hidden");
hiddenField.setAttribute("name", 'a'+j);
hiddenField.setAttribute("value", idsInOrder[i]);
form.appendChild(hiddenField);
}
console.log("form is:");
console.log(form);
form.submit();
}

Render rails fields_for through ajax call

I have an AJAX call:
$('#enrollment_members').change(function(){
var memberNumber = $(this);
$.ajax({type: 'GET',
url: $(this).href,
type: "get",
data: { members: memberNumber.val() },
error: function(){ alert("There was a problem, please try again.") }
});
return false;
console.log(data);
});
through which I send params[:members] into a new method.
I wanna do something like this:
def new
#enrollment = Enrollment.new
params[:members] ? params[:members].to_i.times { #enrollment.atendees.build } : #enrollment.atendees.build
respond_to do |format|
format.js
end
end
I need this value in order to know how many fields_for to build.
But this being in the new action, how can I update the content of the new view after inputting a value in the members input field?
From that ternary, #enrollment.atendees contains 4 objects.
My new.js.erb :
$("#contact-wrap").html("<%= j render(:partial => 'enrollments/form') %>");
The xhr response contains 4 fields_for forms.
Is the object #enrollment_members the input value you are trying to pass to the controller?
if so, try this:
$('#enrollment_members').change(function(){
var memberNumber = $(this);
$.ajax({type: 'GET',
url: $(this).href,
type: "get",
data: { members: memberNumber.serialize() }, //CHANGE
error: function(){
alert("There was a problem, please try again.")
}
});
return false;
Hmm are you really sure you need a custom made solution for this ? The behavior of dynamically adding/removing children in fields_for is already adressed by several gems like nested_form (no longer maintained) or cocoon (more promising)
I'd suggest to actually reuse their library even if you need to tweak it your way. Because doing an AJAX request is completely pointless. Your AJAX is a GET request that will always do the same thing, unless you have a custom atendees.build which will do weird things for successive calls (like incrementing a global counter somewhere).
Those gems I mentionned above will actually save the HTML fields to generate in a "template" (stored locally in HTML or JS), and just call this template when you want to add a new field.
I got it working by modifying the ajax call:
$('#enrollment_members').change(function(){
var memberNumber = $(this);
$.ajax({type: 'GET',
url: $(this).href,
type: "get",
dataType : "html",
data: { members: memberNumber.val() },
success: function( data ) {
var result = $('<div />').append(data).find('#contact-wrap').html();
$('#contact-wrap').html(result);
$('#atendees-wrap').show();
},
error: function( xhr, status ) {
alert( "Sorry, there was a problem!" );
}
});
return false;
});

Uploading a file through AJAX with a Django Form

I've been trying to create a system that allows uploads of text and a file through my Django form. Whenever I try post the form I can only seem to get the message part of the form. I've been following this answer for reference but I've been running into trouble. First, my form looks like this:
class MessageForm(forms.Form):
message = forms.CharField(widget=forms.Textarea, required=False)
file = forms.FileField(label="Attachment", required=False)
and it's rendered to HTML like this:
<form id="message-form" enctype="multipart/form-data">
{{form.message}}<br>
{{form.file}}
<div class="sectio4-bottom">
<div class="right-bottom">
<input id="send-button" type="submit" value="Send"/>
</div>
</div>
</form>
The current version of my JS function I'm working with looks entirely like this:
$('html').on('submit', '#message-form', function(e){
e.preventDefault();
var data = new FormData($('#message-form').get(0));
$.ajax({
url: '#',
type: 'POST',
data: {
'data': data,
'csrfmiddlewaretoken': $('.csrftoken').text()
}
});
return false;
})
but the part I'm interested in is var data = new FormData($('#message-form').get(0));. I got this from the linked question but when it runs it gives me an empty object. I've also tried passing the data as 'data': $('#message-form').serialize() but when it gets to the backend and I look at request.POST I see that the only thing included in data is the message I send. request.FILES is empty.
How can I access the specified file?
Try adding:
data.append('file',$("#file").files[0]); #Assume 'file' is id of your file field
after
var data = new FormData($('#message-form').get(0));
Here an example function that I'm using
function saveVeichle() {
$(".sk-wave").show();
var dati = new FormData();
dati.append('csrfmiddlewaretoken','{{csrf_token}}');
dati.append('note',$("#note").val());
dati.append('dip',$("#dip-0").val());
dati.append('stato',$("#stato").val());
$("input").each(function(id,obj){
if (obj.type == 'checkbox') {
dati.append(obj.name,obj.checked);
} else {
dati.append(obj.id,obj.value);
}
});
dati.append('foto',$(".foto")[0].files[0]);
dati.append('libretto',$(".libretto")[0].files[0]);
$.ajax({
url: "/mezzi/api/salva_mezzo/",
type: "POST",
data: dati,
cache: false,
contentType: false,
processData: false,
}).done(function(data) {
if (data.res == 'ok') {
window.location = '/mezzi/' + data.id + '/';
} else {
if (data.errors) {
for (d in data.errors) {
noty_alert(d + ":" + data.errors[d]);
}
} else {
noty_alert('Errore Salvataggio Mezzo!');
}
$(".sk-wave").hide();
}
});
}

how to use ajax result in click function?

i make a form in symfony when i submit form through ajax then i store (result.id) in a variable and then i used this variable in click function but the error occur invoiceid does not exist in new.html.twig
how to resolve this problem?
here is my code of ajax:
$("form").submit(function(e) {
e.preventDefault();
var url = $(this).attr('action');
var data = $(this).serialize();
$.ajax({
type: "POST",
url: url,
data: data,
}).done(function( result ) {
var invoiceid=(result.id);
if(result.success) {
$('#result').css({
'color':'black',
'background-color':'#8F8',
'display':'Block',
'width':'200px'
});
$('#result').html('Invoices Record Inserted');
setTimeout(function(){
$('#result').hide();
},3000);
}
});
this.reset();
});
$("#edit").click(function(){
window.location.href= "{{ path('invoices_edit', {'id': invoiceid }) }}";
});
Your templating function {{ path }} is resolved before JavaScript even runs.
Your templating engine is unable to see JavaScript values, and the variable invoiceid does not exist in your template.

Categories

Resources