Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRogelio Mita <rogeliomita@activitycentral.com>2013-02-21 23:46:33 (GMT)
committer Rogelio Mita <rogeliomita@activitycentral.com>2013-02-21 23:46:33 (GMT)
commitaf9555f46d4bf605d52b13c415eb65352de773a8 (patch)
treecdfafaec0733bfccfe781ea161e7cfed4a7847ce
parent6470e0d404120530323b549ab1b0e4bcca06f8a2 (diff)
Adding validation to widgets of fields.
-rw-r--r--webapp/polls/exceptions.py2
-rw-r--r--webapp/polls/models.py50
-rw-r--r--webapp/polls/templates/builder.html58
-rw-r--r--webapp/polls/tests.py41
-rw-r--r--webapp/polls/views.py5
5 files changed, 128 insertions, 28 deletions
diff --git a/webapp/polls/exceptions.py b/webapp/polls/exceptions.py
new file mode 100644
index 0000000..15e676c
--- /dev/null
+++ b/webapp/polls/exceptions.py
@@ -0,0 +1,2 @@
+class ValidationError(Exception):
+ pass
diff --git a/webapp/polls/models.py b/webapp/polls/models.py
index 2ab0f43..06c85b6 100644
--- a/webapp/polls/models.py
+++ b/webapp/polls/models.py
@@ -1,16 +1,22 @@
+# -*- encoding: utf-8 -*-
import time
+from exceptions import *
+
WIDGET_TYPES = (
- ('TextInput', 'TextInput'),
- ('MultipleCheckbox', 'MultipleCheckbox'),
- ('RadioButton', 'RadioButton'),
- ('DropDownList', 'DropDownList'),
+ ('TextInput', 'Respuesta en texto'),
+ ('MultipleCheckbox', 'Respuesta con checks (multiple selección)'),
+ ('RadioButton', 'Respuesta con radios (Solo una selección)'),
+ ('DropDownList', 'Respuesta con lista de opciones'),
)
class AbastractObject(object):
+ ValidationError = ValidationError
+ errors = []
+
@staticmethod
def get_offset_id():
return int(time.time() * 1000)
@@ -36,6 +42,25 @@ class Option(AbastractObject):
class Field(AbastractObject):
+ rules = {
+ 'MultipleCheckbox': (
+ lambda f: len(f.options) > 0,
+ "Respuesta con checks (multiple selección): necesita "
+ "al menos una opción."
+ ),
+ 'RadioButton': (
+ lambda f: len(f.options) > 1,
+ "Respuesta con radios (Solo una selección): necesita "
+ "al menos dos opciones."
+ ),
+ 'DropDownList': (
+ lambda f: len(f.options) > 0,
+ "Respuesta con lista de opciones: necesita "
+ "al menos una opción."
+ ),
+ 'TextInput': (lambda f: True, ""),
+ }
+
def __init__(self, name, widget_type, key=None):
super(Field, self).__init__()
@@ -81,6 +106,13 @@ class Field(AbastractObject):
def add_dependence(self, dependence):
self.dependence = dependence
+ def validate(self):
+ self.errors = []
+ rule, msg = Field.rules.get(self.widget_type)
+ if not rule(self):
+ self.errors.append(msg)
+ raise Field.ValidationError(msg)
+
class Group(AbastractObject):
@@ -143,3 +175,13 @@ class Structure(object):
self.groups = groups_pre + [group] + groups_post
return group
+
+ def is_valid(self):
+ valid = True
+ for group in self.groups:
+ for field in group.fields:
+ try:
+ field.validate()
+ except Field.ValidationError:
+ valid = False
+ return valid
diff --git a/webapp/polls/templates/builder.html b/webapp/polls/templates/builder.html
index 76f615e..fc8e298 100644
--- a/webapp/polls/templates/builder.html
+++ b/webapp/polls/templates/builder.html
@@ -5,40 +5,52 @@
<form class="form-inline" method="post" action="">
{% for group in structure.groups %}
- <fieldset>
+ <fieldset class="well">
- <legend>{% trans group.name %}</legend>
-
- <input
- type="hidden"
+ <legend>
+ <label><h3>Nombre del Grupo:</h3></label>
+ <input
+ type="text"
name="groups.{{ forloop.counter0 }}.name"
value="{{ group.name|default_if_none:'' }}"
/>
+ </legend>
{% for field in group.fields %}
{% with group_index=forloop.parentloop.counter0 %}
- <input
- class="input-xxlarge"
- type="text"
- name="groups.{{ group_index }}.fields.{{ forloop.counter0 }}.name"
- value="{{ field.name|default_if_none:'' }}"
- placeholder="Pregunta..."
- />
+ {% if field.errors %}
+ <div class="control-group error">
+ <label class="control-label">{{ field.errors.0 }}</label></br>
+ </div>
+ {% endif %}
+
+ <div class="row-fluid">
+ <input
+ class="input-xxlarge"
+ type="text"
+ name="groups.{{ group_index }}.fields.{{ forloop.counter0 }}.name"
+ value="{{ field.name|default_if_none:'' }}"
+ placeholder="Pregunta..."
+ />
- <select name="groups.{{ group_index }}.fields.{{ forloop.counter0 }}.widget_type">
+ <select class="span3" name="groups.{{ group_index }}.fields.{{ forloop.counter0 }}.widget_type">
{% for k, v in WIDGET_TYPES %}
<option value="{{ k }}" {% if k == field.widget_type %}selected="selected"{% endif %}>{{ v }}</option>
{% endfor %}
- </select>
-
- <input
- class="input-mini"
- type="text"
- name=".groups.{{ group_index }}.fields.{{ field_index }}.options.{{ option.id }}.dependence"
- value="{{ option.dependence|default_if_none:'' }}"
- placeholder="dependence"
- />
+ </select>
+ </div>
+
+ <div class="row-fluid">
+ <label>Depende de la opción:</label>
+ <input
+ class="input-mini"
+ type="text"
+ name=".groups.{{ group_index }}.fields.{{ field_index }}.options.{{ option.id }}.dependence"
+ value="{{ option.dependence|default_if_none:'' }}"
+ placeholder="nro. ID"
+ />
+ </div>
{% if field.options %}
<div class="control-group">
@@ -48,7 +60,7 @@
{% for option in field.options %}
{% with field_index=forloop.parentloop.counter0 %}
<div class="span3">
- <label>Opci&oacute;n {{ forloop.counter }}</label>
+ <label>Opci&oacute;n (ID: {{ option.id }})</label>
<input
class="input-large"
type="text"
diff --git a/webapp/polls/tests.py b/webapp/polls/tests.py
index b6b898d..5499c00 100644
--- a/webapp/polls/tests.py
+++ b/webapp/polls/tests.py
@@ -1,3 +1,4 @@
+# -*- encoding: utf-8 -*-
from django.test import TestCase
from polls.models import Field, Group, Structure, Option, WIDGET_TYPES
@@ -71,6 +72,23 @@ class FieldsTests(TestCase):
self.assertEqual(1, len(field.options))
+ def test_validate(self):
+
+ self.field.widget_type = "MultipleCheckbox"
+
+ self.assertRaises(Field.ValidationError, self.field.validate)
+ self.assertEqual(1, len(self.field.errors))
+
+ self.field.widget_type = "RadioButton"
+
+ self.assertRaises(Field.ValidationError, self.field.validate)
+ self.assertEqual(1, len(self.field.errors))
+
+ self.field.widget_type = "DropDownList"
+
+ self.assertRaises(Field.ValidationError, self.field.validate)
+ self.assertEqual(1, len(self.field.errors))
+
class OptionTests(TestCase):
@@ -171,3 +189,26 @@ class StructureTests(TestCase):
field_1_1 = group_1.fields[1]
self.assertEqual('field_1_1', field_1_1.name)
self.assertEqual('DropDownList', field_1_1.widget_type)
+
+ def test_is_valid(self):
+ data = {
+ 'groups': {
+ '0': {
+ 'name': 'group_0',
+ 'fields': {
+ '0': {
+ 'widget_type': 'RadioButton',
+ 'name': 'field_0_0'
+ },
+ }
+ }
+ }
+ }
+
+ structure = Structure(data=data)
+
+ self.assertFalse(structure.is_valid())
+
+ field_0_0 = structure.groups[0].fields[0]
+
+ self.assertEqual(1, len(field_0_0.errors))
diff --git a/webapp/polls/views.py b/webapp/polls/views.py
index a2d4581..295103e 100644
--- a/webapp/polls/views.py
+++ b/webapp/polls/views.py
@@ -96,6 +96,9 @@ class BuilderView(TemplateView):
data[key] = clean_data(value)
structure = Structure(data={"groups": data['groups']})
- context.update({'structure': structure})
+ if structure.is_valid():
+ pass
+
+ context.update({'structure': structure})
return self.render_to_response(context)