1
{% extends "base.html" %}
5
<script type="text/javascript">
8
// This is called when a checkbox has been toggled. If it has been
9
// set to true the associated text input will be disabled, otherwise
10
// it will be enabled.
11
function checkbox_changed(name) {
12
var input = document.getElementById(name);
13
var checkbox = document.getElementById(name + '_lock');
14
if (input && checkbox)
15
input.disabled = checkbox.checked;
19
// Constructor for calc_entry.
20
function calc_entry(type, id, voters, locked) {
28
// Try to parse the value of a text input as an integer, return
30
function parse_int_from_input(input_name) {
31
elt = document.getElementById(input_name);
32
var value = parseInt(elt.value);
34
window.alert(elt.value + ' kan inte tolkas som ett tal!');
39
// Calculate the ballot distribution.
40
function calculate() {
42
var calc_entries = new Array();
43
var early_calc_entries = new Array();
44
var locked_ballots = 0;
45
var unlocked_subregion_voters = 0;
46
var unlocked_station_voters = 0;
47
var unlocked_entries = 0;
48
var unlocked_locals = 0;
50
ballots_available = parse_int_from_input('ballots_available');
51
if (isNaN(ballots_available))
53
var total_ballots = ballots_available;
54
var unit = parse_int_from_input('unit_size');
58
var early_percentage = parse_int_from_input('early_percentage');
59
if (isNaN(early_percentage))
61
if (early_percentage < 0 || early_percentage > 100) {
62
window.alert('Procentandelen valsedlar till fortidsrostningen ' +
63
'maste vara mellan 0 och 100!');
69
// Add the entries for all subregions
70
{% for subregion in subregions %}
71
var eltId = 'region_{{ subregion.shortname }}_value';
72
var inputElt = document.getElementById(eltId);
73
var lockElt = document.getElementById(eltId + '_lock');
74
cy = new calc_entry('region', '{{ subregion.shortname }}',
75
{{ subregion.total_voters }}, lockElt.checked);
76
if (lockElt.checked) {
77
var ballots = parse_int_from_input(eltId);
80
locked_ballots += ballots;
84
unlocked_subregion_voters += {{ subregion.total_voters }};
88
calc_entries.push(cy);
93
// Add the entries for all early voting stations
94
{% for local in locals %}
95
var eltId = 'local_{{ local.pk }}_value';
96
var inputElt = document.getElementById(eltId);
97
var lockElt = document.getElementById(eltId + '_lock');
98
cy = new calc_entry('local', {{ local.pk }}, 0, lockElt.checked);
99
if (lockElt.checked) {
100
var ballots = parse_int_from_input(eltId);
103
locked_ballots += ballots;
104
cy.ballots = ballots;
110
early_calc_entries.push(cy);
115
// Add the entries for all normal voting stations.
116
{% for station in stations %}
117
var eltId = 'station_{{ station.pk }}_value';
118
var inputElt = document.getElementById(eltId);
119
var lockElt = document.getElementById(eltId + '_lock');
120
cy = new calc_entry('station', {{ station.pk }},
121
{{ station.voters }}, lockElt.checked);
122
if (lockElt.checked) {
123
var ballots = parse_int_from_input(eltId);
126
locked_ballots += ballots;
127
cy.ballots = ballots;
130
unlocked_station_voters += {{ station.voters }};
134
calc_entries.push(cy);
138
var unlocked_voters =
139
unlocked_subregion_voters + unlocked_station_voters;
141
// If all regions and stations are locked, stop now.
142
if (unlocked_entries == 0)
145
// Subtract all locked ballots.
146
total_ballots -= locked_ballots;
147
if (total_ballots < 0) {
148
window.alert('Du har last fler valsedlar an du har tillgangliga!');
152
// Check that the unit is sane.
153
rest_ballots = total_ballots % unit;
154
total_ballots -= rest_ballots;
155
ballot_units = total_ballots / unit;
156
if (total_ballots <= 0 || ballot_units < unlocked_entries) {
157
window.alert('Du har inte tillrackligt manga valsedlar! ' +
158
'Minska paketstorleken.');
163
// If there are unlocked early voting stations, calculate the number of
164
// ballots they should have.
165
if (unlocked_locals > 0) {
166
var early_units_min = unlocked_locals;
167
var early_units = Math.round(ballot_units *
168
(unlocked_station_voters /
170
early_percentage / 100);
171
early_units = (early_units < early_units_min ?
172
early_units_min : early_units);
173
early_units_per_station = Math.floor(early_units / unlocked_locals);
174
ballot_units -= early_units;
176
var last_unlocked_early = 0;
177
for (i = 0; i < early_calc_entries.length; ++i) {
178
if (!early_calc_entries[i].locked) {
179
early_calc_entries[i].ballots += unit * early_units_per_station;
180
early_units -= early_units_per_station;
181
last_unlocked_early = i;
184
early_calc_entries[last_unlocked_early].ballots +=
191
// Give one unit to each entry.
192
voters_per_unit = unlocked_voters / ballot_units;
193
for (i = 0; i < calc_entries.length; ++i) {
194
if (!calc_entries[i].locked) {
195
log += 'Giving 1 unit to ' + calc_entries[i].type +
196
'_' + calc_entries[i].id + "\n";
197
calc_entries[i].ballots += unit;
198
calc_entries[i].voters -= voters_per_unit;
201
ballot_units -= unlocked_entries;
203
// Distribute the rest of the units as fairly as possible.
204
function compare_voters(a, b) { return b.voters - a.voters; }
205
var voter_threshold = voters_per_unit;
206
while (ballot_units > 0) {
207
calc_entries.sort(compare_voters);
208
var old_ballot_units = ballot_units;
209
for (i = 0; i < calc_entries.length && ballot_units > 0; ++i) {
210
if (!calc_entries[i].locked &&
211
calc_entries[i].voters > voter_threshold) {
212
calc_entries[i].ballots += unit;
213
calc_entries[i].voters -= voters_per_unit;
217
if (ballot_units == old_ballot_units)
218
voter_threshold -= voters_per_unit / 4;
221
// Set the ballot values for all regions and stations.
222
for (i = 0; i < calc_entries.length; ++i) {
223
name = calc_entries[i].type + '_' + calc_entries[i].id + '_value';
225
document.getElementById(calc_entries[i].type + '_' +
226
calc_entries[i].id + '_value');
227
value_elt.value = '' + calc_entries[i].ballots;
230
// Set the ballot values for all early stations
231
for (i = 0; i < early_calc_entries.length; ++i) {
232
name = early_calc_entries[i].type + '_' +
233
early_calc_entries[i].id + '_value';
235
document.getElementById(early_calc_entries[i].type + '_' +
236
early_calc_entries[i].id + '_value');
237
value_elt.value = '' + early_calc_entries[i].ballots;
240
document.getElementById('input_rest_ballots').value = ''+ rest_ballots;
243
for (i = 0; i < early_calc_entries.length; ++i)
244
sum += early_calc_entries[i].ballots;
245
for (i = 0; i < calc_entries.length; ++i)
246
sum += calc_entries[i].ballots;
248
if (sum + rest_ballots != ballots_available)
249
window.alert('Antalet fordelade valsedlar (' + sum +
250
') plus resten (' + rest_ballots +
251
') ar inte lika med det totala antalet (' +
252
ballots_available + ')! Lita inte pa berakningen!');
264
<h1>{{ region.name }}</h1>
267
<form action="../save_calculation/" method="POST">
268
<div id="regioninfo">
270
<strong>Valsedelsdistributör:</strong>
271
<a href="../../user/{{ region.user.username }}/">
272
{{ region.user.username }}
275
<i>Det finns ingen ansvarig för den här regionen!</i>
279
<strong>Bokade vallokaler:
280
{{ region.total_booked_stations }} /
281
{{ region.total_stations }}</strong>
284
<div id="region_ballot_info">
288
Tilldelade valsedlar:
293
<div class="help_text">
294
Det här är antalet valsedlar som den här
295
regionen har tilldelats från regionen ovanför.
301
Tillgängliga valsedlar:
304
<input type="text" id="ballots_available" name="ballots_available"
305
value="{{ region.ballots_available }}"/>
307
<div class="help_text">
308
Här kan du ändra antalet valsedlar som faktiskt är
309
tillgängliga ifall det skiljer sig från det tilldelade
319
<input type="text" id="unit_size" name="unit_size"
320
value="{{ region.ballot_unit_size }}"/>
322
<div class="help_text">
323
Här kan du ändra antalet valsedlar i ett paket.
330
Förtidsröstning (procent):
333
<input type="text" id="early_percentage"
334
value="{{ region.ballot_early_percentage }}"
335
name="early_percentage" />
337
<div class="help_text">
338
Här skriver du in andelen av valsedlarna som ska
339
användas till förtidsröstningslokaler, i procent.
346
<div class="help_text">
348
I textfälten nedan kommer antalet valsedlar som bör
349
distribueras till varje region och/eller vallokal att fyllas i
350
automatiskt när du trycker på
351
<strong>Beräkna</strong>.
352
Om du vill sätta antalet valsedlar för en viss region
353
eller lokal till ett fixt antal, t.ex. för att du redan har gett
354
valsedlar till den ansvariga personen, så kan du skriva in det
355
i dess textfält och kryssa för <strong>Låst</strong>
356
så kommer den att undantas från den automatiska
360
När du är nöjd med fördelningen så ska
361
du trycka på <strong>Spara</strong>, så sparas alla
362
värden i databasen. Om den här regionen har några
363
delregioner så kommer dessutom det beräknade antalet
364
valsedlar för dem att dyka upp i fältet
365
<strong>Tilldelade valsedlar</strong> på deras
366
beräkningssidor.
370
Paketstorleken ovan används i den automatiska beräkningen.
371
Alla stationer eller delregioner kommer att tilldelas minst
372
ett paket, och alla tilldelningar är alltid jämnt
373
delbara med paketstorleken.
379
<div id="subregions" class="calc_result">
380
<div class="calc_result_header">
382
<div>Antal valsedlar</div>
383
<div>Låst</div>
385
{% for subregion in subregions %}
386
<div class="calc_result_entry">
387
<div class="subregion">
388
<a href="../../{{ subregion.shortname }}/calculate/">
389
{{ subregion.name }}</a>
390
[{{ subregion.total_booked_stations }} /
391
{{ subregion.total_stations }}]
392
<div class="voter_info">
393
{{ subregion.total_voters }}
394
röstberättigade
398
<input type="text" id="region_{{ subregion.shortname }}_value"
399
name="region_{{ subregion.shortname }}_value"
400
class="region_value" value="{{ subregion.ballots }}"
401
{% if subregion.ballots_locked %}disabled="disabled"{% endif %}/>
404
<input type="checkbox"
405
id="region_{{ subregion.shortname }}_value_lock"
406
name="region_{{ subregion.shortname }}_value_lock"
407
onchange="checkbox_changed('region_{{ subregion.shortname }}_value'); return false;"
408
{% if subregion.ballots_locked %}
419
<h3>Förtidsröstningslokaler</h3>
420
<div id="locallist" class="calc_result">
421
<div class="calc_result_header">
423
<div>Antal valsedlar</div>
424
<div>Låst</div>
426
{% for local in locals %}
427
<div class="calc_result_entry">
430
<img src="{{MEDIA_URL}}images/green_check.png"
431
alt="Vallokalen är bokad"
432
title="Vallokalen är bokad">
434
<img src="{{MEDIA_URL}}images/red_cross.png"
435
alt="Vallokalen är inte bokad"
436
title="Vallokalen är inte bokad">
438
<a href="../{{ local.pk }}/">
439
{% if station.name %}{{ station.name }}{% else %}<i>Namn saknas</i>{% endif %}</a>
442
<input type="text" id="local_{{ local.pk }}_value"
443
name="local_{{ local.pk }}_value"
444
class="local_value" value="{{ local.ballots }}"
445
{% if local.ballots_locked %}disabled="disabled"{% endif %}/>
448
<input type="checkbox"
449
id="local_{{ local.pk }}_value_lock"
450
name="local_{{ local.pk }}_value_lock"
451
onchange="checkbox_changed('local_{{ local.pk }}_value'); return false;"
452
{% if local.ballots_locked %}
464
<div id="stationlist" class="calc_result">
465
<div class="calc_result_header">
467
<div>Antal valsedlar</div>
468
<div>Låst</div>
470
{% for station in stations %}
471
<div class="calc_result_entry">
474
{% if station.user %}
475
<img src="{{MEDIA_URL}}images/green_check.png"
476
alt="Vallokalen är bokad"
477
title="Vallokalen är bokad">
479
<img src="{{MEDIA_URL}}images/red_cross.png"
480
alt="Vallokalen är inte bokad"
481
title="Vallokalen är inte bokad">
483
<a href="../{{ station.pk }}/">
484
{{ station.name }}</a>
486
<div class="voter_info">
488
röstberättigade
492
<input type="text" id="station_{{ station.pk }}_value"
493
name="station_{{ station.pk }}_value"
494
class="station_value" value="{{ station.ballots }}"
495
{% if station.ballots_locked %}disabled="disabled"{% endif %}/>
498
<input type="checkbox"
499
id="station_{{ station.pk }}_value_lock"
500
name="station_{{ station.pk }}_value_lock"
501
onchange="checkbox_changed('station_{{ station.pk }}_value'); return false;"
502
{% if station.ballots_locked %}
513
<div class="calc_result">
514
<div class="calc_result_entry">
516
<strong>Kvarvarande valsedlar:</strong>
520
id="input_rest_ballots" disabled="disabled" />
526
<input type="button" value="Beräkna" onclick="calculate()" />
529
<input type="submit" name="submit" value="Spara"/>
b'\\ No newline at end of file'