diff gpp/forums/forms.py @ 286:72fd300685d5

For #95. You can now make posts with no text in the body if you have attachments. And now if you create a new topic with an attachment, and the POST fails (say you forgot the topic title), we will now re-attach attachments. Also fixed a bug in the smiley code that would arise if it was asked to markup an empty string.
author Brian Neal <bgneal@gmail.com>
date Sat, 23 Oct 2010 20:19:46 +0000
parents 8fd4984d5c3b
children 26fc9ac9a0eb
line wrap: on
line diff
--- a/gpp/forums/forms.py	Thu Oct 14 02:39:35 2010 +0000
+++ b/gpp/forums/forms.py	Sat Oct 23 20:19:46 2010 +0000
@@ -12,7 +12,8 @@
 
 class NewPostForm(forms.Form):
     """Form for creating a new post."""
-    body = forms.CharField(label='', 
+    body = forms.CharField(label='',
+            required=False,
             widget=forms.Textarea(attrs={'class': 'markItUp smileyTarget'}))
     topic_id = forms.IntegerField(widget=forms.HiddenInput)
     topic = None
@@ -22,7 +23,7 @@
             'all': (settings.GPP_THIRD_PARTY_CSS['markitup'] +
                 settings.GPP_THIRD_PARTY_CSS['jquery-ui']),
         }
-        js = (settings.GPP_THIRD_PARTY_JS['markitup'] + 
+        js = (settings.GPP_THIRD_PARTY_JS['markitup'] +
                 settings.GPP_THIRD_PARTY_JS['jquery-ui'] +
                 ('js/forums.js', ))
 
@@ -31,13 +32,19 @@
         attachments = args[0].getlist('attachment') if len(args) else []
         self.attach_proc = AttachmentProcessor(attachments)
 
+    def clean_body(self):
+        data = self.cleaned_data['body']
+        if not data and not self.attach_proc.has_attachments():
+            raise forms.ValidationError("This field is required.")
+        return data
+
     def clean_topic_id(self):
         id = self.cleaned_data['topic_id']
         try:
             self.topic = Topic.objects.select_related().get(pk=id)
         except Topic.DoesNotExist:
             raise forms.ValidationError('invalid topic')
-        return id 
+        return id
 
     def save(self, user, ip=None):
         """
@@ -58,7 +65,7 @@
     """
     name = forms.CharField(label='Subject', max_length=255,
             widget=forms.TextInput(attrs={'size': 64}))
-    body = forms.CharField(label='', 
+    body = forms.CharField(label='', required=False,
             widget=forms.Textarea(attrs={'class': 'markItUp smileyTarget'}))
     user = None
     forum = None
@@ -69,7 +76,7 @@
             'all': (settings.GPP_THIRD_PARTY_CSS['markitup'] +
                 settings.GPP_THIRD_PARTY_CSS['jquery-ui']),
         }
-        js = (settings.GPP_THIRD_PARTY_JS['markitup'] + 
+        js = (settings.GPP_THIRD_PARTY_JS['markitup'] +
                 settings.GPP_THIRD_PARTY_JS['jquery-ui'] +
                 ('js/forums.js', ))
 
@@ -86,6 +93,23 @@
         attachments = args[0].getlist('attachment') if len(args) else []
         self.attach_proc = AttachmentProcessor(attachments)
 
+        # If this form is being POSTed, and the user is trying to add 
+        # attachments, create hidden fields to list the Oembed ids. In
+        # case the form isn't valid, the client-side javascript will know
+        # which Oembed media to ask for when the form is displayed with
+        # errors.
+        if self.attach_proc.has_attachments():
+            pks = self.attach_proc.get_ids()
+            self.fields['attachment'] = forms.MultipleChoiceField(label='',
+                    widget=forms.MultipleHiddenInput(),
+                    choices=[(v, v) for v in pks])
+
+    def clean_body(self):
+        data = self.cleaned_data['body']
+        if not data and not self.attach_proc.has_attachments():
+            raise forms.ValidationError("This field is required.")
+        return data
+
     def save(self, ip=None):
         """
         Creates the new Topic and first Post from the form data and supplied
@@ -113,7 +137,8 @@
     """
     Form for editing an existing post or a new, non-quick post.
     """
-    body = forms.CharField(label='', 
+    body = forms.CharField(label='',
+            required=False,
             widget=forms.Textarea(attrs={'class': 'markItUp smileyTarget'}))
 
     class Meta:
@@ -125,20 +150,42 @@
             'all': (settings.GPP_THIRD_PARTY_CSS['markitup'] +
                 settings.GPP_THIRD_PARTY_CSS['jquery-ui']),
         }
-        js = (settings.GPP_THIRD_PARTY_JS['markitup'] + 
+        js = (settings.GPP_THIRD_PARTY_JS['markitup'] +
                 settings.GPP_THIRD_PARTY_JS['jquery-ui'] +
                 ('js/forums.js', ))
 
+    def __init__(self, *args, **kwargs):
+        super(PostForm, self).__init__(*args, **kwargs)
+
+        attachments = args[0].getlist('attachment') if len(args) else []
+        self.attach_proc = AttachmentProcessor(attachments)
+        
+        # If this form is being used to edit an existing post, and that post
+        # has attachments, create a hidden post_id field. The client-side
+        # AJAX will use this as a cue to retrieve the HTML for the embedded
+        # media.
+        if 'instance' in kwargs:
+            post = kwargs['instance']
+            if post.attachments.count():
+                self.fields['post_id'] = forms.CharField(label='',
+                        widget=forms.HiddenInput(attrs={'value': post.id}))
+
+    def clean_body(self):
+        data = self.cleaned_data['body']
+        if not data and not self.attach_proc.has_attachments():
+            raise forms.ValidationError('This field is required.')
+        return data
+
 
 class MoveTopicForm(forms.Form):
     """
     Form for a moderator to move a topic to a forum.
     """
-    forums = forms.ModelChoiceField(label='Move to forum', 
+    forums = forms.ModelChoiceField(label='Move to forum',
           queryset=Forum.objects.none())
 
     def __init__(self, user, *args, **kwargs):
-        hide_label = kwargs.pop('hide_label', False) 
+        hide_label = kwargs.pop('hide_label', False)
         required = kwargs.pop('required', True)
         super(MoveTopicForm, self).__init__(*args, **kwargs)
         self.fields['forums'].queryset = \
@@ -154,7 +201,7 @@
     """
     name = forms.CharField(label='New topic title', max_length=255,
             widget=forms.TextInput(attrs={'size': 64}))
-    forums = forms.ModelChoiceField(label='Forum for new topic', 
+    forums = forms.ModelChoiceField(label='Forum for new topic',
           queryset=Forum.objects.none())
     post_ids = []
     split_at = False