From 038d7f89e51abc47119870ea3d0cb54ddb0ec27e Mon Sep 17 00:00:00 2001 From: Rocky Duan Date: Fri, 3 Aug 2012 14:26:37 -0400 Subject: [PATCH] ajax editing comments / threads --- .../django_comment_client/base/views.py | 12 ++++--- .../django_comment_client/forum/views.py | 21 ++++++++---- .../coffee/src/discussion/content.coffee | 32 +++++++++---------- .../coffee/src/discussion/discussion.coffee | 14 ++++---- lms/static/coffee/src/discussion/main.coffee | 6 ++-- lms/static/coffee/src/discussion/utils.coffee | 20 ++++++++---- lms/templates/discussion/_forum.html | 6 +++- lms/templates/discussion/_inline.html | 6 +++- lms/templates/discussion/_thread.html | 8 ++--- .../discussion/ajax_create_thread.html | 2 +- .../discussion/ajax_update_comment.html | 3 ++ .../discussion/ajax_update_thread.html | 3 ++ lms/templates/discussion/thread.html | 6 ++-- 13 files changed, 83 insertions(+), 56 deletions(-) create mode 100644 lms/templates/discussion/ajax_update_comment.html create mode 100644 lms/templates/discussion/ajax_update_thread.html diff --git a/lms/djangoapps/django_comment_client/base/views.py b/lms/djangoapps/django_comment_client/base/views.py index 6b8986a918..ee545cf389 100644 --- a/lms/djangoapps/django_comment_client/base/views.py +++ b/lms/djangoapps/django_comment_client/base/views.py @@ -76,16 +76,18 @@ def create_thread(request, course_id, commentable_id): def update_thread(request, course_id, thread_id): attributes = extract(request.POST, ['body', 'title', 'tags']) response = comment_client.update_thread(thread_id, attributes) - if response.is_ajax(): + if request.is_ajax(): context = { 'thread': response, + 'course_id': course_id, } html = render_to_string('discussion/ajax_update_thread.html', context) return JsonResponse({ 'html': html, 'content': response, }) - return JsonResponse(response) + else: + return JsonResponse(response) def _create_comment(request, course_id, _response_from_attributes): attributes = extract(request.POST, ['body']) @@ -128,16 +130,18 @@ def delete_thread(request, course_id, thread_id): def update_comment(request, course_id, comment_id): attributes = extract(request.POST, ['body']) response = comment_client.update_comment(comment_id, attributes) - if response.is_ajax(): + if request.is_ajax(): context = { 'comment': response, + 'course_id': course_id, } html = render_to_string('discussion/ajax_update_comment.html', context) return JsonResponse({ 'html': html, 'content': response, }) - return JsonResponse(response) + else: + return JsonResponse(response) @instructor_only @login_required diff --git a/lms/djangoapps/django_comment_client/forum/views.py b/lms/djangoapps/django_comment_client/forum/views.py index 8855bf79ec..e3c40d4af8 100644 --- a/lms/djangoapps/django_comment_client/forum/views.py +++ b/lms/djangoapps/django_comment_client/forum/views.py @@ -48,6 +48,8 @@ def render_discussion(request, course_id, threads, discussion_id=None, \ 'forum': (lambda: reverse('django_comment_client.forum.views.forum_form_discussion', args=[course_id, discussion_id])), }[discussion_type]() + annotated_content_info = {thread['id']: get_annotated_content_info(thread, request.user.id) for thread in threads} + context = { 'threads': threads, 'discussion_id': discussion_id, @@ -58,6 +60,7 @@ def render_discussion(request, course_id, threads, discussion_id=None, \ 'discussion_type': discussion_type, 'base_url': base_url, 'query_params': utils.strip_none(utils.extract(query_params, ['page', 'sort_key', 'sort_order', 'tags', 'text'])), + 'annotated_content_info': json.dumps(annotated_content_info), } context = dict(context.items() + query_params.items()) return render_to_string(template, context) @@ -119,13 +122,17 @@ def forum_form_discussion(request, course_id, discussion_id): } return render_to_response('discussion/index.html', context) -def get_annotated_content_info(thread, user_id): + +def get_annotated_content_info(content, user_id): + return { + 'editable': str(content['user_id']) == str(user_id), # TODO may relax this to instructors + } + +def get_annotated_content_infos(thread, user_id): infos = {} def _annotate(content): - infos[str(content['id'])] = { - 'editable': str(content['user_id']) == str(user_id), # TODO may relax this to instructors - } - for child in content['children']: + infos[str(content['id'])] = get_annotated_content_info(content, user_id) + for child in content.get('children', []): _annotate(child) _annotate(thread) return infos @@ -134,7 +141,7 @@ def render_single_thread(request, course_id, thread_id): thread = comment_client.get_thread(thread_id, recursive=True) - annotated_content_info = get_annotated_content_info(thread=thread, \ + annotated_content_info = get_annotated_content_infos(thread=thread, \ user_id=request.user.id) context = { @@ -151,7 +158,7 @@ def single_thread(request, course_id, discussion_id, thread_id): if request.is_ajax(): thread = comment_client.get_thread(thread_id, recursive=True) - annotated_content_info = get_annotated_content_info(thread=thread, \ + annotated_content_info = get_annotated_content_infos(thread=thread, \ user_id=request.user.id) context = {'thread': thread} html = render_to_string('discussion/_ajax_single_thread.html', context) diff --git a/lms/static/coffee/src/discussion/content.coffee b/lms/static/coffee/src/discussion/content.coffee index 90d1ea55a8..ea9f27d737 100644 --- a/lms/static/coffee/src/discussion/content.coffee +++ b/lms/static/coffee/src/discussion/content.coffee @@ -19,23 +19,22 @@ Discussion = @Discussion $replyView.show() else thread_id = $discussionContent.parents(".thread").attr("_id") - view = { + view = id: id showWatchCheckbox: not Discussion.isSubscribed(thread_id, "thread") - } $discussionContent.append Mustache.render Discussion.replyTemplate, view Discussion.makeWmdEditor $content, $local, "reply-body" $local(".discussion-submit-post").click -> handleSubmitReply(this) $local(".discussion-cancel-post").click -> handleCancelReply(this) $local(".discussion-reply").hide() + $local(".discussion-edit").hide() handleCancelReply = (elem) -> $replyView = $local(".discussion-reply-new") if $replyView.length $replyView.hide() - #reply = Discussion.generateDiscussionLink("discussion-reply", "Reply", handleReply) - #$(elem).replaceWith(reply) $local(".discussion-reply").show() + $local(".discussion-edit").show() handleSubmitReply = (elem) -> if $content.hasClass("thread") @@ -68,6 +67,7 @@ Discussion = @Discussion Discussion.bindContentEvents($comment) $local(".discussion-reply-new").hide() $local(".discussion-reply").show() + $local(".discussion-edit").show() $discussionContent.attr("status", "normal") ) @@ -97,15 +97,7 @@ Discussion = @Discussion } $discussionContent.append Mustache.render Discussion.editThreadTemplate, view Discussion.makeWmdEditor $content, $local, "thread-body-edit" - $local(".thread-tags-edit").tagsInput - autocomplete_url: Discussion.urlFor('tags_autocomplete') - autocomplete: - remoteDataType: 'json' - interactive: true - defaultText: "Tag your post: press enter after each tag" - height: "30px" - width: "100%" - removeWithBackspace: true + $local(".thread-tags-edit").tagsInput Discussion.tagsInputOptions() $local(".discussion-submit-update").unbind("click").click -> handleSubmitEditThread(this) $local(".discussion-cancel-update").unbind("click").click -> handleCancelEdit(this) @@ -114,13 +106,16 @@ Discussion = @Discussion title = $local(".thread-title-edit").val() body = Discussion.getWmdContent $content, $local, "thread-body-edit" tags = $local(".thread-tags-edit").val() - $.ajax + Discussion.safeAjax + $elem: $(elem) url: url type: "POST" dataType: 'json' data: {title: title, body: body, tags: tags}, success: Discussion.formErrorHandler($local(".discussion-update-errors"), (response, textStatus) -> - Discussion.handleAnchorAndReload(response) + $discussionContent.replaceWith(response.html) + Discussion.initializeContent($content) + Discussion.bindContentEvents($content) ) handleEditComment = (elem) -> @@ -138,13 +133,16 @@ Discussion = @Discussion handleSubmitEditComment= (elem) -> url = Discussion.urlFor('update_comment', id) body = Discussion.getWmdContent $content, $local, "comment-body-edit" - $.ajax + Discussion.safeAjax + $elem: $(elem) url: url type: "POST" dataType: "json" data: {body: body} success: Discussion.formErrorHandler($local(".discussion-update-errors"), (response, textStatus) -> - Discussion.handleAnchorAndReload(response) + $discussionContent.replaceWith(response.html) + Discussion.initializeContent($content) + Discussion.bindContentEvents($content) ) handleEndorse = (elem) -> diff --git a/lms/static/coffee/src/discussion/discussion.coffee b/lms/static/coffee/src/discussion/discussion.coffee index 3bd6718562..8141cf9c36 100644 --- a/lms/static/coffee/src/discussion/discussion.coffee +++ b/lms/static/coffee/src/discussion/discussion.coffee @@ -7,9 +7,9 @@ initializeVote = (index, content) -> $content = $(content) $local = Discussion.generateLocal($content.children(".discussion-content")) id = $content.attr("_id") - if id in $$user_info.upvoted_ids + if Discussion.isUpvoted id $local(".discussion-vote-up").addClass("voted") - else if id in $$user_info.downvoted_ids + else if Discussion.isDownvoted id $local(".discussion-vote-down").addClass("voted") subscriptionLink = (type, id) -> @@ -40,8 +40,7 @@ subscriptionLink = (type, id) -> $(elem).replaceWith followLink() dataType: 'json' - if type == 'discussion' and id in $$user_info.subscribed_commentable_ids \ - or type == 'thread' and id in $$user_info.subscribed_thread_ids + if Discussion.isSubscribed(id, type) unfollowLink() else followLink() @@ -67,10 +66,9 @@ initializeFollowThread = (index, thread) -> $local = Discussion.generateLocal(discussion) - if $$user_info? - $local(".comment").each(initializeVote) - $local(".thread").each(initializeVote).each(initializeFollowThread) - #initializeFollowDiscussion(discussion) TODO move this somewhere else + $local(".comment").each(initializeVote) + $local(".thread").each(initializeVote).each(initializeFollowThread) + #initializeFollowDiscussion(discussion) TODO move this somewhere else $local(".new-post-tags").tagsInput Discussion.tagsInputOptions() diff --git a/lms/static/coffee/src/discussion/main.coffee b/lms/static/coffee/src/discussion/main.coffee index 6187763532..4828c60c4d 100644 --- a/lms/static/coffee/src/discussion/main.coffee +++ b/lms/static/coffee/src/discussion/main.coffee @@ -1,14 +1,16 @@ $ -> + toggle = -> + $('.course-wrapper').toggleClass('closed') + Discussion = window.Discussion - console.log "here" if $('#accordion').length active = $('#accordion ul:has(li.active)').index('#accordion ul') $('#accordion').bind('accordionchange', @log).accordion active: if active >= 0 then active else 1 header: 'h3' autoHeight: false - $('#open_close_accordion a').click @toggle + $('#open_close_accordion a').click toggle $('#accordion').show() $(".discussion-module").each (index, elem) -> diff --git a/lms/static/coffee/src/discussion/utils.coffee b/lms/static/coffee/src/discussion/utils.coffee index ffb25ea0ae..424ab6be85 100644 --- a/lms/static/coffee/src/discussion/utils.coffee +++ b/lms/static/coffee/src/discussion/utils.coffee @@ -69,12 +69,20 @@ wmdEditors = {} removeWithBackspace: true isSubscribed: (id, type) -> - if type == "thread" - id in $$user_info.subscribed_thread_ids - else if type == "commentable" or type == "discussion" - id in $$user_info.subscribed_commentable_ids - else - id in $$user_info.subscribed_user_ids + $$user_info? and ( + if type == "thread" + id in $$user_info.subscribed_thread_ids + else if type == "commentable" or type == "discussion" + id in $$user_info.subscribed_commentable_ids + else + id in $$user_info.subscribed_user_ids + ) + + isUpvoted: (id) -> + $$user_info? and (id in $$user_info.upvoted_ids) + + isDownvoted: (id) -> + $$user_info? and (id in $$user_info.downvoted_ids) formErrorHandler: (errorsField, success) -> (response, textStatus, xhr) -> diff --git a/lms/templates/discussion/_forum.html b/lms/templates/discussion/_forum.html index 080305f5d3..ba0567c076 100644 --- a/lms/templates/discussion/_forum.html +++ b/lms/templates/discussion/_forum.html @@ -17,7 +17,7 @@ <%include file="_sort.html" />
% for thread in threads: - ${renderer.render_thread(course_id, thread, edit_thread=False, show_comments=False)} + ${renderer.render_thread(course_id, thread, show_comments=False)} % endfor
<%include file="_paginator.html" /> @@ -31,4 +31,8 @@ diff --git a/lms/templates/discussion/_inline.html b/lms/templates/discussion/_inline.html index 70681b1cf4..b5d1067bd9 100644 --- a/lms/templates/discussion/_inline.html +++ b/lms/templates/discussion/_inline.html @@ -10,7 +10,7 @@
% for thread in threads: - ${renderer.render_thread(course_id, thread, edit_thread=False, show_comments=False)} + ${renderer.render_thread(course_id, thread, show_comments=False)} % endfor
<%include file="_paginator.html" /> @@ -24,4 +24,8 @@ diff --git a/lms/templates/discussion/_thread.html b/lms/templates/discussion/_thread.html index 108b7c8ae5..e033519eb7 100644 --- a/lms/templates/discussion/_thread.html +++ b/lms/templates/discussion/_thread.html @@ -3,9 +3,9 @@ <%! from dateutil.parser import parse %> <%! import urllib %> -<%def name="render_thread(course_id, thread, edit_thread=False, show_comments=False)"> +<%def name="render_thread(course_id, thread, show_comments=False)">
- ${render_content(thread, "thread", edit_thread=edit_thread, show_comments=show_comments)} + ${render_content(thread, "thread", show_comments=show_comments)} % if show_comments: ${render_comments(thread.get('children', []))} % endif @@ -77,9 +77,7 @@
${render_info(content)} ${render_link("discussion-link discussion-reply discussion-reply-" + type, "Reply")} - % if type == "thread" and kwargs['edit_thread'] or type == "comment": - ${render_link("discussion-link discussion-edit", "Edit")} - % endif + ${render_link("discussion-link discussion-edit", "Edit")} % if type == "comment" and request.user.is_staff: % if content['endorsed']: diff --git a/lms/templates/discussion/ajax_create_thread.html b/lms/templates/discussion/ajax_create_thread.html index 792a71e52d..e05c586232 100644 --- a/lms/templates/discussion/ajax_create_thread.html +++ b/lms/templates/discussion/ajax_create_thread.html @@ -1,3 +1,3 @@ <%namespace name="renderer" file="_thread.html"/> -${renderer.render_thread(course_id, thread, edit_thread=True, show_comments=False)} +${renderer.render_content(thread, "thread")} diff --git a/lms/templates/discussion/ajax_update_comment.html b/lms/templates/discussion/ajax_update_comment.html new file mode 100644 index 0000000000..d0b371e029 --- /dev/null +++ b/lms/templates/discussion/ajax_update_comment.html @@ -0,0 +1,3 @@ +<%namespace name="renderer" file="_thread.html"/> + +${renderer.render_content(comment, "comment")} diff --git a/lms/templates/discussion/ajax_update_thread.html b/lms/templates/discussion/ajax_update_thread.html new file mode 100644 index 0000000000..e05c586232 --- /dev/null +++ b/lms/templates/discussion/ajax_update_thread.html @@ -0,0 +1,3 @@ +<%namespace name="renderer" file="_thread.html"/> + +${renderer.render_content(thread, "thread")} diff --git a/lms/templates/discussion/thread.html b/lms/templates/discussion/thread.html index e49d555d59..0f23988331 100644 --- a/lms/templates/discussion/thread.html +++ b/lms/templates/discussion/thread.html @@ -73,10 +73,8 @@ <%def name="render_bottom_bar(content, type, **kwargs)">
${render_info(content)} - % if type == "thread" and kwargs['edit_thread'] or type == "comment": - ${render_link("discussion-link discussion-reply", "Reply")} - ${render_link("discussion-link discussion-edit", "Edit")} - % endif + ${render_link("discussion-link discussion-reply", "Reply")} + ${render_link("discussion-link discussion-edit", "Edit")}