parent
6bb2dfddcb
commit
90bb2b6265
@ -119,11 +119,23 @@ class ListChoiceQuestion(Question):
|
||||
def pretty_answer(self, answer):
|
||||
if len(answer.choices) == 0:
|
||||
return '(blank votes)'
|
||||
return ', '.join([self.choices[choice].name for choice in answer.choices])
|
||||
flat_choices = self.flatten_choices()
|
||||
return ', '.join([flat_choices[choice].name for choice in answer.choices])
|
||||
|
||||
def max_bits(self):
|
||||
answer = self.answer_type(choices=list(range(len(self.choices))))
|
||||
return len(EosObject.to_json(EosObject.serialise_and_wrap(answer))) * 8
|
||||
|
||||
def flatten_choices(self):
|
||||
# Return a flat list of Choices, without Tickets
|
||||
flat_choices = []
|
||||
for choice in self.choices:
|
||||
if isinstance(choice, Ticket):
|
||||
for choice2 in choice.choices:
|
||||
flat_choices.append(choice2)
|
||||
else:
|
||||
flat_choices.append(choice)
|
||||
return flat_choices
|
||||
|
||||
class ApprovalAnswer(Answer):
|
||||
choices = ListField(IntField())
|
||||
@ -140,6 +152,16 @@ class PreferentialQuestion(ListChoiceQuestion):
|
||||
class Choice(EmbeddedObject):
|
||||
name = StringField()
|
||||
party = StringField(default=None)
|
||||
|
||||
@property
|
||||
def party_or_ticket(self):
|
||||
if self.party is not None:
|
||||
return self.party
|
||||
else:
|
||||
ticket = self.recurse_parents(Ticket)
|
||||
if ticket:
|
||||
return ticket.name
|
||||
return None
|
||||
|
||||
class Ticket(EmbeddedObject):
|
||||
name = StringField()
|
||||
|
@ -109,10 +109,14 @@
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.preferential-choice .party-name {
|
||||
.preferential-choice .party-name, .preferential-choice .ticket-party-name {
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.ticket .ticket-party-name {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.ticket > .content > .party-name {
|
||||
min-height: 2em;
|
||||
}
|
||||
|
@ -26,7 +26,7 @@
|
||||
<div class="field">
|
||||
<div class="ui checkbox">
|
||||
<input type="checkbox" id="question-choice-{{ loop.index0 }}" onchange="choicesChanged();">
|
||||
<label for="question-choice-{{ loop.index0 }}">{{ choice }}</label>
|
||||
<label for="question-choice-{{ loop.index0 }}">{{ choice.name }}{% if choice.party %} – {{ choice.party }}{% endif %}</label>
|
||||
</div>
|
||||
</div>
|
||||
{% endfor %}
|
||||
|
@ -20,7 +20,7 @@
|
||||
{% for choice in booth.answers[loop.index0].value.choices %}
|
||||
<div class="item">
|
||||
<i class="checkmark icon"></i>
|
||||
<div class="content">{{ question.choices.__getitem__(choice) }}</div>
|
||||
<div class="content">{{ question.choices.__getitem__(choice).name }}{% if question.choices.__getitem__(choice).party %}{{ question.choices.__getitem__(choice).party }}{% endif %}</div>
|
||||
</div>
|
||||
{% else %}
|
||||
<div class="item">
|
||||
|
@ -34,12 +34,22 @@
|
||||
<p>You have selected more than the maximum allowed number of choices. To proceed, you must deselect some choices by dragging them from the blue box back to the grey box.</p>
|
||||
</div>
|
||||
|
||||
{% set flat_choices = election.questions.__getitem__(questionNum).flatten_choices() %}
|
||||
|
||||
{% macro printchoice(choice, ticket=None) %}
|
||||
<div class="preferential-choice" data-choiceno="{{ loop.index0 }}">
|
||||
<div class="preferential-choice" data-choiceno="{{ flat_choices.indexOf(choice) }}">
|
||||
<div class="number"></div>
|
||||
<div class="content">
|
||||
<div class="candidate-name">{{ choice.name }}</div>
|
||||
{% if (ticket and choice.party and choice.party != ticket.name) or (not ticket and choice.party) %}<div class="party-name">{{ choice.party }}</div>{% endif %}
|
||||
{% if choice.party %}
|
||||
{% if (ticket and choice.party != ticket.name) or not ticket %}
|
||||
<div class="party-name">{{ choice.party }}</div>
|
||||
{% else %}
|
||||
<div class="ticket-party-name">{{ choice.party }}</div>
|
||||
{% endif %}
|
||||
{% elif ticket %}
|
||||
<div class="ticket-party-name">{{ ticket.name }}</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
{% endmacro %}
|
||||
@ -51,7 +61,7 @@
|
||||
{% for choice in election.questions.__getitem__(questionNum).choices.impl %}
|
||||
{% if choice.choices %}
|
||||
{# Ticket #}
|
||||
<div class="preferential-choice ticket" data-choiceno="{{ loop.index0 }}">
|
||||
<div class="preferential-choice ticket" data-ticketno="{{ loop.index0 }}">
|
||||
<div class="number"></div>
|
||||
<div class="content">
|
||||
<div class="party-name">{{ choice.name }}</div>
|
||||
@ -71,6 +81,7 @@
|
||||
|
||||
<script>
|
||||
var allowAdding = true;
|
||||
var flat_choices = election.questions.__getitem__(booth.questionNum).flatten_choices();
|
||||
|
||||
function choicesChanged() {
|
||||
// Recalculate numbers
|
||||
@ -103,10 +114,9 @@
|
||||
}
|
||||
|
||||
// Fill in ballot with previous selections
|
||||
if (booth.answers[booth.questionNum]) {
|
||||
for (var selection of booth.answers[booth.questionNum].value.choices) { // Answer already serialised
|
||||
$(".preferential-choice[data-choiceno=" + selection + "]").detach().appendTo("#question-choices-selected .dragarea");
|
||||
}
|
||||
if (booth.q_state[booth.questionNum]) {
|
||||
$("#question-choices-selected .dragarea").html(booth.q_state[booth.questionNum][0]);
|
||||
$("#question-choices-remaining .dragarea").html(booth.q_state[booth.questionNum][1]);
|
||||
choicesChanged();
|
||||
}
|
||||
|
||||
@ -117,9 +127,6 @@
|
||||
if ("dragarea-hint" in el.classList) {
|
||||
return false;
|
||||
}
|
||||
//if ("ticket" in el.classList && !("party-name" in handle.classList)) {
|
||||
// return false;
|
||||
//}
|
||||
if ($.contains(document.querySelector("#question-choices-remaining"), el)) {
|
||||
return allowAdding;
|
||||
}
|
||||
@ -129,16 +136,33 @@
|
||||
}
|
||||
);
|
||||
|
||||
function breakTicket(ticket) {
|
||||
ticket.find(".ticket-choices .preferential-choice").each(function(i, el) {
|
||||
$(el).detach().insertAfter(ticket);
|
||||
});
|
||||
ticket.remove();
|
||||
}
|
||||
|
||||
dragulaChoices.on("drop", function(el, target, source, sibling) {
|
||||
// If the source or target is a ticket, break the ticket
|
||||
if ($(source).parents(".ticket").length > 0) {
|
||||
breakTicket($(source).parents(".ticket").first())
|
||||
}
|
||||
if ($(target).parents(".ticket").length > 0) {
|
||||
breakTicket($(target).parents(".ticket").first())
|
||||
}
|
||||
|
||||
choicesChanged();
|
||||
});
|
||||
|
||||
function saveSelections() {
|
||||
selections = [];
|
||||
$("#question-choices-selected .preferential-choice").each(function(i, el) {
|
||||
$("#question-choices-selected .preferential-choice:not(.ticket)").each(function(i, el) {
|
||||
selections.push(parseInt(el.dataset.choiceno));
|
||||
});
|
||||
answer = eosjs.eos.base.election.__all__.PreferentialAnswer(eosjs.__kwargtrans__({choices: selections}));
|
||||
booth.answers[booth.questionNum] = eosjs.eos.core.objects.__all__.EosObject.serialise_and_wrap(answer);
|
||||
|
||||
booth.q_state[booth.questionNum] = [$("#question-choices-selected .dragarea").html(), $("#question-choices-remaining .dragarea").html()]; // wew lad
|
||||
}
|
||||
</script>
|
||||
|
@ -16,11 +16,13 @@
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#}
|
||||
|
||||
{% set flat_choices = question.flatten_choices() %}
|
||||
|
||||
{% if booth.answers[loop.index0].value.choices.length > 0 %}
|
||||
<div class="ui ordered list">
|
||||
{% for choice in booth.answers[loop.index0].value.choices %}
|
||||
<div class="item">
|
||||
<div class="content">{{ question.choices.__getitem__(choice) }}</div>
|
||||
<div class="content">{{ flat_choices[choice].name }}{% if flat_choices[choice].party_or_ticket %} – {{ flat_choices[choice].party_or_ticket }}{% endif %}</div>
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
|
@ -55,6 +55,7 @@
|
||||
booth = {
|
||||
"questionNum": 0,
|
||||
"answers": [],
|
||||
"q_state": []
|
||||
};
|
||||
}
|
||||
resetBooth();
|
||||
@ -136,6 +137,7 @@
|
||||
techDetails = '<p>Technical details: ' + err + '</p>';
|
||||
}
|
||||
$("#booth-content").html('<div class="ui error message"><p>We were unable to display the next page of the voting booth. For your security, your ballot selections have been cleared. Please try again. If this problem persists, contact the {{ election.kind }} administrator.</p>' + techDetails + '</div>');
|
||||
console.error(err);
|
||||
}
|
||||
|
||||
function showTemplate(template, opts, destination) {
|
||||
|
Loading…
Reference in New Issue
Block a user