Commit d49338c9 by Rocky Duan

integrated search; refactored some frontend code

parent 3267aa17
......@@ -11,10 +11,11 @@ from datehelper import time_ago_in_words
class DiscussionModule(XModule):
def get_html(self):
context = {
'threads': comment_client.get_threads(self.discussion_id, recursive=True),
'threads': comment_client.get_threads(self.discussion_id, recursive=False),
'time_ago_in_words': time_ago_in_words,
'parse': dateutil.parser.parse,
'commentable_id': self.discussion_id,
'discussion_id': self.discussion_id,
'search_bar': '',
}
return self.system.render_template('discussion/inline.html', context)
......
$ ->
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
$('#accordion').show()
$("section.discussion").each (index, discussion) ->
Discussion.bindDiscussionEvents(discussion)
Discussion =
urlFor: (name, param) ->
{
create_thread : "/discussions/#{param}/threads/create"
update_thread : "/discussions/threads/#{param}/update"
create_comment : "/discussions/threads/#{param}/reply"
delete_thread : "/discussions/threads/#{param}/delete"
update_comment : "/discussions/comments/#{param}/update"
endorse_comment : "/discussions/comments/#{param}/endorse"
create_sub_comment : "/discussions/comments/#{param}/reply"
delete_comment : "/discussions/comments/#{param}/delete"
upvote_comment : "/discussions/comments/#{param}/upvote"
downvote_comment : "/discussions/comments/#{param}/downvote"
upvote_thread : "/discussions/threads/#{param}/upvote"
downvote_thread : "/discussions/threads/#{param}/downvote"
search : "/discussions/forum/search"
}[name]
handleAnchorAndReload: (response) ->
window.location = window.location.pathname + "#" + response['id']
window.location.reload()
bindContentEvents: (content) ->
$content = $(content)
$discussionContent = $content.children(".discussion-content")
$local = (selector) -> $discussionContent.find(selector)
discussionContentHoverIn = ->
status = $discussionContent.attr("status") || "normal"
if status == "normal"
$local(".discussion-link").show()
else if status == "reply"
$local(".discussion-cancel-reply").show()
$local(".discussion-submit-reply").show()
else if status == "edit"
$local(".discussion-cancel-edit").show()
$local(".discussion-update-edit").show()
discussionContentHoverOut = ->
$local(".discussion-link").hide()
$discussionContent.hover(discussionContentHoverIn, discussionContentHoverOut)
generateDiscussionLink = (cls, txt, handler) ->
$("<a>").addClass("discussion-link").
attr("href", "javascript:void(0)").
addClass(cls).html(txt).
click(-> handler(this))
handleReply = (elem) ->
editView = $local(".discussion-content-edit")
if editView.length
editView.show()
else
editView = $("<div>").addClass("discussion-content-edit")
editView.append($("<textarea>").addClass("comment-edit"))
$discussionContent.append(editView)
cancelReply = generateDiscussionLink("discussion-cancel-reply", "Cancel", handleCancelReply)
submitReply = generateDiscussionLink("discussion-submit-reply", "Submit", handleSubmitReply)
$local(".discussion-link").hide()
$(elem).after(submitReply).replaceWith(cancelReply)
$discussionContent.attr("status", "reply")
handleCancelReply = (elem) ->
editView = $local(".discussion-content-edit")
if editView.length
editView.hide()
$local(".discussion-submit-reply").remove()
reply = generateDiscussionLink("discussion-reply", "Reply", handleReply)
$local(".discussion-link").show()
$(elem).replaceWith(reply)
$discussionContent.attr("status", "normal")
handleSubmitReply = (elem) ->
if $content.hasClass("thread")
url = Discussion.urlFor('create_comment', $content.attr("_id"))
else if $content.hasClass("comment")
url = Discussion.urlFor('create_sub_comment', $content.attr("_id"))
else
return
body = $local(".comment-edit").val()
$.post url, {body: body}, (response, textStatus) ->
if textStatus == "success"
Discussion.handleAnchorAndReload(response)
, 'json'
$local(".discussion-reply").click ->
handleReply(this)
$local(".discussion-cancel-reply").click ->
handleCancelReply(this)
bindDiscussionEvents: (discussion) ->
$discussion = $(discussion)
$discussionNonContent = $discussion.children(".discussion-non-content")
$local = (selector) -> $discussionNonContent.find(selector)
handleSearch = (text, isSearchWithinBoard) ->
if text.length
if $local(".discussion-search-within-board").is(":checked")
window.location = window.location.pathname + '?text=' + encodeURI(text)
else
window.location = Discussion.urlFor('search') + '?text=' + encodeURI(text)
handleSubmitNewThread = (elem) ->
title = $local(".new-post-title").val()
body = $local(".new-post-body").val()
url = Discussion.urlFor('create_thread', $local(".new-post-form").attr("_id"))
$.post url, {title: title, body: body}, (response, textStatus) ->
if textStatus == "success"
Discussion.handleAnchorAndReload(response)
, 'json'
$local(".discussion-search-form").submit (event) ->
event.preventDefault()
text = $local(".discussion-search-text").val()
isSearchWithinBoard = $local(".discussion-search-within-board").is(":checked")
handleSearch(text, isSearchWithinBoard)
$local(".discussion-new-post").click ->
handleSubmitNewThread(this)
$local(".discussion-search").click ->
$local(".new-post-form").submit()
$discussion.find(".thread").each (index, thread) ->
Discussion.bindContentEvents(thread)
$discussion.find(".comment").each (index, comment) ->
Discussion.bindContentEvents(comment)
$comment_margin_left: 20px;
$discussion_title_size: 1.6em;
$comment_title_size: 1.2em;
$comment_body_size: 1.0em;
$comment_info_size: 0.75em;
$discussion_input_width: 60%;
@mixin discussion-font {
font-family: "Comic Sans MS", cursive, sans-serif !important;
}
@mixin discussion-clickable {
color: black;
&:hover {
text-decoration: none;
}
}
.course-content {
.discussion {
margin-left: 40px;
margin-top: 15px;
}
}
.discussion {
.discussion-search-form {
margin-bottom: 40px;
.discussion-search {
@include discussion-font;
color: #1d9dd9;
display: block;
margin-top: 10px;
font-weight: bold;
}
.discussion-search-text {
@include discussion-font;
}
}
.discussion-title {
@include discussion-font;
@include discussion-clickable;
font-size: $discussion_title_size;
font-weight: bold;
margin-bottom: 20px;
display: block;
}
.new-post-form {
.new-post-title, .new-post-body {
@include discussion-font;
display: block !important;
width: $discussion_input_width !important;
}
.new-post-body {
margin-top: 10px;
}
.discussion-new-post {
@include discussion-font;
color: #1d9dd9;
display: block;
margin-top: 10px;
font-weight: bold;
}
}
.thread {
//display: none;
margin-top: 30px;
margin-bottom: 30px;
.thread-title {
@include discussion-font;
@include discussion-clickable;
font-size: $comment_title_size;
font-weight: bold;
display: block;
}
.thread-body {
@include discussion-font;
font-size: $comment_body_size;
margin-top: 7px;
margin-bottom: 2px;
}
.info {
@include discussion-font;
font-size: $comment_info_size;
font-style: italic;
margin-top: 5px;
color: gray;
.discussion-link {
margin-left: 2px;
}
.discussion-reply {
margin-left: 4px;
}
.discussion-link {
@include discussion-font;
display: inline-block;
color: #1d9dd9;
display: none;
}
}
.discussion-content:hover {
.discussion-link {
display: inline-block;
}
}
.discussion-content {
.discussion-content-edit {
.comment-edit {
@include discussion-font;
width: $discussion_input_width !important;
margin-left: $comment_margin_left;
font-size: $comment_body_size;
margin-top: 10px;
}
}
}
.comments {
//display: none;
margin-left: $comment_margin_left;
.comment {
.comment-body {
@include discussion-font;
font-size: $comment_body_size;
margin-top: 10px;
display: block;
color: black;
}
}
}
}
}
<%page args="active_page" />
<%
def url_class(url):
if url == active_page:
return "active"
return ""
%>
<%! from django.core.urlresolvers import reverse %>
<nav class="${active_page} course-material">
<div class="inner-wrapper">
<ol class="course-tabs">
<li class="courseware"><a href="${reverse('courseware', args=[course.id])}" class="${url_class('courseware')}">Courseware</a></li>
<li class="info"><a href="${reverse('info', args=[course.id])}" class="${url_class('info')}">Course Info</a></li>
% if user.is_authenticated():
<li class="book"><a href="${reverse('book', args=[course.id])}" class="${url_class('book')}">Textbook</a></li>
<li class="discussion"><a href="${reverse('django_comment_client.forum.views.forum_form_discussion', args=[course.id.replace('/', '-'), course.id.replace('/', '_').replace('.', '_')])}" class="${url_class('discussion')}">Discussion</a></li>
% endif
<li class="wiki"><a href="${reverse('wiki_root', args=[course.id])}" class="${url_class('wiki')}">Wiki</a></li>
% if user.is_authenticated():
<li class="profile"><a href="${reverse('profile', args=[course.id])}" class="${url_class('profile')}">Profile</a></li>
% endif
</ol>
</div>
</nav>
<%! from django.core.urlresolvers import reverse %>
<%
def url_for(board):
return reverse('django_comment_client.forum.views.forum_form_discussion', args=[course.id.replace('/', '-'), board['discussion_id']])
%>
<%def name="make_category(category, boards)">
<h3><a href="#">${category}</a></h3>
<ul>
% for board in boards:
<li${' class="active"' if active == board['discussion_id'] else ''}>
<a href="${url_for(board)}">
<p>${board['title']}</p>
</a>
% endfor
</ul>
</%def>
% for category, boards in discussion_info.items():
${make_category(category, boards)}
% endfor
<%inherit file="../main.html" />
<%namespace name='static' file='../static_content.html'/>
<%block name="bodyclass">courseware discussion</%block>
<%block name="title"><title>Discussion – MITx 6.002x</title></%block>
<%block name="headextra">
<script type="text/javascript" src="${static.url('js/vendor/flot/jquery.flot.js')}"></script>
</%block>
<%block name="js_extra">
<!-- TODO: http://docs.jquery.com/Plugins/Validation -->
<script type="text/javascript">
document.write('\x3Cscript type="text/javascript" src="' +
document.location.protocol + '//www.youtube.com/player_api">\x3C/script>');
</script>
</%block>
##<%include file="../course_navigation.html" args="active_page='discussion'" />
<section class="container">
<div class="course-wrapper">
<section aria-label="Course Navigation" class="course-index">
<header id="open_close_accordion">
<h2>Discussion Boards</h2>
<a href="#">close</a>
</header>
<div id="accordion" style="display:none">
<nav>
${accordion}
</nav>
</div>
</section>
<section class="course-content">
${content}
</section>
</div>
</section>
<%! from django.core.urlresolvers import reverse %>
<%
def url_for(thread_id):
return reverse('django_comment_client.forum.views.single_thread', args=[thread_id])
%>
<section class="discussion">
<div class="discussion-non-content">
<a class="discussion-title" href="javascript:void(0)">Discussion</a>
${search_bar}
<form class="new-post-form" _id="${discussion_id}">
<input type="text" class="new-post-title" placeholder="Title"/>
<textarea class="new-post-body"></textarea>
<a class="discussion-new-post" href="javascript:void(0)">New Post</a>
</form>
</div>
% for thread in threads:
${render_thread(thread)}
% endfor
</section>
<%def name="render_thread(thread, edit_thread=False, show_comments=False)">
<div class="thread" _id="${thread['id']}">
<div class="discussion-content">
<a class="thread-title" name="${thread['id']}" href="${url_for(thread['id'])}">${thread['title']}</a>
<div class="discussion-content-view">
<div class="thread-body">${thread['body']}</div>
<div class="info">
${render_info(thread)}
% if edit_thread:
${render_reply('')}
${render_edit('')}
% endif
</div>
</div>
</div>
% if show_comments:
<div class="comments">
${render_comments(thread['children'])}
</div>
% endif
</div>
</%def>
<%def name="render_comments(comments)">
% for comment in comments:
<div class="comment" _id="${comment['id']}">
<div class="discussion-content">
<div class="discussion-content-view">
<a class="comment-body" name="${comment['id']}">${comment['body']}</a>
<div class="info">
${render_info(comment)}
${render_reply('')}
${render_edit('')}
</div>
</div>
</div>
<div class="comments">
${render_comments(comment['children'])}
</div>
</div>
% endfor
</%def>
<%def name="render_info(content)">
${time_ago_in_words(parse(content['updated_at']))} ago by user No.${content['user_id']}
</%def>
<%def name="render_reply(url)">
<a class="discussion-link discussion-reply" href="javascript:void(0)">Reply</a>
</%def>
<%def name="render_edit(url)">
<a class="discussion-link discussion-edit" href="javascript:void(0)">Edit</a>
</%def>
<%! from django.core.urlresolvers import reverse %>
<%
def url_for_search():
return reverse('django_comment_client.forum.views.search')
%>
<form action="${url_for_search()}" method="get" class="discussion-search-form">
<input type="text" class="discussion-search-text" value="${text}"/>
<label for="discussion-search-within-board-${discussion_id}">search within board</label>
<input type="checkbox" id="discussion-search-within-board-${discussion_id}" class="discussion-search-within-board" checked/>
<a class="discussion-link discussion-search" href="javascript:void(0)">Search</a>
</form>
<%! from django.core.urlresolvers import reverse %>
<section class="discussion">
<a class="discussion-title" href="javascript:void(0)">Discussion</a>
${render_thread(thread, edit_thread=True, show_comments=True)}
</section>
<%def name="render_thread(thread, edit_thread=False, show_comments=False)">
<div class="thread" _id="${thread['id']}">
<div class="discussion-content">
<a class="thread-title" name="${thread['id']}" href="javascript:void(0)">${thread['title']}</a>
<div class="discussion-content-view">
<div class="thread-body">${thread['body']}</div>
<div class="info">
${render_info(thread)}
% if edit_thread:
${render_reply('')}
${render_edit('')}
% endif
</div>
</div>
</div>
% if show_comments:
<div class="comments">
${render_comments(thread['children'])}
</div>
% endif
</div>
</%def>
<%def name="render_comments(comments)">
% for comment in comments:
<div class="comment" _id="${comment['id']}">
<div class="discussion-content">
<div class="discussion-content-view">
<a class="comment-body" name="${comment['id']}">${comment['body']}</a>
<div class="info">
${render_info(comment)}
${render_reply('')}
${render_edit('')}
</div>
</div>
</div>
<div class="comments">
${render_comments(comment['children'])}
</div>
</div>
% endfor
</%def>
<%def name="render_info(content)">
${time_ago_in_words(parse(content['updated_at']))} ago by user No.${content['user_id']}
</%def>
<%def name="render_reply(url)">
<a class="discussion-link discussion-reply" href="javascript:void(0)">Reply</a>
</%def>
<%def name="render_edit(url)">
<a class="discussion-link discussion-edit" href="javascript:void(0)">Edit</a>
</%def>
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment