Finished main view. Some tuning are to be done.

This commit is contained in:
Jean-Baptiste Lenglet 2016-12-22 21:16:46 +01:00 committed by klmp200
parent 9ac1cab983
commit a3a5a0446d
3 changed files with 117 additions and 78 deletions

View File

@ -36,6 +36,9 @@ class Election(models.Model):
now = timezone.now() now = timezone.now()
return bool(now <= self.end_candidature and now >= self.start_candidature) 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 # Permissions

View File

@ -35,6 +35,10 @@ th {
margin-bottom: 5px; margin-bottom: 5px;
} }
.election__vote-form {
width: auto;
}
.role { .role {
} }
@ -47,6 +51,10 @@ th {
color: darkgreen; color: darkgreen;
} }
.role__error {
color: darkred;
}
.role .role_candidates { .role .role_candidates {
background: white; background: white;
} }
@ -78,6 +86,8 @@ th {
width: 150px; width: 150px;
height: 150px; height: 150px;
min-width: 150px;
min-height: 150px;
background-color: lightgrey; background-color: lightgrey;
} }
@ -122,7 +132,9 @@ th {
border: solid 1px darkgrey; border: solid 1px darkgrey;
color: dimgray;
text-align: center; text-align: center;
font-weight: bolder;
cursor: pointer; cursor: pointer;
} }
@ -131,10 +143,10 @@ th {
} }
.candidate__vote-input:checked + .candidate__vote-choice { .candidate__vote-input:checked + .candidate__vote-choice {
padding: 14px;
border-width: 2px; border-width: 2px;
border-color: darkgreen; border-color: darkgreen;
color: darkgreen; color: darkgreen;
font-weight: bolder;
} }
.candidate__vote-input:checked + .candidate__vote-choice:hover, .candidate__vote-input:checked + .candidate__vote-choice:hover,
@ -142,6 +154,16 @@ th {
background: palegreen; 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 { .election__sumbit-section {
margin-top: 5px; margin-top: 5px;
} }
@ -151,51 +173,74 @@ th {
width: 100%; width: 100%;
padding: 20px; padding: 20px;
background: white; background: white;
border: solid 15px orange; border: solid 15px #4081cb;
text-align: center; text-align: center;
font-size: 200%; font-size: 200%;
font-weight: bolder; font-weight: bolder;
cursor: pointer; cursor: pointer;
} }
.election__sumbit-button:hover,
.election__sumbit-button:focus {
background-color: lightskyblue;
}
</style> </style>
{%- endblock %} {%- endblock %}
{% block content %} {% block content %}
<h3 class="election__title">{{ object.title }}</h3> <h3 class="election__title">{{ election.title }}</h3>
<p class="election__description">{{ object.description }}</p> <p class="election__description">{{ election.description }}</p>
<hr> <hr>
<section> <section>
<p class="election__details"> <p class="election__details">
{% trans %}Polls close {% endtrans %} {% trans %}Polls close {% endtrans %}
<time datetime="{{ election.end_date }}">{{ election.end_date|date("l d F Y") }}</time> at <time>{{ election.end_date|time("G:i") }}</time> <time datetime="{{ election.end_date }}">{{ election.end_date|date("l d F Y") }}</time> at <time>{{ election.end_date|time("G:i") }}</time>
</p> </p>
{# {%- if object.has_voted(request.user) %} {%- if election.has_voted(request.user) %}
<p class="election__elector-infos"> <p class="election__elector-infos">
<span>{% trans %}You already have submitted your vote.{% endtrans %}</span> <span>{% trans %}You already have submitted your vote.{% endtrans %}</span>
</p> </p>
{%- endif %} {%- endif %}
#} </section> </section>
<section> <section>
<form action="/election/1/vote" method="post" class="election__vote-form" name="vote-form" id="vote-form">
{% csrf_token %}
<table> <table>
{%- set election_lists = object.election_list.all() -%} {%- set election_lists = election.election_list.all() -%}
<caption></caption> <caption></caption>
<thead> <thead>
<th>{% trans %}Blank vote{% endtrans %}</th>
{%- for election_list in election_lists %} {%- for election_list in election_lists %}
<th>{{election_list.title}}</th> <th>{{election_list.title}}</th>
{%- endfor %} {%- endfor %}
<th>{% trans %}Blank vote{% endtrans %}</th>
</thead> </thead>
{%- for role in object.role.all() %} {%- for role in election.role.all() %}
<tbody class="role"> {%- set count = [0] %}
{%- set role_data = election_form.data.getlist(role.title) if role.title in election_form.data else [] %}
<tbody class="role {% if election_form.errors[role.title] is defined %}role_error{% endif %}">
<tr class="role__title"> <tr class="role__title">
<td colspan="{{election_lists.count() + 1}}"> <td colspan="{{election_lists.count() + 1}}">
<span>{{role.title}}</span> <span>{{role.title}}</span>
{%- if role.max_choice > 1 %} {%- if role.max_choice > 1 %}
<strong class="role__multiple-choices">{% trans %}You may choose up to{% endtrans %} {{ role.max_choice }} {% trans %}people.{% endtrans %}</strong> <strong class="role__multiple-choices">{% trans %}You may choose up to{% endtrans %} {{ role.max_choice }} {% trans %}people.{% endtrans %}</strong>
{%- endif %} {%- endif %}
{%- if election_form.errors[role.title] is defined %}
{%- for error in election_form.errors.as_data()[role.title] %}
<strong class="role__error">{{ error.message }}</strong>
{%- endfor %}
{%- endif %}
</td> </td>
</tr> </tr>
<tr class="role_candidates"> <tr class="role_candidates">
<td class="list-per-role">
{%- if election.is_active and role.max_choice == 1 %}
<input id="id_{{ role.title }}_{{ count[0] }}" class="candidate__vote-input" type="radio" name="{{ role.title }}" value {{ '' if role_data in election_form else 'checked' }}>
<label for="id_{{ role.title }}_{{ count[0] }}" class="candidate__vote-choice">
<span>{% trans %}Choose blank vote{% endtrans %}</span>
</label>
{%- set _ = count.append(count.pop() + 1) %}
{%- endif %}
</td>
{%- for election_list in election_lists %} {%- for election_list in election_lists %}
<td class="list-per-role"> <td class="list-per-role">
<ul class="list-per-role__candidates"> <ul class="list-per-role__candidates">
@ -212,42 +257,33 @@ th {
<q class="candidate__program">{{ candidature.program or '' }}</q> <q class="candidate__program">{{ candidature.program or '' }}</q>
</figcaption> </figcaption>
</figure> </figure>
{%- if object.is_active %} {%- if election.is_active %}
<input id="id" class="candidate__vote-input" type="radio" name="vote"> <input id="id_{{ role.title }}_{{ count[0] }}" type="{{ 'checkbox' if role.max_choice > 1 else 'radio' }}" {{ 'checked' if candidature.id|string in role_data else '' }} name="{{ role.title }}" value="{{ candidature.id }}" class="candidate__vote-input">
<label for="id" class="candidate__vote-choice"> <label for="id_{{ role.title }}_{{ count[0] }}" class="candidate__vote-choice">
<span>{% trans %}Choose{% endtrans %} {{ candidature.user.nick_name or candidature.user.first_name }}</span> <span>{% trans %}Choose{% endtrans %} {{ candidature.user.nick_name or candidature.user.first_name }}</span>
</label> </label>
{% endif %} {%- set _ = count.append(count.pop() + 1) %}
{%- endif %}
</li> </li>
{%- endfor %} {%- endfor %}
</ul> </ul>
</td> </td>
{%- endfor %} {%- endfor %}
<td class="list-per-role">
{%- if object.is_active %}
<input id="id" class="candidate__vote-input" type="radio" name="vote">
<label for="id" class="candidate__vote-choice">
<span>{% trans %}Choose blank vote{% endtrans %}</span>
</label>
{% endif %}
</td>
</tr> </tr>
</tbody> </tbody>
{%- endfor %} {%- endfor %}
</table> </table>
</form>
</section> </section>
<section class="election__sumbit-section"> <section class="election__sumbit-section">
<button class="election__sumbit-button">{% trans %}Submit the vote !{% endtrans %}</button> <button class="election__sumbit-button" form="vote-form">{% trans %}Submit the vote !{% endtrans %}</button>
</section> </section>
<section class="election__add-elements">
<a href="{{url('election:create_list')}}">{% trans %}Add a new list{% endtrans %}</a> <a href="{{url('election:create_list')}}">{% trans %}Add a new list{% endtrans %}</a>
<a href="{{url('election:create_role')}}">{% trans %}Add a new role{% endtrans %}</a> <a href="{{url('election:create_role')}}">{% trans %}Add a new role{% endtrans %}</a>
<form action="{{url('election:candidate', election_id=object.id)}}" method="post">{{candidate_form}} </section>
<form action="{{url('election:candidate', election_id=election.id)}}" method="post">{{candidate_form}}
{% csrf_token %} {% csrf_token %}
<p><input type="submit" value="{% trans %}Candidate{% endtrans %}" /></p> <p><input type="submit" value="{% trans %}Candidate{% endtrans %}" /></p>
</form> </form>
<form action="{{url('election:vote', election_id=object.id)}}" method="post">
{{election_form.as_p()}}
<p><input type="submit" value="{% trans %}Vote{% endtrans %}" /></p>
{% csrf_token %}
</form>
{% endblock %} {% endblock %}

View File

@ -40,7 +40,7 @@ class VoteCheckbox(forms.ModelMultipleChoiceField):
def validate(self, qs): def validate(self, qs):
if qs.count() > self.max_choice: 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 # Forms