polls: added multi-choices polls

This commit is contained in:
Eldeberen 2021-02-22 22:49:11 +01:00
parent b23fc15b6e
commit d6512bb197
Signed by untrusted user: Darks
GPG Key ID: 7515644268BE1433
5 changed files with 96 additions and 3 deletions

View File

@ -1,5 +1,5 @@
from flask_wtf import FlaskForm
from wtforms import StringField, SubmitField, TextAreaField
from wtforms import StringField, SubmitField, TextAreaField, SelectField
from wtforms.fields.html5 import DateTimeField
from wtforms.validators import InputRequired, Optional
@ -19,6 +19,13 @@ class PollForm(FlaskForm):
# TODO: add a validator to check if there is at least one choice
]
)
type = SelectField(
'Type',
choices=[
('simplepoll', 'Réponse unique'),
('multiplepoll', 'Réponses multiples')
]
)
start = DateTimeField(
'Début',
default=datetime.now(),

View File

@ -0,0 +1,49 @@
from app import db
from app.models.poll import Poll, PollAnswer
from collections import Counter
from itertools import chain
class MultiplePoll(Poll):
"""Poll with many answers allowed"""
__tablename__ = 'multiplepoll'
# Names of templates
template = 'multiplepoll.html'
__mapper_args__ = {
'polymorphic_identity': __tablename__,
}
def __init__(self, author, title, choices, **kwargs):
choices = [Choice(i, t) for i, t in enumerate(choices)]
super().__init__(author, title, choices, **kwargs)
# Mandatory methods
def vote(self, user, request):
answers_id = []
for c in self.choices:
if f"pollanswers-{c.id}" in request.form:
answers_id.append(c.id)
return PollAnswer(self, user, answers_id)
@property
def results(self):
values = {c: 0 for c in self.choices}
counter = Counter(values)
for a in self.answers:
counter.update([self.choice_from_id(id) for id in a.answer])
return counter
# Custom method
def choice_from_id(self, id):
for c in self.choices:
if c.id == id:
return c
return None
class Choice():
def __init__(self, id, title):
self.id = id
self.title = title

View File

@ -3,6 +3,7 @@ from flask import abort, flash, redirect, request, url_for
from flask_login import current_user
from app.models.polls.simple import SimplePoll
from app.models.polls.multiple import MultiplePoll
from app.forms.poll import PollForm
from app.utils.render import render
@ -10,10 +11,14 @@ from app.utils.render import render
def account_polls():
form = PollForm()
polls = current_user.polls
polls_types = {
'simplepoll': SimplePoll,
'multiplepoll': MultiplePoll,
}
if form.validate_on_submit():
choices = list(filter(None, form.choices.data.split('\n')))
p = SimplePoll(current_user, form.title.data, choices,
p = polls_types[form.type.data](current_user, form.title.data, choices,
start=form.start.data, end=form.end.data)
db.session.add(p)
db.session.commit()

View File

@ -9,7 +9,6 @@
<section class="form">
<h1>Créer un sondage</h1>
<form action="" method="post">
{{ form.hidden_tag() }}
<div>
{{ form.title.label }}<br>
{{ form.title(size=32) }}<br>
@ -24,6 +23,13 @@
<span class="msgerror">{{ error }}</span>
{% endfor %}
</div>
<div>
{{ form.type.label }}<br>
{{ form.type }}<br>
{% for error in form.type.errors %}
<span style="color: red;">{{ error }}</span>
{% endfor %}
</div>
<div>
{{ form.start.label }}
{{ form.start() }}
@ -38,6 +44,7 @@
<span class="msgerror">{{ error }}</span>
{% endfor %}
</div>
{{ form.hidden_tag() }}
<div>{{ form.submit(class_="bg-ok") }}</div>
</form>
</section>

View File

@ -0,0 +1,25 @@
{% macro choices(poll) %}
<fieldset>
{% for choice in poll.choices %}
<input type="checkbox" id="poll{{ poll.id }}-{{ choice.id }}" name="pollanswers-{{ choice.id }}" value="{{ choice.id }}" />
<label for="poll{{ poll.id }}-{{ choice.id }}">{{ choice.title }}</label><br/>
{% endfor %}
</fieldset>
{% endmacro %}
{% macro results(poll) %}
<table>
{% for choice, votes in poll.results.most_common() %}
<tr>
<td><label for="poll{{ poll.id }}-{{ choice.id }}">{{ choice.title }}</label></td>
<td>
<progress id="poll{{ poll.id }}-{{ choice.id }}" value="{{ votes }}" max="{{ len(poll.answers) }}"></progress>
</td>
<td>{{ votes }}</td>
</tr>
{% endfor %}
<tr>
<th>Participations</th><th></th><th>{{ len(poll.answers) }}</th>
</tr>
</table>
{% endmacro %}