angularjs http post with angular and GAE - javascript

I require a small fix. I simply need to POST my data (comments) to the datastore (GAE) using angularjs but it's not happening just yet. What's wrong with the following angularjs "post" or html?
ANGULAR:
$scope.addComment = function() {
var form_comment = $scope.formFields.comment
var payload = {
comment: form_comment
}
$http({
method: 'POST',
url: '/exp'
}).then(function successCallback(response) {
$scope.comments.push(payload);
}, function errorCallback(response) {
});
};
HTML:
{% extends "home.html"%}
{% block content %}
<div ng-controller="commentController" class="formcontent">
<div class ="container">
<form ng-submit="addComment()" method="post" id="frmComment">
<textarea ng-model="formFields.comment" id="comment" name="commento" class="form-control status-box sameline" rows="2" placeholder="Recommend Colin"></textarea>
</form>
<div class="button-group pull-right sameline">
<p class="counter">140</p>
<button form ="frmComment"class="btn btn-primary" type="submit">Post</button>
</div>
</div>
<div>
<ul class="posts">
<li ng-repeat = "c in comments">
{< c.comment >}
</li>
</ul>
</div>
</div>
{% endblock %}
PYTHON:
class expHandler(webapp2.RequestHandler):
def get(self):
title="Colin_MK: Experience"
recommendations = Recommendation.query()
self.response.out.write(json.dumps([rec.to_dict() for rec in recommendations]))
template_vars = {'title': title, 'recommendations': recommendations}
template = JINJA_ENVIRONMENT.get_template('/exp.html')
self.response.out.write(template.render(template_vars))
def post(self):
r = json.loads(self.request.body)
new_comment = Recommendation(comment=r['comment'])
new_comment.put()
app = webapp2.WSGIApplication([
('/', MainHandler),
('/bio', bioHandler),
('/exp', expHandler)
], debug=True)

The signature to the post method is the following:
post(url, data, [config]);
so you should also include the payload. Try something like this:
$http.post('/exp', payload).then(...)
Also, on the then() method of the promise, you should send a reference to the method:
.then(function(response) {
$scope.comments.push(payload);
}, function(response) {
});

Related

JAVASCRIPT: After sending Item to Database (POST) the window.location.reload() does not work. How to refresh the Data in HTML-Template?

I recode a Tutorial on Youtube.
Django, Python, HTML an Javascript.
Everthing works fine exept the window.location.reload() function.
I try some workarounds with
windows.reload(true),
window.href = window.href
location = self.location
and some more.
I have a hunch that the reload is executed before or during the code before the reload. But I do not know.
The goal is to send the data from the input to the database and only then refresh the page.
This ist the Code from the tutorial:
index.html (shortened)
<body>
<header>
<h1>Shoppinglist</h1>
<div id="input-field">
<label for="item-input">Was möchtest du einkaufen?</label>
<input type="text" name="item" id="item-input">
</div>
<button id="btn" onclick="addItem()">+</button>
</header>
<div id="item-table">
{% for row in all_items %}
<div class="list-item">
<input type="checkbox"> {{row.name}}
</div>
{% endfor %}
</div>
<script>
function addItem(){
let itemName = document.getElementById("item-input").value;
let formData = new FormData();
let token = '{{csrf_token}}';
formData.append('itemName', itemName);
formData.append('csrfmiddlewaretoken', token);
fetch('/mylist/', {
method: 'POST',
body: formData
});
window.location.reload();
};
</script>
</body>
</html>
views.py
from django.shortcuts import render
from .models import ShoppingItem
# Create your views here.
def mylist(request):
if request.method == 'POST':
print('Received date: ', request.POST['itemName'])
ShoppingItem.objects.create(name = request.POST['itemName'])
all_items = ShoppingItem.objects.filter(done = 0)
return render(request, 'index.html', {'all_items':all_items})
models.py
from django.db import models
from datetime import date
#Create your models here.
class ShoppingItem(models.Model):
creatDate = models.DateField (default=date.today)
name = models.CharField (max_length =200)
done = models.BooleanField(default=False)
def __str__(self):
return '(' + str(self.id) +') ' +self.name
Try this:
async function addItem() {
let itemName = document.getElementById("item-input").value;
let formData = new FormData();
let token = "{{csrf_token}}";
formData.append("itemName", itemName);
formData.append("csrfmiddlewaretoken", token);
await fetch("/mylist/", {
method: "POST",
body: formData,
});
window.location.reload();
}

Method Not Allowed (POST) in ajax request with django

I am trying to pass the values of form data through ajax .And getting method not allowed error. I am trying to add comment in a blog post.
This is my form which is inside blog_detail page
<form id="commentform" class="commentform" method="post">
{% csrf_token %}
{%with allcomments.count as total_comments%}
<p>
{{total_comments}} comment{{total_comments|pluralize}}
</p>
{%endwith%}
<select name="blog" class="d-none" id="id_blog">
<option value="{{blog.id}}" selected="{{blog.id}}"></option>
</select>
<label class="small font-weight-bold">{{comment_form.parent.label}}</label>
{{comment_form.parent}}
<div class="d-flex">
<img class="avatar_comment align-self-center" src="{% for data in avatar%}{{data.avatar.url}}{%endfor%}" alt="">
{{comment_form.content}}
</div>
<div class="d-flex flex-row-reverse">
<button value="commentform" id="newcomment" type="submit" class="newcomment btn btn-primary">Submit</button>
</div>
</form>
And when I click the button it should call the ajax
$(document).on('click','#newcomment',function(e){
e.preventDefault();
var button =$(this).attr("value");
var placement = "commentform"
if (button=="newcommentform"){
var placement = "newcommentform"
}
$.ajax({
type: 'POST',
url: '{% url "website:addcomment" %}',
data: $("#" + button).serialize(),
cache: false,
sucess: function(json){
console.log(json)
$('<div id="" class="my-2 p-2" style="border: 1px solid grey"> \
<div class="d-flex justify-content-between">By ' + json['user'] + '<div></div>Posted: Just now!</div> \
<div>' + json['result'] + '</div> \
<hr> \
</div>').insertBefore('#' + placement);
},
error: function(xhr,errmsg,err){
}
});
})
This is my urls.py
path('blog/<int:blog_id>', BlogDetails.as_view(), name="blog_detail"),
path('addcomment/',addcomment, name="addcomment"),
and my views.py is:
class BlogDetails(View):
def get(self, request, blog_id):
query = request.GET.get('query')
if query:
return redirect(reverse('website:search') + '?query=' + query)
blog = Blog.objects.get(id=blog_id)
total_comment = Comment.objects.filter(blog=blog).count()
allcomments = blog.comments.filter(status=True)
blog_list = Blog.objects.all()
comment_form = NewCommentForm()
data = {
'blog': blog,
'blog_list': blog_list,
'total_comment': total_comment,
'comment_form': comment_form,
'allcomments': allcomments
}
return render(request, "blog_detail.html", data)
def addcomment(request):
if request.method == 'post':
comment_form = NewCommentForm(request.POST)
print(comment_form)
if comment_form.is_valid():
user_comment = comment_form.save(commit=False)
user_comment.user = request.user
user_comment.save()
result = comment_form.cleaned_data.get('content')
user = request.user.username
return JsonResponse({'result': result, 'user': user})
Please help me with this it is not calling addcomment view
If how I've interpreted your code is correct, it would probably work if changed your BlogDetails class to this:
class BlogDetails(View):
def get(self, request, blog_id):
query = request.GET.get('query')
if query:
return redirect(reverse('website:search') + '?query=' + query)
blog = Blog.objects.get(id=blog_id)
total_comment = Comment.objects.filter(blog=blog).count()
allcomments = blog.comments.filter(status=True)
blog_list = Blog.objects.all()
comment_form = NewCommentForm()
data = {
'blog': blog,
'blog_list': blog_list,
'total_comment': total_comment,
'comment_form': comment_form,
'allcomments': allcomments
}
return render(request, "blog_detail.html", data)
def post(self, request, *args, **kwargs):
return self.addcomment(request)
def addcomment(self, request):
comment_form = NewCommentForm(request.POST)
print(comment_form)
if comment_form.is_valid():
user_comment = comment_form.save(commit=False)
user_comment.user = request.user
user_comment.save()
result = comment_form.cleaned_data.get('content')
user = request.user.username
return JsonResponse({'result': result, 'user': user})
Because you are trying to POST to a view that doesn't have a post method defined.
Then you would need to remove addcomment from the URL you are calling and just post to whatever URL you are currently at.

Ajax request to changing boolean value of object in django

i'm struggling to make ajax function that change the boolean value of an object without refreshing the page.
It returns error 500.
Model:
class Donation(models.Model):
is_taken = models.BooleanField(default=False)
HTML:
<div style="width: 50%; float:left" class="steps--container">
{% for d in taken %}
<div style="width: 80%; float: left">
<h4>{{d.quantity}} bags of {% for c in d.categories.all %} {{c}} {% endfor %} by {{d.user.first_name}} {{d.user.last_name}} </h4>
<input type="text" id="donation_id" value={{d.id}} hidden>
</div>
<div style="width: 20%; float:right">
<input type="button" onclick="updateStatus()" value="{{d.id}}" Mark as not taken>
</div>
<br>
{% endfor %}
</div>
JS:
function updateStatus() {
var dId = document.getElementById("donation_id").value;
var dIdInt = parseInt(dId, 10)
$.ajax({
type: "GET",
url: "/ajax/taken_or_not_taken/",
data: {
"donation_id": dIdInt
}
}).done(function(e){
console.log("done")
console.log(dIdInt)
})
.fail(function(e){
console.log('error')
console.log(e)
})
}
View:
def taken_or_not_taken(request):
obj = request.GET.get('donation_id', '')
print(obj)
return JsonResponse(obj)
Url:
url(r'^ajax/taken_or_not_taken/$', views.taken_or_not_taken, name='taken_or_not_taken'),
How can i make it works?
The full stacktrace says :
line 121, in taken_or_not_taken return JsonResponse(obj)
line 555, in __init__'In order to allow non-dict objects to be serialized set the the safe parameter to False.'
JsonResponse() should have a dict in argument and you pass an integer.
You can use the donation_id name:
def taken_or_not_taken(request):
obj = request.GET.get('donation_id', '')
print(obj)
return JsonResponse({'donation_id':obj})
Or use the safe=False parameter : https://docs.djangoproject.com/en/3.1/ref/request-response/#django.http.JsonResponse
Yea, i found it out, thanks guys anyway,
But the new problem appeared.
User still needs refresh the page to see the changes.
How to do it without refreshing page? Can i do it in django view?
Like:
def taken_or_not_taken(request):
obj = request.GET.get('donation_id')
data = {
"id": obj
}
donate = Donation.objects.get(id=obj)
if donate.is_taken == True:
donate.is_taken = False
donate.save()
elif donate.is_taken == False:
donate.is_taken = True
donate.save()
return JsonResponse(data)
You can use ajax "POST" method to send the query to the server without refreshing the page.
$.ajax({
type: "POST",
url: "url_of_query",
data: {
// Data you want to update
}
success: function(){
console.log("Success msg");
},
error: function(){
console.log("error");
},
)}

Django Alternative to PK in Form Action Parameter

I have two models in a parent-child relationship: Idea and Comment. I am using DRF and nested DataTables to serve these models to the browser. To create a comment, the corresponding idea ID must be known. The button to create a new comment looks like this with parentObjData being the Idea id:
<button type="button" class="btn btn-primary js-create-idea-comment" data-url="/platform/ideas/comments/' + parentObjData + '/create/"><span class="fa fa-plus"></span> New Comment</button>
When clicked, this happens:
var loadForm = function () {
var btn = $(this)
$.ajax({
url: btn.attr("data-url"),
type: 'get',
dataType: 'json',
beforeSend: function () {
$("#modal-activity").modal()
},
success: function (data) {
$("#modal-activity .modal-content").html(data.html_form)
}
})
}
This works, and a request to the proper URL is sent when each button is clicked. What's supposed to happen with a successful request is demonstrated by these views:
def save_comment_form_create(request, form, template_name, parent_id):
data = dict()
if request.method == 'POST':
if form.is_valid():
instance = form.save(commit=False)
instance.created_by_id = request.user.id
instance.idea_id = parent_id
form.save()
data['form_is_valid'] = True
comments = IdeaComment.objects.all()
data['html_idea_comment_list'] = render_to_string('ic/includes/partial_idea_comment_list.html', {
'comments': comments
})
else:
data['form_is_valid'] = False
context = {'form': form}
data['html_form'] = render_to_string(template_name, context, request=request)
return JsonResponse(data)
def idea_comment_create(request, parent_id):
idea_id = parent_id
if request.method == 'POST':
form = IdeaCommentForm(request.POST)
else:
form = IdeaCommentForm()
return save_comment_form_create(request, form, 'ic/includes/partial_idea_comment_create.html', idea_id)
partial_idea_comment_create.html resolves to this form:
<form method="post" action="{% url 'idea_comment_create' parent_id %}" class="js-idea-comment-create-form">
{% csrf_token %}
<div class="modal-header">
<h4 class="modal-title">New Comment</h4>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
{% include 'ic/includes/partial_idea_comment_form.html' %}
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
<button type="submit" class="btn btn-primary">Create</button>
</div>
</form>
And here is the URL:
url(r'^platform/ideas/comments/(?P<parent_id>\d+)/create/$', views.idea_comment_create, name='idea_comment_create'),
parent_id is the issue. If I hard code a number into partial_idea_comment_create.html, everything works great (except comments go to the wrong idea). The way it is now, I get this error:
NoReverseMatch at /platform/ideas/comments/1/create/
Reverse for 'idea_comment_create' with arguments '('',)' not found. 1 pattern(s) tried: ['platform/ideas/comments/(?P<parent_id>\\d+)/create/$']
For a normal pk that doesn't rely on a parent instance, I would do something like this:
<form method="post" action="{% url 'idea_update' form.instance.pk %}">
How should I dynamically load the parent_id into that URL?
I think this question gets partially there: How do I pass a parent id as an fk to child object's ModelForm using generic class-based views in Django? but I haven't been able to get it to work for me.
The issue is that you're not passing the parent_id in the template context. This is what you should do in the save_comment_form_create method:
...
context = {'form': form, 'parent_id': parent_id}
data['html_form'] = render_to_string(template_name, context, request=request)
return JsonResponse(data)

Submit button for a formset doesn't work when generated by ajax [duplicate]

This question already has answers here:
Event binding on dynamically created elements?
(23 answers)
Closed 5 years ago.
I have a formset to update my models and I display forms from my formset based on the search query. I have an ajax keyup function to send post requests so I can generate search_results.html that I then pass to in search.html.
Now, if I generate the forms dynamically the submit button does not work. If I ditch the search and pass the content of search_results.html to search.html directly it does work.
I have two views, SearchReportView which supposed to be the main one, and SearchReports to handle generating the report. I guess I might just merge them at this point - it doesn't solve my problem though.
Also I had this working before when I used multiple forms but I had to switch to a formset.
body of search.html
<div class="container">
<div class="navbar">
<div class="navbarItem">
<img src="{% static 'back.png' %}" width="20px" height="12px" \>Back
</div>
</div>
<div>
<h3>Search:</h3>
{% csrf_token %}
<input type="text" id="search" name="search" />
<span class="button-checkbox">
<button id="mybutton" type="button" class="btn" data-color="primary">Recent</button>
<input type="checkbox" class="hidden" name="reports_checkbox" checked />
</span>
</div>
<div class="normalText" id="search-results"></div>
</div>
search_results.html
{% if reports_and_formset %}
<form action="/TP/auto/report/search/" method="post" enctype="multipart/form-data"> {% csrf_token %}
{{ formset.management_form }}
{% for x, form in reports_and_formset %}
<button type="submit" class="button" >Submit</button>
{{ form.checking_user }}
{{ form.comment }}
{% for hidden in form.hidden_fields %}
{{ hidden }}
{% endfor %}
{% endfor %}
</form>
{% else %}
<tr> <td> <center>
No results found.
</center></td></tr>
{% endif %}
views.py
class SearchReportView(FormView):
def post(self, request, *args, **kwargs):
# form = ReportCommentForm(initial={'comment': ''})
# context = {'form': form}
if 'form-TOTAL_FORMS' in request.POST:
single_day_enb_reports = SingleDayEnbReport.objects.all()
report_form_set = modelformset_factory(SingleDayEnbReport, form=ReportCommentForm,
max_num=single_day_enb_reports.count())
formset = report_form_set(request.POST, queryset=single_day_enb_reports)
formset.save()
return HttpResponseRedirect('/TP/auto/report/search/report_search/')
# #requires_csrf_token
def get(self, request, *args, **kwargs):
return render(request, 'app/search.html')
class SearchReports(View):
def get(self, request, *args, **kwargs):
single_day_enb_reports = SingleDayEnbReport.objects.all()
report_form_set = modelformset_factory(SingleDayEnbReport, form=ReportCommentForm, max_num=single_day_enb_reports.count())
formset = report_form_set(queryset=single_day_enb_reports)
single_day_enb_reports_and_formset = zip(single_day_enb_reports, formset)
# context = {'single_day_enb_reports': single_day_enb_reports, 'formset': formset}
context = {'reports_and_formset': single_day_enb_reports_and_formset, 'formset': formset}
return render(request, 'app/search_results.html', context, context_instance=RequestContext(request))
#classmethod
def calculate_dates(self): #not important
def post(self, request, *args, **kwargs):
if 'form-TOTAL_FORMS' in request.POST:
single_day_enb_reports = SingleDayEnbReport.objects.all()
report_form_set = modelformset_factory(SingleDayEnbReport, form=ReportCommentForm,
max_num=single_day_enb_reports.count())
formset = report_form_set(request.POST, queryset=single_day_enb_reports)
# if formset.is_valid():
formset.save()
return HttpResponseRedirect('/TP/auto/report/search/report_search/')
if 'button_state' in request.POST:
search_text = request.POST['search_text']
button_state = request.POST['button_state']
if button_state == 'false':
button_state = False
else:
button_state = True
if button_state:
now, fit_date = self.calculate_dates()
single_day_enb_reports = SingleDayEnbReport.objects.all().filter(
Q(last_modification_date__range=[fit_date, now]) & (
Q(alarms__contains=search_text)|
Q(enb__contains=search_text)|
Q(creation_date__date__contains=search_text) |
Q(last_modification_date__date__contains=search_text)|
Q(comment__contains=search_text)|
Q(checking_user__name__contains=search_text)))
else:
single_day_enb_reports = SingleDayEnbReport.objects.all().filter(
Q(alarms__contains=search_text)|
Q(enb__contains=search_text)|
Q(creation_date__date__contains=search_text) |
Q(last_modification_date__date__contains=search_text)|
Q(comment__contains=search_text)|
Q(checking_user__name__contains=search_text))
report_form_set = modelformset_factory(SingleDayEnbReport, form=ReportCommentForm,
max_num=single_day_enb_reports.count())
formset = report_form_set(queryset=single_day_enb_reports)
single_day_enb_reports_and_formset = zip(single_day_enb_reports, formset)
context = {'reports_and_formset': single_day_enb_reports_and_formset, 'formset': formset}
return render_to_response('app/search_results.html', context, context_instance=RequestContext(request))
ajax.js
$('#search').keyup(function(){
delay(function(){
if($('input[name=reports_checkbox]:checked').val()) button_state = true
else button_state = false
$.ajax({
type: "POST",
url: "/TP/auto/report/search/report_search/",
data: {
'button_state' : button_state,
'search_text' : $('#search').val(),
'csrfmiddlewaretoken' : $("input[name=csrfmiddlewaretoken]").val()
},
success: searchSuccess,
dataType: 'html'
});
}, 500 );
});
});
function searchSuccess(data, textStatus, jqXHR){
//generated data is put into search-results <div>field in search.html
$('#search-results').html(data);
}
Please change your this line
$('#search').keyup(function(){
with
$(document).on('keyup','#search', function(){

Categories

Resources