so I have this commenting form that works fine in post.html and now I'm trying to use it in commentThread.html but I'm having some problem.(this has been bugging me for three days, any help would be appreciated) I'll explain with my code
def post(request, slug):
hotCat = Category.objects.get_hotCat()
post = get_object_or_404(Post, slug=slug)
post.views += 1 # increment the number of views
post.save() # and save it
profile = post.moderator
#path = request.get_full_path()
#comments = Comment.objects.filter(path=path)
comments_count = Comment.objects.filter(post=post).count()
comments = post.commented_post.all()
for c in comments:
c.get_children()
hidden_data = {
"post_id" : post.id,
"origin_path" : request.get_full_path,
"parent_id" : None
}
comment_form = CommentForm(hidden_data=hidden_data)
context_dict = {
'post' :post,
'hotCat' :hotCat,
'comments' : comments,
'comment_form':comment_form,
'comments_count':comments_count,
'profile' :profile,
}
return render(request, 'main/post.html', context_dict)
above is my function for post.html. which is in main directory. Now to move on to comment directory, I'll post my comment form
class CommentForm(forms.Form):
comment = forms.CharField(
widget=forms.Textarea(attrs={"placeholder": "leave"})
)
#hidden_field = forms.CharField(widget=forms.HiddenInput())
def __init__(self, hidden_data=None, data=None, files=None, **kwargs):
super(CommentForm, self).__init__(data, files, kwargs)
self.helper = FormHelper()
self.helper.form_show_labels = False
self.helper.add_input(Submit('submit', 'leave', css_class='btn btn-default'))
if hidden_data:
self.helper.add_input(Hidden('post_id', hidden_data['post_id']))
self.helper.add_input(Hidden('origin_path', hidden_data['origin_path']))
if hidden_data.get('parent_id', None):
self.helper.add_input(Hidden('parent_id', hidden_data['parent_id']))
and in comment directory, this is my views.py for creating commenting. It has two parts, one for parent_comment and one for replying to parent_comment which I named child_comment.
Now in my post.html, I needed both feature. But for commentThread.html, parent_comment is shown and I want one form that allows users to reply to parent_comment. So what I need in commentThread.html is just child_comment form.
@csrf_exempt
def comment_create_view(request):
if request.method == "POST" and request.user.is_authenticated():
parent_id = request.POST.get('parent_id')
post_id = request.POST.get("post_id")
origin_path = request.POST.get("origin_path")
try:
post = Post.objects.get(id=post_id)
except:
response_dat = {"code":400,"message":"Post does not exists"}
return JsonResponse(response_data)
parent_comment = None
if parent_id is not None:
try:
parent_comment = Comment.objects.get(id=parent_id)
except:
parent_comment = None
if parent_comment is not None and parent_comment.post is not None:
post = parent_comment.post
form = CommentForm(data=request.POST)
if form.is_valid():
comment_text = form.cleaned_data['comment']
if parent_comment is not None:
# parent comments exists
new_comment = Comment.objects.create_comment(
user=MyProfile.objects.get(user=request.user),
path=parent_comment.get_origin,
text=comment_text,
post = post,
parent=parent_comment
)
hidden_data = {
"post_id" : post.id,
"origin_path" : request.get_full_path,
"parent_id" : parent_comment.id
}
comment_form = CommentForm(hidden_data=hidden_data)
html = render_to_string('main/child_comment.html', {'comment': [new_comment],
'user': request.user,
'comment_form':comment_form})
response_data = {"status":200, "message":"abc~",
"comment":html,
'parent': True,
'parent_id': parent_comment.id,
'comment_count': parent_comment.comment_count()}
return JsonResponse(response_data)
else:
new_comment = Comment.objects.create_comment(
user=MyProfile.objects.get(user=request.user),
path=origin_path,
text=comment_text,
post = post
)
hidden_data = {
"post_id" : post.id,
"origin_path" : request.get_full_path,
"parent_id" : None
}
comment_form = CommentForm(hidden_data=hidden_data)
html = render_to_string('main/parent_comment.html', {'comment': new_comment,
'user': request.user,
'comment_form':comment_form})
response_data = {"status":200, "message":"abc~", "comment":html, 'parent': False}
return JsonResponse(response_data)
else:
print str(form)
messages.error(request, "There was an error with your comment.")
response_data = {"status":400,"message":"There was an error with your comment."}
return JsonResponse(response_data)
else:
raise Http404
With the same approach as post.html, I created view for commentThread.html and below is what I did, please let me know what I did wrong here;
def comment_thread(request, id):
hotCat = Category.objects.get_hotCat()
comment = Comment.objects.get(id=id)
comments = comment.post.commented_post.all()
for c in comments:
c.get_children()
hidden_data = {
"post_id" : comment.post.id,
"origin_path" : request.get_full_path,
"parent_id" : None
}
comment_form = CommentForm(hidden_data=hidden_data)
context = {
"comment": comment,
'comment_form':comment_form,
"hotCat":hotCat
}
return render(request, "comments/comment_thread.html", context)
In post.html, to display commenting I had three templates. post.html, parent_comment.html, and child_comment.html. I'll post them here as well.
In post.html
{% if user.is_authenticated %}
<!-- <form method="POST" id="commentForAjax" class='form-comment'>{% csrf_token %}
<input type='hidden' name='post_id' value='{{ post.id }}'/>
<input type='hidden' name='origin_path' value='{{ request.get_full_path }}'/> -->
{% crispy comment_form comment_form.helper %}
<!-- </form> -->
{% endif %}
<div class="comment_bottom" style="padding:3px;">
{% if user.is_authenticated %}
<div class="make_reply">
<a href='#' class='reply_btn'>reply</a>
<div class='reply_comment'>
<!-- <form method="POST" id="childCommentForAjax" class='form-comment'>{% csrf_token %}
<input type='hidden' name='post_id' id='post_id' value='{{ post.id }}'/>
<input type='hidden' name='origin_path' id='origin_path' value='{{ request.get_full_path }}'/>
<input type='hidden' name='parent_id' id='parent_id' value='{{ comment.id }}' /> -->
{% crispy comment_form comment_form.helper %}
<!-- </form> -->
</div>
</div>
{% endif %}
<script>
$(document).ready(function() {
$(document).on('submit', 'form', function(e){
e.preventDefault();
if($(this).parents("tr").length != 0) {
parent_id = $(this).parents("tr").attr("id").split("_")[1];
data_str = $(this).serialize() + "&parent_id=" + parent_id;
} else {
data_str = $(this).serialize();
}
$.ajax({
type:'POST',
url:'/comment/create/', // make sure , you are calling currect url
data:data_str,
success:function(json){
alert(json.message);
if(json.status==200){
var comment = json.comment.trim();
var user = json.user;
/// set `comment` and `user` using jquery to some element
if(!json.parent) {
$(comment).insertBefore('.table tr:first');
}
else {
$(comment).insertBefore('#comment_' + json.parent_id + ' #child_comment:first');
$(".replies").text("reply" + json.comment_count + "view all");
}
}
},
error:function(response){
alert("some error occured. see console for detail");
}
});
});
$('#comment-post-form').on('submit', function(event){
event.preventDefault();
console.log("form submitted!"); // sanity check
create_post();
});
</script>
For ajax below is my parent_comment.html
{% load crispy_forms_tags %}
<tr id="comment_{{ comment.id }}">
<td>
<div class="row">
<div class="col-sm-1">
<a href="{% url 'userena_profile_detail' comment.user.user %}"><img src="{{ comment.user.get_mugshot_url }}" height='48' width='48' /></a>
</div>
<div class="col-sm-11">
<div class="row">
<div class="col-sm-12">
<p> <a href="{% url 'userena_profile_detail' comment.user.user %}" style="padding:5px;">{{ comment.user.user }}</a>| <small>{{ comment.timestamp|timesince }} </small></p>
</div>
</div>
<div class="row">
<span style="margin:5px; word-break: break-all;">
{{ comment.get_comment }}
</span>
</div>
</div>
</div>
<div class="comment_bottom" style="padding:3px;">
{% if user.is_authenticated %}
<div class="make_reply">
<a href='#' class='reply_btn'>reply</a>
<div class='reply_comment'>
<form id="childCommentForAjax" method="POST">{% csrf_token %}
<input type='hidden' name='post_id' id='post_id' value='{{ post.id }}'/>
<input type='hidden' name='origin_path' id='origin_path' value='{{ comment.get_origin }}'/>
<input type='hidden' name='parent_id' id='parent_id' value='{{ comment.id }}' />
{% crispy comment_form comment_form.helper %}
</form>
</div>
</div>
{% endif %}
<div class="replyInfo">
{% if not comment.is_child %}
<div class="wholeReply">
{% if comment.comment_count %}
<a href='#' class='replies'>
{{comment.comment_count}}</a>
{% endif %}
<div class="got_replies">
<ul id="child_comment" style="list-style-type: none;">
{% for child in comment.get_children %}
<hr>
<li>
<div class="row">
<div class="col-sm-1">
<a href="{% url 'userena_profile_detail' child.user.user %}" style="float:left;"><img src="{{ child.user.get_mugshot_url }}" height='48' width='48'/></a>
</div>
<div class="col-sm-11">
<div class="row">
<div class="col-sm-12">
<p><a href="{% url 'userena_profile_detail' child.user.user %}" style="float:left;"> {{ child.user.user }}</a>| <small>{{ comment.timestamp|timesince }} </small></p>
</div>
</div>
<div class="row">
<div class="col-sm-12">
<span style="word-break: break-all; margin:5px;">
{{ child.get_comment }}</span>
</div>
</div>
</div>
</div>
</li>
{% endfor %}
</ul>
</div>
</div>
</div>
</div>
</div>
</div>
{% endif %}
</td></tr>
and below is my child.html
{% load crispy_forms_tags %}
<ul id="child_comment" style="list-style-type: none;">
{% for child in comment %}
<hr>
<li>
<div class="row">
<div class="col-sm-1">
<a href="{% url 'userena_profile_detail' child.user.user %}" style="float:left;"><img src="{{ child.user.get_mugshot_url }}" height='48' width='48'/></a>
</div>
<div class="col-sm-11">
<div class="row">
<div class="col-sm-12">
<p><a href="{% url 'userena_profile_detail' child.user.user %}" style="float:left;"> {{ child.user.user }}</a>| <small>{{ child.timestamp|timesince }} </small></p>
</div>
</div>
<div class="row">
<div class="col-sm-12">
<span style="word-break: break-all; margin:5px;">
{{ child.get_comment }}</span>
</div>
</div>
</div>
</div>
</li>
{% endfor %}
</ul>
so in commentThread.html, for the form all I did was
<div>
{% crispy comment_form comment_form.helper %}
</div>
I tried putting same ajax function I put up there but no difference..
==>the page gets refreshed without changing anything...shows no error it just gets refreshed...no data saved....]]
Can someone please help me out here? I tried to be as detailed as possible
Include the form inside a <form></form>
tag in html as it is done in parent_comment.html. And also use the <script>
block of post.html in your commentThread.html. Problem seems to be due to absence of form element in commentThread.html
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With