diff --git a/election/models.py b/election/models.py index e4c03599..18343383 100644 --- a/election/models.py +++ b/election/models.py @@ -36,6 +36,9 @@ class Election(models.Model): now = timezone.now() return bool(now <= self.end_candidature and now >= self.start_candidature) + def has_voted(self, user): + return hasattr(user, 'has_voted') and user.has_voted.all() == list(self.role.all()) + # Permissions diff --git a/election/templates/election/election_detail.jinja b/election/templates/election/election_detail.jinja index 2721226c..ebcd4cb6 100644 --- a/election/templates/election/election_detail.jinja +++ b/election/templates/election/election_detail.jinja @@ -35,6 +35,10 @@ th { margin-bottom: 5px; } +.election__vote-form { + width: auto; +} + .role { } @@ -47,6 +51,10 @@ th { color: darkgreen; } +.role__error { + color: darkred; +} + .role .role_candidates { background: white; } @@ -78,6 +86,8 @@ th { width: 150px; height: 150px; + min-width: 150px; + min-height: 150px; background-color: lightgrey; } @@ -117,13 +127,15 @@ th { } .candidate__vote-choice { - margin-top: 5px; - padding: 15px; + margin-top: 5px; + padding: 15px; - border: solid 1px darkgrey; + border: solid 1px darkgrey; - text-align: center; - cursor: pointer; + color: dimgray; + text-align: center; + font-weight: bolder; + cursor: pointer; } .candidate__vote-choice:hover, .candidate__vote-choice:focus { @@ -131,10 +143,10 @@ th { } .candidate__vote-input:checked + .candidate__vote-choice { + padding: 14px; border-width: 2px; border-color: darkgreen; color: darkgreen; - font-weight: bolder; } .candidate__vote-input:checked + .candidate__vote-choice:hover, @@ -142,6 +154,16 @@ th { background: palegreen; } +.role_error .candidate__vote-input:checked + .candidate__vote-choice { + border-color: darkred; + color: darkred; +} + +.role_error .candidate__vote-input:checked + .candidate__vote-choice:hover, +.role_error .candidate__vote-input:checked + .candidate__vote-choice:focus { + background: indianred; +} + .election__sumbit-section { margin-top: 5px; } @@ -151,103 +173,117 @@ th { width: 100%; padding: 20px; background: white; - border: solid 15px orange; + border: solid 15px #4081cb; text-align: center; font-size: 200%; font-weight: bolder; cursor: pointer; } + +.election__sumbit-button:hover, +.election__sumbit-button:focus { + background-color: lightskyblue; +} {%- endblock %} {% block content %} -

{{ object.title }}

-

{{ object.description }}

+

{{ election.title }}

+

{{ election.description }}


{% trans %}Polls close {% endtrans %} at

-{# {%- if object.has_voted(request.user) %} + {%- if election.has_voted(request.user) %}

{% trans %}You already have submitted your vote.{% endtrans %}

{%- endif %} - #}
+
- - {%- set election_lists = object.election_list.all() -%} - - - {%- for election_list in election_lists %} - - {%- endfor %} - - - {%- for role in object.role.all() %} - - - - - + + {% csrf_token %} +
{{election_list.title}}{% trans %}Blank vote{% endtrans %}
- {{role.title}} - {%- if role.max_choice > 1 %} - {% trans %}You may choose up to{% endtrans %} {{ role.max_choice }} {% trans %}people.{% endtrans %} - {%- endif %} -
+ {%- set election_lists = election.election_list.all() -%} + + + {%- for election_list in election_lists %} - + {%- endfor %} - - - - {%- endfor %} -
{% trans %}Blank vote{% endtrans %} -
    - {%- for candidature in election_list.candidature.filter(role=role) %} -
  • -
    -
    - {%- if candidature.user.profile_pict %} - {% trans %}Profile{% endtrans %} - {%- endif %} -
    -
    - {{ candidature.user.first_name }} {{candidature.user.nick_name or ''}} {{ candidature.user.last_name }} - {{ candidature.program or '' }} -
    -
    - {%- if object.is_active %} - - - {% endif %} -
  • - {%- endfor %} -
-
{{election_list.title}} - {%- if object.is_active %} - - - {% endif %} -
+ + {%- for role in election.role.all() %} + {%- set count = [0] %} + {%- set role_data = election_form.data.getlist(role.title) if role.title in election_form.data else [] %} + + + + {{role.title}} + {%- if role.max_choice > 1 %} + {% trans %}You may choose up to{% endtrans %} {{ role.max_choice }} {% trans %}people.{% endtrans %} + {%- endif %} + {%- if election_form.errors[role.title] is defined %} + {%- for error in election_form.errors.as_data()[role.title] %} + {{ error.message }} + {%- endfor %} + {%- endif %} + + + + + {%- if election.is_active and role.max_choice == 1 %} + + + {%- set _ = count.append(count.pop() + 1) %} + {%- endif %} + + {%- for election_list in election_lists %} + + + + {%- endfor %} + + + {%- endfor %} + +
- +
- {% trans %}Add a new list{% endtrans %} - {% trans %}Add a new role{% endtrans %} -
{{candidate_form}} +
+ {% trans %}Add a new list{% endtrans %} + {% trans %}Add a new role{% endtrans %} +
+ {{candidate_form}} {% csrf_token %}

-
- {{election_form.as_p()}} -

- {% csrf_token %} -
{% endblock %} \ No newline at end of file diff --git a/election/views.py b/election/views.py index 3a703935..5368bb3f 100644 --- a/election/views.py +++ b/election/views.py @@ -40,7 +40,7 @@ class VoteCheckbox(forms.ModelMultipleChoiceField): def validate(self, qs): if qs.count() > self.max_choice: - raise forms.ValidationError(_("You have selected too much candidate")) + raise forms.ValidationError(_("You have selected too much candidates."), code='invalid') # Forms