Permalink
Browse files

Add ajax-based preview.

There is more switching of pages for the JavaScript version of this page.
  • Loading branch information...
1 parent 0787439 commit 9e4afe74391e2f6ec529a53a24918e517af48313 @vdboor vdboor committed May 25, 2012
@@ -4,7 +4,8 @@
var active_input = '';
// Settings
- var SCROLL_TOP_OFFSET = 60;
+ var COMMENT_SCROLL_TOP_OFFSET = 40;
+ var PREVIEW_SCROLL_TOP_OFFSET = 20;
$.fn.ready(function()
@@ -53,44 +54,47 @@
function onCommentFormSubmit(event)
{
+ event.preventDefault(); // only after ajax call worked.
var form = event.target;
- if( active_input != 'preview' )
- {
- event.preventDefault(); // only after ajax call worked.
- ajaxComment(form, {
- 'complete': onCommentPosted
- });
- return false;
- }
- return true;
+ var preview = (active_input == 'preview');
+
+ ajaxComment(form, {
+ onsuccess: (preview ? null : onCommentPosted),
+ preview: preview
+ });
+ return false;
}
function scrollToComment(id, speed)
{
// Allow initialisation before scrolling.
var $comment = $("#c" + id);
+ if( $comment.length == 0 ) {
+ if( window.console ) console.warn("scrollToComment() - #c" + id + " not found.");
+ return;
+ }
+
if( window.on_scroll_to_comment && window.on_scroll_to_comment({comment: $comment}) === false )
return;
// Scroll to the comment.
- if( $comment.length )
- $(scrollElement).animate( {scrollTop: $comment.offset().top - SCROLL_TOP_OFFSET }, speed || 1000 );
+ scrollToElement( $comment, speed, COMMENT_SCROLL_TOP_OFFSET );
}
- function onCommentPosted($comment)
+ function scrollToElement( $element, speed, offset )
{
- var id = $comment.attr('id');
+ if( $element.length )
+ $(scrollElement).animate( {scrollTop: $element.offset().top - (offset || 0) }, speed || 1000 );
+ }
- if( id.substring(0, 1) == 'c' )
- {
- id = parseInt(id.substring(1));
- $("#comment-added-message").fadeIn(200);
- setTimeout(function(){ scrollToComment(id, 1000); }, 1000);
- setTimeout(function(){ $("#comment-added-message").fadeOut(500) }, 4000);
- }
+ function onCommentPosted( comment_id, $comment )
+ {
+ $("#comment-added-message").fadeIn(200);
+ setTimeout(function(){ scrollToComment(comment_id, 1000); }, 1000);
+ setTimeout(function(){ $("#comment-added-message").fadeOut(500) }, 4000);
}
@@ -101,10 +105,12 @@
Updated to be more generic, more fancy, and usable with different templates.
*/
var commentBusy = false;
+ var previewAutoAdded = false;
function ajaxComment(form, args)
{
- var oncomplete = args.complete;
+ var onsuccess = args.onsuccess;
+ var preview = !!args.preview;
$('div.comment-error').remove();
if (commentBusy) {
@@ -113,12 +119,13 @@
commentBusy = true;
var $form = $(form);
- var comment = $form.serialize();
+ var comment = $form.serialize() + (preview ? '&preview=1' : '');
var url = $form.attr('action') || './';
var ajaxurl = $form.attr('data-ajax-action');
// Add a wait animation
- $('#comment-waiting').fadeIn(1000);
+ if( ! preview )
+ $('#comment-waiting').fadeIn(1000);
// Use AJAX to post the comment.
$.ajax({
@@ -131,9 +138,14 @@
removeWaitAnimation();
if (data.success) {
- commentSuccess(data);
- var added = $("#comments > :last-child");
- if( oncomplete ) oncomplete(added);
+ var $added;
+ if( preview )
+ $added = commentPreview(data);
+ else
+ $added = commentSuccess(data);
+
+ if( onsuccess )
+ args.onsuccess(data.comment_id, $added);
}
else {
commentFailure(data);
@@ -156,10 +168,30 @@
// Clean form
$('form.js-comments-form textarea')[0].value = "";
$('#id_comment').val('');
+ removePreview();
// Show comment
$('#comments').append(data['html']);
$('div.comment:last').show('slow');
+ return $("#comments > div.comment:last-of-type");
+ }
+
+ function commentPreview(data)
+ {
+ var $previewarea = $("#comment-preview-area");
+ if( $previewarea.length == 0 )
+ {
+ // If not explicitly added to the HTML, include a previewarea in the comments.
+ // This should at least give the same markup.
+ $("#comments").append('<div id="comment-preview-area"></div>');
+ $previewarea = $("#comment-preview-area");
+ previewAutoAdded = true;
+ }
+
+ $previewarea.html(data.html);
+
+ // Scroll to preview, but allow time to render it.
+ setTimeout(function(){ scrollToElement( $previewarea, 500, PREVIEW_SCROLL_TOP_OFFSET ); }, 500);
}
function commentFailure(data)
@@ -174,6 +206,15 @@
}
}
+ function removePreview()
+ {
+ var $previewarea = $("#comment-preview-area");
+ if( previewAutoAdded )
+ $previewarea.remove(); // make sure it's added at the end again later.
+ else
+ $previewarea.html('');
+ }
+
function removeWaitAnimation()
{
// Remove the wait animation and message
@@ -17,9 +17,9 @@
This should give you consistent dates across all views.
{% endcomment %}
{% load i18n %}
-
- <div id="c{{ comment.id }}" class="comment-item">
- {% spaceless %}
+ <div{% if preview %} id="comment-preview"{% else %} id="c{{ comment.id }}"{% endif %} class="comment-item">
+ {% if preview %}<h3>{% trans "Preview of your comment" %}</h3>{% endif %}
+ {% spaceless %}
<h4>
{% if comment.url %}<a href="{{ comment.url }}" rel="nofollow">{% endif %}
{% if comment.name %}{{ comment.name }}{% else %}{% trans "Anonymous" %}{% endif %}{% comment %}
View
@@ -24,6 +24,10 @@ def post_comment_ajax(request, using=None):
# This is copied from django.contrib.comments.
# Basically this view does too much, and doesn't offer a hook to change the rendering
# (request is not passed to next_redirect for example)
+ #
+ # This is a separate view, unlike the approach that django-ajaxcomments takes.
+ # However, the django-ajaxcomments solution is not thread safe, as it changes the comment view per request.
+
# Fill out some initial data fields from an authenticated user, if present
data = request.POST.copy()
@@ -70,8 +74,12 @@ def post_comment_ajax(request, using=None):
escape(str(form.security_errors())))
# If there are errors or if we requested a preview show the comment
- if form.errors or preview:
- return _ajax_result(request, form)
+ if preview:
+ comment = form.get_comment_object() if not form.errors else None
+ return _ajax_result(request, form, "preview", comment)
+ if form.errors:
+ return _ajax_result(request, form, "post")
+
# Otherwise create the comment
comment = form.get_comment_object()
@@ -99,10 +107,10 @@ def post_comment_ajax(request, using=None):
request = request
)
- return _ajax_result(request, form, comment)
+ return _ajax_result(request, form, "post", comment)
-def _ajax_result(request, form, comment=None):
+def _ajax_result(request, form, action, comment=None):
# Based on django-ajaxcomments, BSD licensed.
# Copyright (c) 2009 Brandon Konkle and individual contributors.
#
@@ -119,13 +127,19 @@ def _ajax_result(request, form, comment=None):
comment_html = None
if comment:
- context = {'comment': comment}
+ context = {
+ 'comment': comment,
+ 'action': action,
+ 'preview': (action == 'preview'),
+ }
comment_html = render_to_string('comments/comment.html', context, context_instance=RequestContext(request))
json_response = simplejson.dumps({
'success': success,
+ 'action': action,
'errors': json_errors,
'html': comment_html,
+ 'comment_id': comment.id if comment else None,
})
return HttpResponse(json_response, mimetype="application/json")

0 comments on commit 9e4afe7

Please sign in to comment.