Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature: Add vote choice filter to poll overview #167

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions bitpoll/base/static/js/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ $(document).ready(function() {
$(".script-only").css("display", "block");
$("a.script-only").css("display", "inline-block");
$("button.script-only").css("display", "inline-block");
$("span.script-only").css("display", "inline");
$("td.script-only").css("display", "table-cell");
$("tr.script-only").css("display", "table-row");
$("table.script-only").css("display", "table");
Expand Down
107 changes: 107 additions & 0 deletions bitpoll/base/static/js/poll_filter.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
var scores;

$(function() {
// Collect scores for all vote choices
scores = []
$("#scores .choice-sum").each(function () {
// "n/a" should be treated like 0%
scores.push(parseFloat($(this).data("score")) || 0.0);
});

// Event handler
$("#filter-threshold-percent").on("input", filterUpdatePercent);
$("#filter-threshold-count").on("input", filterUpdateCount);
$("#filter-apply").on("click", filterUpdatePercent);
$("#filter-reset").on("click", filterReset);

// Fill form inputs with total count
filterReset();
});

function filterColumns(keepCount) {
var threshold = $("#filter-threshold-percent").val() || 0.0;

// Identify filtered columns
var count = 0;
var filteredColumns = [true]; // Always show first column (vote author)
scores.forEach(function (score) {
if (score >= threshold) {
filteredColumns.push(true);
count++;
} else {
filteredColumns.push(false);
}
});
filteredColumns.push(true); // Always show last column (edit, impersonate)

if (!keepCount) {
$("#filter-threshold-count").val(count);
}

filterSetVisibleColumns(filteredColumns);

return count != scores.length;
}

function filterCountToPercent(count) {
if (count <= 0) return 100;
if (scores.length <= count) return 0;
var sorted = scores.slice();
sorted.sort((a, b) => a - b);
return sorted[sorted.length - count];
}

function filterReset() {
// count will be automatically set by filterUpdate
$("#filter-threshold-percent").val(0);
filterUpdate();
}

function filterSetVisibleColumns(columns) {
// Remove old filtering
$("[data-original-colspan]").each(function () {
$(this).attr("colspan", $(this).attr("data-original-colspan"));
});
$(".filtered").removeClass("filtered");

// Set new filtering
$("#poll tr").each(function () {
var columnIdx = 0;
$(this).find("td, th").each(function () {
var colspan = parseInt($(this).attr("data-original-colspan") ?? $(this).attr("colspan") ?? "1");

var visible = columns.slice(columnIdx, columnIdx + colspan).filter(x => x).length;
if (visible > 0) {
$(this).attr("data-original-colspan", $(this).attr("colspan"));
$(this).attr("colspan", visible);
} else {
$(this).addClass("filtered");
}

columnIdx += colspan;
});
});
}

function filterUpdate(keepCount) {
var isFiltered = filterColumns(keepCount)

if (isFiltered) {
$("#filterLink").addClass("hidden");
$("#filterLinkWarning").removeClass("hidden");
} else {
$("#filterLink").removeClass("hidden");
$("#filterLinkWarning").addClass("hidden");
}
}

function filterUpdateCount() {
var count = parseInt($("#filter-threshold-count").val());
var threshold = filterCountToPercent(count);
$("#filter-threshold-percent").val(threshold);
filterUpdate(true);
}

function filterUpdatePercent() {
filterUpdate(false);
}
2 changes: 1 addition & 1 deletion bitpoll/base/static/scss/main.scss
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ html, body, h1, h2, h3, h4, h5, h6, .h1, .h2, .h3, .h4, .h5, .h6, input, textare

html,
body {
margin:0;
margin:0 !important;
padding:0;
height:100%;
}
Expand Down
69 changes: 67 additions & 2 deletions bitpoll/poll/templates/poll/poll.html
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
{% extends "base.html" %}
{% load pipeline %}
{% load i18n %}
{% load poll_filter vote_permissions comment_permissions poll_permissions %}
{% load tz %}
Expand Down Expand Up @@ -149,7 +150,7 @@
{% if summary %}
<tr id="scores">
<th>
<span class="print-only"><b>{% trans 'Scores' %}<br/></b></span>
<span class="print-only"><b>{% trans 'Percentage' %}<br/></b></span>
</th>
{# {% set scores, counts, totals, max_score = poll.get_stats() %}#}
{% for choice in stats %}
Expand Down Expand Up @@ -211,10 +212,70 @@
{# TODO: Add legend for choice values #}
</div>

<div class="pull-right">
<div class="pull-right noprint">
<span class="script-only" id="filterLink">
<a class="" href="#" data-toggle="modal" data-target="#filterModal">{% trans 'Filter' %}</a>
&middot;
</span>
{# Highlight link if poll results are filtered #}
<span class="script-only hidden" id="filterLinkWarning">
<a class="text-warning" href="#" data-toggle="modal" data-target="#filterModal">
<i class="fa fa-filter"></i>
<strong>{% trans 'Filter' %}</strong>
</a>
&middot;
</span>
<a href="{% url 'poll_export_csv' poll.url %}">{% trans 'Export as CSV' %}</a>
</div>

<div class="modal fade noprint" id="filterModal" tabindex="-1" role="dialog" aria-labelledby="filterModalLabel">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">&times;</span>
</button>
<h4 class="modal-title" id="filterModalLabel">{% trans 'Filter' %}</h4>
</div>
<form>
<div class="modal-body">
<div class="form-group">
<div class="row">
<div class="col-sm-5">
<label for="recipient-name" class="control-label">{% trans 'Minimum percentage' %}</label>
<div class="input-group">
<input type="number" min="0" max="100" class="form-control" id="filter-threshold-percent">
<span class="input-group-addon">%</span>
</div>
</div>
<div class="col-sm-2 text-center">
<label>&nbsp;</label>
<div class="or">
<i class="fa fa-exchange"></i>
</div>
</div>
<div class="col-sm-5">
<label for="message-text" class="control-label">{% trans 'Maximum count' %}</label>
<input type="number" min="0" max="{{ matrix|first|length }}" class="form-control" id="filter-threshold-count"></textarea>
</div>
</div>
</div>
</div>
<div class="modal-footer">
<button type="button" class="action secondary pull-left" data-dismiss="modal" id="filter-reset">
<i class="fa fa-undo"></i>
{% trans 'Reset' %}
</button>
<button type="button" class="action primary" data-dismiss="modal" id="filter-apply">
<i class="fa fa-check"></i>
{% trans 'Done' %}
</button>
</div>
</form>
</div>
</div>
</div>

<br/><br/>{% if comments %}<h1 class="print-only">{% trans 'Comments' %}</h1>{% endif %}
<div class="comments">
{% for comment in comments %}
Expand Down Expand Up @@ -254,3 +315,7 @@ <h3>{% trans 'Post a comment' %}</h3>
</div>
</div>
{% endblock %}

{% block additionalJS %}
{% javascript 'poll_view' %}
{% endblock %}
6 changes: 6 additions & 0 deletions bitpoll/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,12 @@
),
'output_filename': 'js/poll_edit.js',
},
'poll_view': {
'source_filenames': (
'js/poll_filter.js',
),
'output_filename': 'js/poll_view.js',
},
'base_late': {
'source_filenames': (
#'js/lib/jquery-range.min.js', # TODO: is this needet for the numeric polls?
Expand Down
36 changes: 29 additions & 7 deletions locale/de_DE/LC_MESSAGES/django.po
Original file line number Diff line number Diff line change
Expand Up @@ -1491,23 +1491,45 @@ msgstr "Weise einen User zu"
msgid "Vote"
msgstr "Abstimmen"

#: bitpoll/poll/templates/poll/poll.html:153
msgid "Scores"
msgstr "Auswertungen"
#: bitpoll/poll/templates/poll/poll.html:154
msgid "Percentage"
msgstr "Prozentsatz"

#: bitpoll/poll/templates/poll/poll.html:171
#: bitpoll/poll/templates/poll/poll.html:186
#: bitpoll/poll/templates/poll/poll.html:172
#: bitpoll/poll/templates/poll/poll.html:187
msgid "Score"
msgstr "Auswertung"
msgstr "Punktzahl"

#: bitpoll/poll/templates/poll/poll.html:193
msgid "Details"
msgstr "Details"

#: bitpoll/poll/templates/poll/poll.html:218
#: bitpoll/poll/templates/poll/poll.html:225
#: bitpoll/poll/templates/poll/poll.html:239
msgid "Filter"
msgstr "Filter"

#: bitpoll/poll/templates/poll/poll.html:216
msgid "Export as CSV"
msgstr "Als CSV exportieren"

#: bitpoll/poll/templates/poll/poll.html:246
msgid "Minimum percentage"
msgstr "Minimaler Prozentsatz"

#: bitpoll/poll/templates/poll/poll.html:259
msgid "Maximum count"
msgstr "Maximale Anzahl"

#: bitpoll/poll/templates/poll/poll.html:268
msgid "Reset"
msgstr "Reset"

#: bitpoll/poll/templates/poll/poll.html:272
msgid "Done"
msgstr "Fertig"

#: bitpoll/poll/templates/poll/poll.html:219
msgid "Comments"
msgstr "Kommentare"
Expand Down Expand Up @@ -1670,7 +1692,7 @@ msgstr "Teilnehmerliste verbergen"

#: bitpoll/poll/templates/poll/settings.html:137
msgid "Show score instead of percentage"
msgstr "Zeige Score statt Prozentsatz"
msgstr "Zeige Punktzahl statt Prozentsatz"

#: bitpoll/poll/templates/poll/settings.html:146
msgid ""
Expand Down
32 changes: 27 additions & 5 deletions locale/en_US/LC_MESSAGES/django.po
Original file line number Diff line number Diff line change
Expand Up @@ -1415,23 +1415,45 @@ msgstr ""
msgid "Vote"
msgstr "Vote"

#: bitpoll/poll/templates/poll/poll.html:153
msgid "Scores"
msgstr "Scores"
#: bitpoll/poll/templates/poll/poll.html:154
msgid "Percentage"
msgstr "Percentage"

#: bitpoll/poll/templates/poll/poll.html:171
#: bitpoll/poll/templates/poll/poll.html:186
#: bitpoll/poll/templates/poll/poll.html:172
#: bitpoll/poll/templates/poll/poll.html:187
msgid "Score"
msgstr "Score"

#: bitpoll/poll/templates/poll/poll.html:193
msgid "Details"
msgstr ""

#: bitpoll/poll/templates/poll/poll.html:218
#: bitpoll/poll/templates/poll/poll.html:225
#: bitpoll/poll/templates/poll/poll.html:239
msgid "Filter"
msgstr "Filter"

#: bitpoll/poll/templates/poll/poll.html:216
msgid "Export as CSV"
msgstr ""

#: bitpoll/poll/templates/poll/poll.html:246
msgid "Minimum percentage"
msgstr "Minimum percentage"

#: bitpoll/poll/templates/poll/poll.html:259
msgid "Maximum count"
msgstr "Maximum count"

#: bitpoll/poll/templates/poll/poll.html:268
msgid "Reset"
msgstr "Reset"

#: bitpoll/poll/templates/poll/poll.html:272
msgid "Done"
msgstr "Done"

#: bitpoll/poll/templates/poll/poll.html:219
msgid "Comments"
msgstr "Comments"
Expand Down
32 changes: 27 additions & 5 deletions locale/it_IT/LC_MESSAGES/django.po
Original file line number Diff line number Diff line change
Expand Up @@ -1500,23 +1500,45 @@ msgstr "Assegna utente"
msgid "Vote"
msgstr "Vota"

#: bitpoll/poll/templates/poll/poll.html:153
msgid "Scores"
msgstr "Punteggi"
#: bitpoll/poll/templates/poll/poll.html:154
msgid "Percentage"
msgstr ""

#: bitpoll/poll/templates/poll/poll.html:171
#: bitpoll/poll/templates/poll/poll.html:186
#: bitpoll/poll/templates/poll/poll.html:172
#: bitpoll/poll/templates/poll/poll.html:187
msgid "Score"
msgstr "Punteggio"

#: bitpoll/poll/templates/poll/poll.html:193
msgid "Details"
msgstr "Dettagli"

#: bitpoll/poll/templates/poll/poll.html:218
#: bitpoll/poll/templates/poll/poll.html:225
#: bitpoll/poll/templates/poll/poll.html:239
msgid "Filter"
msgstr ""

#: bitpoll/poll/templates/poll/poll.html:216
msgid "Export as CSV"
msgstr "Esporta come CSV"

#: bitpoll/poll/templates/poll/poll.html:246
msgid "Minimum percentage"
msgstr ""

#: bitpoll/poll/templates/poll/poll.html:259
msgid "Maximum count"
msgstr ""

#: bitpoll/poll/templates/poll/poll.html:268
msgid "Reset"
msgstr ""

#: bitpoll/poll/templates/poll/poll.html:272
msgid "Done"
msgstr ""

#: bitpoll/poll/templates/poll/poll.html:219
msgid "Comments"
msgstr "Commenti"
Expand Down