error checks and feedback

This commit is contained in:
Helmut Merz 2013-03-18 13:20:12 +01:00
parent 74988c1834
commit 12da1c3d0d
7 changed files with 79 additions and 16 deletions

View file

@ -113,6 +113,9 @@ class AdapterBase(object):
self.context = context
self.__parent__ = context # to get the permission stuff right
def __hash__(self):
return hash(self.context)
def __getattr__(self, attr):
self.checkAttr(attr)
return getattr(self.context, '_' + attr, None)

View file

@ -62,7 +62,7 @@ class QuestionGroup(AdapterBase, QuestionGroup):
_contextAttributes = list(IQuestionGroup)
_adapterAttributes = AdapterBase._adapterAttributes + (
'questionnaire', 'questions', 'feedbackItems',)
'questionnaire', 'questions', 'feedbackItems')
_noexportAttributes = _adapterAttributes
@property
@ -109,9 +109,6 @@ class Question(AdapterBase, Question):
def questionnaire(self):
return self.questionGroup.questionnaire
def __hash__(self):
return hash(self.context)
class FeedbackItem(AdapterBase, FeedbackItem):

View file

@ -23,11 +23,13 @@ surveys and self-assessments.
from zope.app.pagetemplate import ViewPageTemplateFile
from zope.cachedescriptors.property import Lazy
from zope.i18n import translate
from cybertools.knowledge.survey.questionnaire import Response
from loops.browser.concept import ConceptView
from loops.common import adapted
from loops.organize.party import getPersonForUser
from loops.util import _
template = ViewPageTemplateFile('view_macros.pt')
@ -36,6 +38,7 @@ class SurveyView(ConceptView):
tabview = 'index.html'
data = None
errors = None
@Lazy
def macro(self):
@ -56,20 +59,57 @@ class SurveyView(ConceptView):
value = int(value)
self.data[uid] = value
response.values[question] = value
self.errors = self.check(response)
if self.errors:
return []
# TODO: store self.data in track
# else:
# get response from track
if response is not None:
result = response.getGroupedResult()
return [dict(category=r[0].title, text=r[1].text,
score=int(round(r[2] * 100)))
for r in result]
def check(self, response):
errors = []
values = response.values
for qu in self.adapted.questions:
if qu.required and qu not in values:
errors.append('Please answer the obligatory questions.')
break
qugroups = {}
for qugroup in self.adapted.questionGroups:
qugroups[qugroup] = 0
for qu in values:
qugroups[qu.questionGroup] += 1
for qugroup, count in qugroups.items():
minAnswers = qugroup.minAnswers
if minAnswers in (u'', None):
minAnswers = len(qugroup.questions)
if count < minAnswers:
errors.append('Please answer the minimum number of questions.')
return errors
def getInfoText(self, qugroup):
lang = self.languageInfo.language
text = qugroup.description
info = None
if qugroup.minAnswers in (u'', None):
info = translate(_(u'Please answer all questions.'), target_language=lang)
elif qugroup.minAnswers > 0:
info = translate(_(u'Please answer at least $minAnswers questions.',
mapping=dict(minAnswers=qugroup.minAnswers)),
target_language=lang)
if info:
text = u'%s<br />(%s)' % (text, info)
return text
def getValues(self, question):
setting = None
# TODO: get response from track
if self.data is not None:
setting = self.data.get(question.uid)
noAnswer = [dict(value='none', checked=(setting == None))]
return noAnswer + [dict(value=i, checked=(setting == i))
noAnswer = [dict(value='none', checked=(setting == None),
radio=(not question.required))]
return noAnswer + [dict(value=i, checked=(setting == i), radio=True)
for i in reversed(range(question.answerRange))]

View file

@ -47,7 +47,7 @@ class IQuestionGroup(IConceptSchema, interfaces.IQuestionGroup):
title=_(u'Minimum Number of Answers'),
description=_(u'Minumum number of questions that have to be answered. '
'Empty means all questions have to be answered.'),
default=4,
default=None,
required=False)

View file

@ -3,8 +3,16 @@
<metal:block define-macro="survey"
tal:define="feedback item/results">
tal:define="feedback item/results;
errors item/errors">
<metal:title use-macro="item/conceptMacros/concepttitle" />
<div class="error"
tal:condition="errors">
<div tal:repeat="error errors">
<span i18n:translate=""
tal:content="error" />
</div>
</div>
<div tal:condition="feedback">
<h3 i18n:translate="">Feedback</h3>
<table class="listing">
@ -25,8 +33,15 @@
<form method="post">
<table class="listing">
<tal:qugroup repeat="qugroup item/adapted/questionGroups">
<tr><td colspan="6">&nbsp;</td></tr>
<tr>
<td><b tal:content="qugroup/title" /></td>
<td tal:define="infoText python:item.getInfoText(qugroup)">
<b tal:content="qugroup/title" />
<div tal:condition="infoText">
<span tal:content="structure infoText" />
<br />&nbsp;
</div>
</td>
<td style="text-align: center"
i18n:translate="">No answer</td>
<td colspan="2"
@ -41,11 +56,16 @@
tal:repeat="value python:item.getValues(question)">
<input type="radio"
i18n:attributes="title"
tal:condition="value/radio"
tal:attributes="
name string:question_${question/uid};
value value/value;
checked value/checked;
title string:survey_value_${value/value}" />&nbsp;
title string:survey_value_${value/value}" />
<span tal:condition="not:value/radio"
title="Obligatory question, must be answered"
i18n:attributes="title">***
</span>
</td>
</tr>
</tal:qugroup>

Binary file not shown.

View file

@ -185,7 +185,7 @@ msgid "Minumum number of questions that have to be answered. Empty means all que
msgstr "Anzahl der Fragen, die mindestens beantwortet werden müssen. Keine Angabe: Es müssen alle Fragen beantwortet werden."
msgid "Required"
msgstr "Erforderlich"
msgstr "Pflichtfrage"
msgid "Question must be answered."
msgstr "Frage muss unbedingt beantwortet werden."
@ -241,8 +241,11 @@ msgstr "Bitte beantworten Sie mindestens $minAnswers Fragen."
msgid "Please answer all questions."
msgstr "Bitte beantworten Sie alle Fragen."
msgid "Please answer the obligatory questions marked with an asterisk."
msgstr "Bitte beantworten Sie die mit einem Stern markierten Pflichtfragen."
msgid "Please answer the obligatory questions."
msgstr "Bitte beantworten Sie die Pflichtfragen."
msgid "Please answer the minimum number of questions."
msgstr "Bitte beantworten Sie die angegebene Mindestanzahl an Fragen je Fragengruppe."
msgid "Obligatory question, must be answered"
msgstr "Pflichtfrage, muss beantwortet werden"