Merge Sara and Jamie's work from November 30 and December 1 together

dj111py38
Mark Jenkins 2015-12-01 23:59:17 -06:00
commit 3d06cd5570
7 changed files with 90 additions and 10 deletions

View File

@ -0,0 +1,24 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('questionnaire', '0003_auto_20151129_0727'),
]
operations = [
migrations.AddField(
model_name='question',
name='parse_html',
field=models.BooleanField(default=False, verbose_name=b'parse question text and footer as html?'),
),
migrations.AlterField(
model_name='question',
name='type',
field=models.CharField(help_text="Determines the means of answering the question. An open question gives the user a single-line textfield, multiple-choice gives the user a number of choices he/she can choose from. If a question is multiple-choice, enter the choices this user can choose from below'.", max_length=32, verbose_name='Type of question'),
),
]

View File

@ -0,0 +1,19 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('questionnaire', '0004_auto_20151202_0230'),
]
operations = [
migrations.AddField(
model_name='questionset',
name='parse_html',
field=models.BooleanField(default=False, verbose_name=b'parse questionset heading and text as html?'),
),
]

View File

@ -101,6 +101,8 @@ class QuestionSet(models.Model):
help_text = """Current options are 'femaleonly' or 'maleonly' and shownif="QuestionNumber,Answer" which takes the same format as <tt>requiredif</tt> for questions.""")
text = models.TextField(u'Text', help_text="This is interpreted as Textile: <a href='http://en.wikipedia.org/wiki/Textile_%28markup_language%29' target='_blank'>http://en.wikipedia.org/wiki/Textile_(markup_language)</a>")
parse_html = models.BooleanField("parse questionset heading and text as html?", null=False, default=False)
def questions(self):
if not hasattr(self, "__qcache"):
def numeric_number(val):
@ -113,6 +115,10 @@ class QuestionSet(models.Model):
self.__qcache = questions_with_sort_id + questions_with_out_sort_id
return self.__qcache
def sorted_questions(self):
questions = self.questions()
return sorted(questions, key = lambda question : str(question.sort_id)+question.number)
def next(self):
qs = self.questionnaire.questionsets()
retnext = False
@ -298,6 +304,8 @@ class Question(models.Model):
'eg. <tt>requiredif="Q1,A or Q2,B"</tt>')
footer = models.TextField(u"Footer", help_text="Footer rendered below the question interpreted as textile", blank=True)
parse_html = models.BooleanField("parse question text and footer as html?", null=False, default=False)
def questionnaire(self):
return self.questionset.questionnaire

View File

@ -77,10 +77,6 @@ def question_open(request, question):
valueaslist = ast.literal_eval(possiblevalue)
if len(valueaslist) > 0:
value = valueaslist[0]
# print 'open or open-textfield question proc, value found: ', possiblevalue, ', type ', type(possiblevalue), ', value used ', value
# else:
# print 'open or open-textfield question proc, no value found'
# print 'open or open-textfield question proc, runid , question_id ', get_runid_from_request(request), ',', question.id
return {
'required': question.getcheckdict().get('required', False),
'value': value,
@ -108,6 +104,12 @@ def process_simple(question, ansdict):
#the key here is to note that requiredif has already been evaluated or we wouldn't have reached this point, so we don't have to recheck
if not ans.strip() and (checkdict.get('required', False) or checkdict.get('requiredif', False)):
raise AnswerException(_(u'Field cannot be blank'))
maxwords = checkdict.get('maxwords', False)
if maxwords:
maxwords = int(maxwords)
answords = len(ans.split())
if answords > maxwords:
raise AnswerException(_(u'Answer is ' + str(answords) + ' words. Please shorten answer to ' + str(maxwords) + ' words or less'))
if ansdict.has_key('comment') and len(ansdict['comment']) > 0:
return dumps([ans, [ansdict['comment']]])
if ans:

View File

@ -1,5 +1,6 @@
{% extends "admin/change_list.html" %}
{% block result_list %}
<script language="javascript">
function togglehide(id) {
obj = document.getElementById("questionnaire-" + id);
@ -25,7 +26,7 @@ function togglehide(id) {
<div id="questionnaire-{{ questionnaire.id }}" style="margin-bottom: 2em;">
{% for questionset in questionnaire.questionsets %}
<H4>QuestionSet: <a href="/admin/questionnaire/questionset/{{ questionset.id }}/"><font color="#111">{{ questionset.heading }} ({{ questionset.sortid }})</font></a></H4>
{% for q in questionset.questions %}
{% for q in questionset.sorted_questions %}
<a href="{{ q.id }}/">{{ q.number }}. {{ q.text }}</a> [{{ q.type }}]<br />
{% endfor %}
&rarr; <a href="add/?questionset={{ questionset.id }}">Add Question to <tt>{{ questionset.heading }}</tt></a>

View File

@ -42,13 +42,21 @@
<h2 class="questionset-title">
{% if questionset.heading %}
{% if questionset.parse_html %}
{{ questionset.heading|safe }}
{% else %}
{{ questionset.heading }}
{% endif %}
{% endif %}
</h2>
<div class="questionset-text">
{% if questionset.text %}
{% if questionset.parse_html %}
{{ questionset.text|safe }}
{% else %}
{{ questionset.text }}
{% endif %}
{% endif %}
</div>
@ -80,8 +88,12 @@
{% include qdict.template %}
{% else %}
<div class="question-text {% if qdict.required %}required{% endif %}">
<span class="qnumber">{{ question.display_number|safe }}.</span>
<span class="qnumber">{% if not question.parse_html %}{{ question.display_number|safe }}.{% endif %}</span>
{% if question.parse_html %}
{{ question.text|safe }}
{% else %}
{{ question.text }}
{% endif %}
</div>
<div class="answer">
{% if error %}
@ -91,12 +103,16 @@
</div>
{% endif %}
</div> <!-- /question container -->
{% if question.footer %}
<div class="question-footer">
{{ question.footer }}
{% if question.footer %}
<div class="question-footer" id="qc_{{ question.number }}_footer" {{qdict.footerchecks|safe}}>
{% if question.parse_html %}
{{ question.footer|safe }}
{% else %}
{{ question.footer }}
{% endif %}
<div class="clearfix"></div>
</div>
{% endif %}
{% endif %}
{% endwith %}
{% endfor %}

View File

@ -555,6 +555,9 @@ def show_questionnaire(request, runinfo, errors={}):
substitute_answer(qvalues, runinfo.questionset)
#we make it clear to the user that we're going to sort by sort id then number, so why wasn't it doing that?
questions = sorted(questions, key=lambda question: str(question.sort_id)+question.number)
for question in questions:
# if we got here the questionset will at least contain one question
# which passes, so this is all we need to check for
@ -584,6 +587,13 @@ def show_questionnaire(request, runinfo, errors={}):
parser = BooleanParser(dep_check)
qdict['checkstring'] = ' checks="%s"' % parser.toString(depon)
jstriggers.append('qc_%s' % question.number)
footerdep = cd.get('footerif', None)
if footerdep:
parser = BooleanParser(dep_check)
qdict['footerchecks'] = ' checks="%s"' % parser.toString(footerdep)
jstriggers.append('qc_%s_footer' % question.number)
if 'default' in cd and not question.number in cookiedict:
qvalues[question.number] = cd['default']
if Type in QuestionProcessors: