From ab3fb1f4b3a544dbaaaa0809df657b7f14faafa2 Mon Sep 17 00:00:00 2001
From: Tanner Prestegard <tanner.prestegard@ligo.org>
Date: Wed, 18 Jan 2017 14:48:08 -0600
Subject: [PATCH] updates to error handling during Contact creation

---
 static/css/style.css |  8 ++++++++
 userprofile/forms.py | 35 +++++++++++++++++++++++------------
 userprofile/views.py | 15 +++++++++++++++
 3 files changed, 46 insertions(+), 12 deletions(-)

diff --git a/static/css/style.css b/static/css/style.css
index bf6b397ce..24a1104ea 100644
--- a/static/css/style.css
+++ b/static/css/style.css
@@ -22,6 +22,14 @@ table.analysis_specific {width:100%}
 table.gstlalcbc {border:0;border-spacing:0px;width:100%;}
 table.gstlalcbc th {padding:3px;border:none;vertical-align:bottom;}
 
+/* Tanner added for ContactForm errors */
+p.error {
+    margin: 0px;
+    padding: 0px;
+    font-weight: bold;
+    color: red;
+}
+
 .content-area {
     margin-top: 10px;
     margin-bottom: 30px;
diff --git a/userprofile/forms.py b/userprofile/forms.py
index e3557b5e4..dcde06173 100644
--- a/userprofile/forms.py
+++ b/userprofile/forms.py
@@ -1,6 +1,7 @@
 from django import forms
 from django.utils.safestring import mark_safe
 from django.utils.encoding import force_text
+from django.forms.utils import ErrorList
 
 from .models import Trigger, Contact
 from gracedb.query import parseLabelQuery
@@ -51,6 +52,19 @@ class TriggerForm(forms.ModelForm):
         model = Trigger
         exclude = ['user', 'triggerType']
 
+def process_errors(err):
+    """Processes and formats errors in ContactForms."""
+    out_errs = []
+    if isinstance(err,ErrorList):
+        for e in err:
+            out_errs.append('<p class="error">{0}</p>'.format(e))
+    elif isinstance(err,str):
+        out_errs.append('<p class="error">{0}</p>'.format(err))
+    else:
+        out_errs.append(force_text(err))
+
+    return "\n".join(out_errs)
+
 class ContactForm(forms.ModelForm):
     # Adjust labels.
     desc = forms.CharField(label='Description')
@@ -76,34 +90,31 @@ class ContactForm(forms.ModelForm):
         # Description/email
         for field in ['desc','email']:
             table_data[field] = row_str.format(field,self[field].label,
-                                               force_text(self[field].errors),
-                                               "text")
+                process_errors(self[field].errors),"text")
+
         # Phone number
         table_data['phone'] = (row_head + row_err +
             '<input id="id_{0}" name="{0}" type="text" />').format(
-            'phone',self['phone'].label,force_text(self['phone'].errors))
+            'phone',self['phone'].label,process_errors(self['phone'].errors))
         # Add call/text checkboxes.
         table_data['phone'] += '<br />'
         table_data['phone'] += ('{1}?<input id="id_{0}" name="{0}"'
-                           'type="checkbox" />&nbsp;&nbsp;'
-                           .format('call_phone',self['call_phone'].label))
+            'type="checkbox" />&nbsp;&nbsp;'.format('call_phone',
+            self['call_phone'].label))
         table_data['phone'] += ('{1}?<input id="id_{0}" name="{0}"'
-                           'type="checkbox" />'
-                           .format('text_phone',self['text_phone'].label))
+            'type="checkbox" />'.format('text_phone',self['text_phone'].label))
 
         # Add phone help text.
         table_data['phone'] += ('<br /><span class="helptext">{0}</span>'
             '</td></tr>\n'.format(self['phone'].help_text))
 
-        # Get non-field errors.
-        nfe = ''.join([force_text(e) for e in self.non_field_errors()])
-
         # Compile table_data dict into a list.
         td = [table_data[k] for k in ['desc','email','phone']]
 
         # Add non-field errors to beginning.
+        nfe = self.non_field_errors()
         if nfe:
-           td.insert(0,'<tr><td colspan="2"><ul><li>' + force_text(nfe) \
-                       + '</li></ul></td></tr>')
+            td.insert(0,'<tr><td colspan="2">' \
+                + process_errors(nfe) + '</td></tr>')
 
         return mark_safe('\n'.join(td))
diff --git a/userprofile/views.py b/userprofile/views.py
index 4c9a78ffc..80f80d28c 100644
--- a/userprofile/views.py
+++ b/userprofile/views.py
@@ -9,6 +9,7 @@ from django.contrib.auth.models import User
 from django.template import RequestContext
 from django.shortcuts import render_to_response
 from django.utils import timezone
+from django.utils.safestring import mark_safe
 from django.db.models import Q
 
 from django_twilio.client import twilio_client
@@ -139,6 +140,19 @@ def delete(request, id):
 
 @internal_user_required
 def createContact(request):
+
+    # Explanatory HTML block.
+    expl = ['<div style="padding: 10px;">',
+            '<h4>Instructions:</h4>',
+            '<ul><li>Description is required.</li>',
+            '<li>Choose a contact method (e-mail, phone, or both).</li>',
+            ('<li>For phone alerts, mark call, text, or both, depending on how'
+             ' you want to receive the alerts.</li>'),
+            '</ul></div>'
+           ]
+    expl = mark_safe("\n".join(expl))
+
+    # Handle form.
     if request.method == "POST":
         form = ContactForm(request.POST)
         if form.is_valid():
@@ -159,6 +173,7 @@ def createContact(request):
     return render_to_response('profile/createNotification.html',
                               { "form": form,
                                 "creating": "Contact",
+                                "explanation": expl,
                               },
                               context_instance=RequestContext(request))
 
-- 
GitLab