Commit 82e90bd18792dcc5aacfde501684f05de0f57c47
1 parent
61a6e5fd
Exists in
master
and in
5 other branches
Adding answer post creation [Issue: #163]
Showing
8 changed files
with
119 additions
and
32 deletions
Show diff stats
forum/forms.py
@@ -41,10 +41,11 @@ class PostAnswerForm(forms.ModelForm): | @@ -41,10 +41,11 @@ class PostAnswerForm(forms.ModelForm): | ||
41 | 41 | ||
42 | class Meta: | 42 | class Meta: |
43 | model = PostAnswer | 43 | model = PostAnswer |
44 | - fields = ('message', ) | 44 | + fields = ('message', 'post', ) |
45 | labels = { | 45 | labels = { |
46 | 'message': _('Message') | 46 | 'message': _('Message') |
47 | } | 47 | } |
48 | widgets = { | 48 | widgets = { |
49 | 'message': forms.Textarea(attrs={'cols': 80, 'rows': 3}), | 49 | 'message': forms.Textarea(attrs={'cols': 80, 'rows': 3}), |
50 | + 'post': forms.HiddenInput(), | ||
50 | } | 51 | } |
51 | \ No newline at end of file | 52 | \ No newline at end of file |
forum/static/js/forum.js
@@ -217,6 +217,26 @@ function answer(id, url) { | @@ -217,6 +217,26 @@ function answer(id, url) { | ||
217 | url: url, | 217 | url: url, |
218 | success: function(data) { | 218 | success: function(data) { |
219 | $("#post_"+id).find(".answer_post").html(data); | 219 | $("#post_"+id).find(".answer_post").html(data); |
220 | + $("#post_"+id).find("#id_post").val(id); | ||
221 | + | ||
222 | + var frm = $("#post_"+id).find(".answer_post_form"); | ||
223 | + frm.submit(function () { | ||
224 | + $.ajax({ | ||
225 | + type: frm.attr('method'), | ||
226 | + url: frm.attr('action'), | ||
227 | + data: frm.serialize(), | ||
228 | + success: function (data) { | ||
229 | + $("#post_"+id).find(".answer_list").append(data); | ||
230 | + | ||
231 | + $("#post_"+id).find(".answer_post").hide(); | ||
232 | + }, | ||
233 | + error: function(data) { | ||
234 | + console.log(frm.serialize()); | ||
235 | + console.log('Error'); | ||
236 | + } | ||
237 | + }); | ||
238 | + return false; | ||
239 | + }); | ||
220 | } | 240 | } |
221 | }); | 241 | }); |
222 | 242 |
forum/templates/post/post_list.html
@@ -36,8 +36,10 @@ | @@ -36,8 +36,10 @@ | ||
36 | <p class="comment-text">{{ post.message|linebreaks }}</p> | 36 | <p class="comment-text">{{ post.message|linebreaks }}</p> |
37 | </div> | 37 | </div> |
38 | <div class="answer_post"></div> | 38 | <div class="answer_post"></div> |
39 | + <div class="answer_list"> | ||
40 | + {% list_post_answer request post %} | ||
41 | + </div> | ||
39 | </div> | 42 | </div> |
40 | </div> | 43 | </div> |
41 | - {% list_post_answer request post %} | ||
42 | {% endfor %} | 44 | {% endfor %} |
43 | {% endif %} | 45 | {% endif %} |
44 | \ No newline at end of file | 46 | \ No newline at end of file |
forum/templates/post_answers/post_answer_form.html
1 | {% load static i18n %} | 1 | {% load static i18n %} |
2 | {% load widget_tweaks %} | 2 | {% load widget_tweaks %} |
3 | 3 | ||
4 | -<form method="post" action="#" enctype="multipart/form-data"> | 4 | +<form class="answer_post_form" method="post" action="{% if answer %}{% else %}{% url 'course:forum:reply_post' %}{% endif %}" enctype="multipart/form-data"> |
5 | {% csrf_token %} | 5 | {% csrf_token %} |
6 | {% for field in form %} | 6 | {% for field in form %} |
7 | - <div class="form-group {% if form.has_error %} has-error {% endif %} is-fileinput"> | ||
8 | - <div class="input-group"> | ||
9 | - <label for="{{ field.auto_id }}">{{ field.label }}</label> | ||
10 | - {% render_field field class='form-control' %} | ||
11 | - <span class="help-block">{{ field.help_text }}</span> | ||
12 | - {% if field.errors %} | ||
13 | - <div class="row"> | ||
14 | - <br /> | ||
15 | - <div class="alert alert-danger alert-dismissible" role="alert"> | ||
16 | - <button type="button" class="close" data-dismiss="alert" aria-label="Close"> | ||
17 | - <span aria-hidden="true">×</span> | ||
18 | - </button> | ||
19 | - <ul> | ||
20 | - {% for error in field.errors %} | ||
21 | - <li>{{ error }}</li> | ||
22 | - {% endfor %} | ||
23 | - </ul> | 7 | + {% if field.field.widget.input_type == 'hidden' %} |
8 | + {% render_field field class='form-control' %} | ||
9 | + {% else %} | ||
10 | + <div class="form-group {% if form.has_error %} has-error {% endif %} is-fileinput"> | ||
11 | + <div class="input-group"> | ||
12 | + <label for="{{ field.auto_id }}">{{ field.label }}</label> | ||
13 | + {% render_field field class='form-control' %} | ||
14 | + <span class="help-block">{{ field.help_text }}</span> | ||
15 | + {% if field.errors %} | ||
16 | + <div class="row"> | ||
17 | + <br /> | ||
18 | + <div class="alert alert-danger alert-dismissible" role="alert"> | ||
19 | + <button type="button" class="close" data-dismiss="alert" aria-label="Close"> | ||
20 | + <span aria-hidden="true">×</span> | ||
21 | + </button> | ||
22 | + <ul> | ||
23 | + {% for error in field.errors %} | ||
24 | + <li>{{ error }}</li> | ||
25 | + {% endfor %} | ||
26 | + </ul> | ||
27 | + </div> | ||
24 | </div> | 28 | </div> |
25 | - </div> | ||
26 | - {% endif %} | ||
27 | - <span class="input-group-btn"> | ||
28 | - <button type="submit" class="btn btn-fab btn-fab-mini"> | ||
29 | - <i class="material-icons">send</i> | ||
30 | - </button> | ||
31 | - </span> | 29 | + {% endif %} |
30 | + <span class="input-group-btn"> | ||
31 | + <button type="submit" class="btn btn-fab btn-fab-mini"> | ||
32 | + <i class="material-icons">send</i> | ||
33 | + </button> | ||
34 | + </span> | ||
35 | + </div> | ||
32 | </div> | 36 | </div> |
33 | - </div> | 37 | + {% endif %} |
34 | {% endfor %} | 38 | {% endfor %} |
35 | - | ||
36 | </form> | 39 | </form> |
37 | \ No newline at end of file | 40 | \ No newline at end of file |
forum/templates/post_answers/post_answer_list.html
@@ -2,11 +2,11 @@ | @@ -2,11 +2,11 @@ | ||
2 | 2 | ||
3 | {% if answers|length > 0 %} | 3 | {% if answers|length > 0 %} |
4 | {% for answer in answers %} | 4 | {% for answer in answers %} |
5 | - <div class="row" style="background-color: #e0e0e0"> | 5 | + <div id="answer_{{ answer_id }}" class="row" style="background-color: #e0e0e0"> |
6 | <div class="col-sm-12 col-xs-12"> | 6 | <div class="col-sm-12 col-xs-12"> |
7 | <h3 class="user-name"> | 7 | <h3 class="user-name"> |
8 | {{ answer.user }} | 8 | {{ answer.user }} |
9 | - {% if request.user|has_role:'system_admin' or request.user|has_role:'professor' and request.user == answer.user %} | 9 | + {% if request.user|has_role:'system_admin' or request.user == answer.user %} |
10 | <div class="pull-right"> | 10 | <div class="pull-right"> |
11 | <div class="btn-group icon-more-horiz"> | 11 | <div class="btn-group icon-more-horiz"> |
12 | <a class="btn btn-default btn-xs dropdown-toggle" type="button" id="dropdownMenu1" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false"> | 12 | <a class="btn btn-default btn-xs dropdown-toggle" type="button" id="dropdownMenu1" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false"> |
@@ -0,0 +1,26 @@ | @@ -0,0 +1,26 @@ | ||
1 | +{% load i18n permission_tags %} | ||
2 | + | ||
3 | +<div id="answer_{{ answer_id }}" class="row" style="background-color: #e0e0e0"> | ||
4 | + <div class="col-sm-12 col-xs-12"> | ||
5 | + <h3 class="user-name"> | ||
6 | + {{ answer.user }} | ||
7 | + {% if request.user|has_role:'system_admin' or request.user == answer.user %} | ||
8 | + <div class="pull-right"> | ||
9 | + <div class="btn-group icon-more-horiz"> | ||
10 | + <a class="btn btn-default btn-xs dropdown-toggle" type="button" id="dropdownMenu1" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false"> | ||
11 | + <i class="material-icons">more_horiz</i> | ||
12 | + </a> | ||
13 | + <ul class="dropdown-menu" aria-labelledby="dropdownMenu1"> | ||
14 | + <li><a href="javascript:void(0)"><i class="material-icons">create</i> {% trans 'Edit' %}</a></li> | ||
15 | + <li><a href="javascript:void(0)"><i class="material-icons">delete_sweep</i> {% trans 'Remove' %}</a></li> | ||
16 | + </ul> | ||
17 | + </div> | ||
18 | + </div> | ||
19 | + {% endif %} | ||
20 | + </h3> | ||
21 | + <div class="card-data"> | ||
22 | + <p class="comment-date"><i class="fa fa-clock-o"></i> {{ answer.answer_date|timesince }} {% trans 'ago' %}</p> | ||
23 | + </div> | ||
24 | + <p class="comment-text">{{ answer.message|linebreaks }}</p> | ||
25 | + </div> | ||
26 | +</div> | ||
0 | \ No newline at end of file | 27 | \ No newline at end of file |
forum/urls.py
@@ -18,5 +18,6 @@ urlpatterns = [ | @@ -18,5 +18,6 @@ urlpatterns = [ | ||
18 | url(r'^post_deleted/$', views.post_deleted, name='deleted_post'), | 18 | url(r'^post_deleted/$', views.post_deleted, name='deleted_post'), |
19 | url(r'^post_answers/$', views.PostAnswerIndex.as_view(), name='post_answers'), | 19 | url(r'^post_answers/$', views.PostAnswerIndex.as_view(), name='post_answers'), |
20 | url(r'^reply_post/$', views.CreatePostAnswerView.as_view(), name='reply_post'), | 20 | url(r'^reply_post/$', views.CreatePostAnswerView.as_view(), name='reply_post'), |
21 | + url(r'^render_post_answer/([\w_-]+)/$', views.render_post_answer, name='render_post_answer'), | ||
21 | url(r'^(?P<slug>[\w_-]+)/$', views.ForumDetailView.as_view(), name='view'), | 22 | url(r'^(?P<slug>[\w_-]+)/$', views.ForumDetailView.as_view(), name='view'), |
22 | ] | 23 | ] |
forum/views.py
@@ -10,6 +10,10 @@ from courses.models import Topic | @@ -10,6 +10,10 @@ from courses.models import Topic | ||
10 | 10 | ||
11 | from .forms import ForumForm, PostForm, PostAnswerForm | 11 | from .forms import ForumForm, PostForm, PostAnswerForm |
12 | 12 | ||
13 | +""" | ||
14 | + Forum Section | ||
15 | +""" | ||
16 | + | ||
13 | class ForumIndex(LoginRequiredMixin, generic.ListView): | 17 | class ForumIndex(LoginRequiredMixin, generic.ListView): |
14 | login_url = reverse_lazy("core:home") | 18 | login_url = reverse_lazy("core:home") |
15 | redirect_field_name = 'next' | 19 | redirect_field_name = 'next' |
@@ -103,6 +107,10 @@ class ForumDetailView(LoginRequiredMixin, generic.DetailView): | @@ -103,6 +107,10 @@ class ForumDetailView(LoginRequiredMixin, generic.DetailView): | ||
103 | 107 | ||
104 | return context | 108 | return context |
105 | 109 | ||
110 | +""" | ||
111 | + Post Section | ||
112 | +""" | ||
113 | + | ||
106 | class CreatePostView(LoginRequiredMixin, generic.edit.CreateView): | 114 | class CreatePostView(LoginRequiredMixin, generic.edit.CreateView): |
107 | login_url = reverse_lazy("core:home") | 115 | login_url = reverse_lazy("core:home") |
108 | redirect_field_name = 'next' | 116 | redirect_field_name = 'next' |
@@ -154,6 +162,12 @@ class PostDeleteView(LoginRequiredMixin, generic.DeleteView): | @@ -154,6 +162,12 @@ class PostDeleteView(LoginRequiredMixin, generic.DeleteView): | ||
154 | def post_deleted(request): | 162 | def post_deleted(request): |
155 | return HttpResponse(_("Post deleted successfully.")) | 163 | return HttpResponse(_("Post deleted successfully.")) |
156 | 164 | ||
165 | + | ||
166 | + | ||
167 | +""" | ||
168 | + Post Answer Section | ||
169 | +""" | ||
170 | + | ||
157 | class PostAnswerIndex(LoginRequiredMixin, generic.ListView): | 171 | class PostAnswerIndex(LoginRequiredMixin, generic.ListView): |
158 | login_url = reverse_lazy("core:home") | 172 | login_url = reverse_lazy("core:home") |
159 | redirect_field_name = 'next' | 173 | redirect_field_name = 'next' |
@@ -174,4 +188,24 @@ class CreatePostAnswerView(LoginRequiredMixin, generic.edit.CreateView): | @@ -174,4 +188,24 @@ class CreatePostAnswerView(LoginRequiredMixin, generic.edit.CreateView): | ||
174 | 188 | ||
175 | template_name = 'post_answers/post_answer_form.html' | 189 | template_name = 'post_answers/post_answer_form.html' |
176 | form_class = PostAnswerForm | 190 | form_class = PostAnswerForm |
177 | - success_url = reverse_lazy('course:forum:index') | ||
178 | \ No newline at end of file | 191 | \ No newline at end of file |
192 | + | ||
193 | + def form_valid(self, form): | ||
194 | + self.object = form.save(commit = False) | ||
195 | + self.object.user = self.request.user | ||
196 | + | ||
197 | + self.object.save() | ||
198 | + | ||
199 | + return super(CreatePostAnswerView, self).form_valid(form) | ||
200 | + | ||
201 | + def get_success_url(self): | ||
202 | + self.success_url = reverse('course:forum:render_post_answer', args = (self.object.id, )) | ||
203 | + | ||
204 | + return self.success_url | ||
205 | + | ||
206 | +def render_post_answer(request, answer): | ||
207 | + last_answer = get_object_or_404(PostAnswer, id = answer) | ||
208 | + | ||
209 | + context = {} | ||
210 | + context['answer'] = last_answer | ||
211 | + | ||
212 | + return render(request, "post_answers/post_answer_render.html", context) | ||
179 | \ No newline at end of file | 213 | \ No newline at end of file |