changeset 89:021492db4aad

Forums: Got the reply function working.
author Brian Neal <bgneal@gmail.com>
date Sat, 12 Sep 2009 21:29:31 +0000
parents 3abf0b045749
children 317c7bcaecee
files gpp/forums/forms.py gpp/forums/urls.py gpp/forums/views.py gpp/templates/forums/display_post.html gpp/templates/forums/topic.html media/css/base.css media/js/forums.js
diffstat 7 files changed, 105 insertions(+), 25 deletions(-) [+]
line wrap: on
line diff
--- a/gpp/forums/forms.py	Sat Sep 12 18:51:55 2009 +0000
+++ b/gpp/forums/forms.py	Sat Sep 12 21:29:31 2009 +0000
@@ -10,14 +10,30 @@
 class PostForm(forms.Form):
     """Form for creating a new post."""
     body = forms.CharField(label='', widget=forms.Textarea)
+    topic_id = forms.IntegerField(widget=forms.HiddenInput)
+    topic = None
 
-    def save(self, topic, user, ip=None):
+    class Media:
+        js = ('js/forums.js', )
+
+    def clean_topic_id(self):
+        id = self.cleaned_data['topic_id']
+        print '*********', id
+        try:
+            self.topic = Topic.objects.get(pk=id)
+            print '******** Got a topic'
+        except Topic.DoesNotExist:
+            raise forms.ValidationError('invalid topic')
+        return id 
+
+    def save(self, user, ip=None):
         """
         Creates a new post from the form data and supplied arguments.
         """
-        post = Post(topic=topic, user=user, body=self.cleaned_data['body'],
-                user_ip=user_ip)
+        post = Post(topic=self.topic, user=user, body=self.cleaned_data['body'],
+                user_ip=ip)
         post.save()
+        return post
 
 
 class NewTopicForm(forms.Form):
--- a/gpp/forums/urls.py	Sat Sep 12 18:51:55 2009 +0000
+++ b/gpp/forums/urls.py	Sat Sep 12 21:29:31 2009 +0000
@@ -9,5 +9,6 @@
     url(r'^topic/(?P<id>\d+)/$', 'topic_index', name='forums-topic_index'),
     url(r'^forum/(?P<slug>[\w\d-]+)/$', 'forum_index', name='forums-forum_index'),
     url(r'^forum/(?P<slug>[\w\d-]+)/new-topic/$', 'new_topic', name='forums-new_topic'),
+    url(r'^quick-reply/$', 'quick_reply_ajax', name='forums-quick_reply'),
 )
 
--- a/gpp/forums/views.py	Sat Sep 12 18:51:55 2009 +0000
+++ b/gpp/forums/views.py	Sat Sep 12 21:29:31 2009 +0000
@@ -3,11 +3,13 @@
 """
 from django.contrib.auth.decorators import login_required
 from django.http import Http404
+from django.http import HttpResponseBadRequest
 from django.http import HttpResponseRedirect
 from django.core.urlresolvers import reverse
 from django.shortcuts import get_object_or_404
 from django.shortcuts import render_to_response
 from django.template import RequestContext
+from django.views.decorators.http import require_POST
 
 from forums.models import Forum
 from forums.models import Topic
@@ -67,7 +69,7 @@
         'topic': topic,
         'posts': posts,
         'last_page': last_page,
-        'form': PostForm(),
+        'form': PostForm(initial={'topic_id': topic.id}),
         },
         context_instance=RequestContext(request))
 
@@ -105,3 +107,24 @@
         'topic': topic,
         },
         context_instance=RequestContext(request))
+
+
+@login_required
+@require_POST
+def quick_reply_ajax(request):
+    """
+    This function handles the quick reply to a thread function. This
+    function is meant to be the target of an AJAX post, and returns
+    the HTML for the new post, which the client-side script appends
+    to the document.
+    """
+    form = PostForm(request.POST)
+    if form.is_valid():
+        post = form.save(request.user, request.META.get("REMOTE_ADDR"))
+        return render_to_response('forums/display_post.html', {
+            'post': post,
+            },
+            context_instance=RequestContext(request))
+
+    return HttpResponseBadRequest();
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gpp/templates/forums/display_post.html	Sat Sep 12 21:29:31 2009 +0000
@@ -0,0 +1,17 @@
+{% load avatar_tags %}
+<tr class="forum-post {% cycle 'odd' 'even' %}">
+   <td class="forum-post-author">
+      <a name="p{{ post.id }}"></a>
+      <a href="{% url bio-view_profile username=post.user.username %}">{{ post.user.username }}</a><br />
+      {% avatar post.user %}
+   </td>
+   <td class="forum-post-body">
+      <div class="forum-post-info quiet">
+         <a href="{{ post.get_absolute_url }}"><img src="{{ MEDIA_URL }}icons/link.png" alt="Link" title="Link to this post" /></a>
+         Posted on {{ post.creation_date|date:"M d, Y H:i" }}
+      </div>
+      <div class="forum-post-body">
+         {{ post.html|safe }}
+      </div>
+   </td>
+</tr>
--- a/gpp/templates/forums/topic.html	Sat Sep 12 18:51:55 2009 +0000
+++ b/gpp/templates/forums/topic.html	Sat Sep 12 21:29:31 2009 +0000
@@ -1,6 +1,6 @@
 {% extends 'base.html' %}
-{% load avatar_tags %}
 {% block title %}Forums: {{ topic.name }}{% endblock %}
+{% block custom_js %}{% if last_page %}{{ form.media }}{% endif %}{% endblock %}
 {% block content %}
 <h2>Forums: {{ topic.name }}</h2>
 
@@ -18,33 +18,18 @@
 {% endif %}
 <a href="{% url forums-new_topic slug=forum.slug %}">New Topic</a>
 
-<table class="forum-topic">
+<table class="forum-topic" id="forum-topic">
 {% for post in posts %}
-<tr class="forum-post">
-   <td class="forum-post-author">
-      <a name="p{{ post.id }}"></a>
-      <a href="{% url bio-view_profile username=post.user.username %}">{{ post.user.username }}</a><br />
-      {% avatar post.user %}
-   </td>
-   <td class="forum-post-body">
-      <div class="forum-post-info quiet">
-         <a href="{{ post.get_absolute_url }}"><img src="{{ MEDIA_URL }}icons/link.png" alt="Link" title="Link to this post" /></a>
-         Posted on {{ post.creation_date|date:"M d, Y H:i" }}
-      </div>
-      <div class="forum-post-body">
-         {{ post.html|safe }}
-      </div>
-   </td>
-</tr>
+{% include 'forums/display_post.html' %}
 {% endfor %}
 </table>
 {% if last_page and user.is_authenticated %}
 <a name="forum-reply-form"></a>
-<form action="" method="post">
+<form action="" method="post" id="forums-quick-reply">
 <fieldset>
 <legend>Reply to &quot;{{ topic.name }}&quot;</legend>
 {{ form.as_p }}
-<input type="submit" value="Submit Reply" />
+<input type="submit" value="Submit Reply" id="forums-reply-post" />
 </fieldset>
 </form>
 {% endif %}
--- a/media/css/base.css	Sat Sep 12 18:51:55 2009 +0000
+++ b/media/css/base.css	Sat Sep 12 21:29:31 2009 +0000
@@ -195,17 +195,21 @@
    text-align:center;
 }
 table.forum-topic {
-   border:1px solid black;
+   border-top:1px solid black;
+   border-left:1px solid black;
+   border-right:1px solid black;
    width:100%;
    margin-top: 5px;
 }
 td.forum-post-author {
    width:5%;
    border-right: 1px solid #ccc;
+   border-bottom: 1px solid black;
 }
 td.forum-post-body {
    vertical-align: top;
    width:95%;
+   border-bottom: 1px solid black;
 }
 div.forum-post-info {
    padding: 2px;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/media/js/forums.js	Sat Sep 12 21:29:31 2009 +0000
@@ -0,0 +1,34 @@
+$(document).ready(function() {
+   var postText = $('#id_body');
+   var postButton = $('#forums-reply-post');
+   postButton.click(function () {
+      var text = $.trim(postText.val());
+      if (text.length == 0) {
+         alert('Please enter some reply text.');
+         return false;
+      }
+      $(this).attr('disabled', 'disabled').val('Posting reply...');
+      $.ajax({
+         url: '/forums/quick-reply/', 
+         type: 'POST',
+         data: {
+         body : postText.val(),
+         topic_id : $('#id_topic_id').val()
+         },
+         dataType: 'html',
+         success: function (data, textStatus) {
+            postText.val('');
+            $('#forum-topic tr:last').after(data);
+            var lastTr = $('#forum-topic tr:last');
+            lastTr.hide();
+            lastTr.fadeIn(3000);
+            postButton.removeAttr('disabled').val('Submit Reply');
+         },
+         error: function (xhr, textStatus, ex) {
+            alert('Oops, an error occurred. Please reload the page and try again.');
+            postButton.removeAttr('disabled').val('Submit Reply');
+         }
+         });
+      return false;
+   });
+});