From dfb8d7dc4dc6a8a0f6c8cb691d0f60875d01c782 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tom=C3=A1=C5=A1?= <git@imaniti.org>
Date: Thu, 26 Jan 2023 08:48:22 +0100
Subject: [PATCH] finish vote selecting, improve styles

---
 .../templates/rv_voting_calc/index.html       | 39 ++++++++++--------
 static_src/rv_voting_calc.js                  | 40 ++++++++++++-------
 static_src/shared/utils.js                    |  5 +++
 3 files changed, 53 insertions(+), 31 deletions(-)
 create mode 100644 static_src/shared/utils.js

diff --git a/rv_voting_calc/templates/rv_voting_calc/index.html b/rv_voting_calc/templates/rv_voting_calc/index.html
index a2e3bc9..63a81b0 100644
--- a/rv_voting_calc/templates/rv_voting_calc/index.html
+++ b/rv_voting_calc/templates/rv_voting_calc/index.html
@@ -14,25 +14,30 @@
     <main>
         <h1 class="text-6xl font-bebas mb-5">Kalkulačka hlasování RV</h1>
 
-        <div class="grid grid-cols-2 gap-4">
-            <div>
-                <h2 class="text-2xl font-bebas mb-5">Hlasy členů</h2>
-                <ul class="flex flex-col gap-2">
-                    {% for member in rv_members %}
-                        <li class="flex gap-4 items-center">
-                            <div class="basis-56 flex items-center">
-                                <i class="ico--user text-xl mr-2"></i>
-                                {{ member.displayName }}
-                            </div>
-                            <select class="grow __vote-selection" multiple="multiple"></select>
-                        </li>
-                    {% endfor %}
-                </ul>
+        <div class="grid grid-cols-2 gap-7 mb-5 items-center">
+            <div class="flex items-center gap-3 justify-between">
+                <h2 class="text-2xl font-bebas">Hlasy členů</h2>
+                <button
+                    class="bg-black text-white px-5 py-3 duration-100 hover:bg-gray-800"
+                    id="count-votes"
+                >Vypočítat</button>
             </div>
 
-            <div>
-                <h2 class="text-2xl font-bebas mb-5">Výsledky</h2>
-            </div>
+            <h2 class="text-2xl font-bebas">Výsledky</h2>
+        </div>
+
+        <div class="grid grid-cols-2 gap-7">
+            <ul class="flex flex-col gap-2">
+                {% for member in rv_members %}
+                    <li class="flex gap-4 items-center">
+                        <div class="basis-56 flex items-center">
+                            <i class="ico--user text-xl mr-2"></i>
+                            {{ member.displayName }}
+                        </div>
+                        <select class="grow w-full __vote-selection" multiple="multiple"></select>
+                    </li>
+                {% endfor %}
+            </ul>
         </div>
     </main>
 
diff --git a/static_src/rv_voting_calc.js b/static_src/rv_voting_calc.js
index 8ba4c3b..4f8b9b6 100644
--- a/static_src/rv_voting_calc.js
+++ b/static_src/rv_voting_calc.js
@@ -21,6 +21,16 @@ $(window).ready(
             }
         });
 
+        $(".__vote-selection").on(
+            "select2:selecting",
+            event => {
+                // Prevent empty tags.
+                if (event.params.args.data.id == "") {
+                    event.preventDefault();
+                }
+            }
+        );
+
         $(".__vote-selection").on(
             "select2:select",
             event => {
@@ -31,7 +41,7 @@ $(window).ready(
                     return;
                 }
 
-                const tagName = event.params.data.text;
+                const tagName = event.params.data.id;
 
                 const addedTag = new Option(
                     tagName,
@@ -46,7 +56,11 @@ $(window).ready(
 
                 // Check if they contain the tag. If they do, ignore them.
                 for (const selection of unfilteredSelections) {
-                    if ($(selection).children(`option[value=${tagName}]`).length === 0) {
+                    if (
+                        $(selection).
+                        children(`option[value=${$.escapeSelector(tagName)}]`).
+                        length === 0
+                    ) {
                         filteredSelections.push(selection);
                     }
                 }
@@ -61,7 +75,7 @@ $(window).ready(
             event => {
                 //// Remove the tag option if it's not selected anywhere.
 
-                const tagName = event.params.data.text;
+                const tagName = event.params.data.id;
 
                 // Get all other selections.
                 const selections = $(".__vote-selection");
@@ -69,16 +83,9 @@ $(window).ready(
                 // Check if any of them have the tag selected. If they do, end the function.
                 for (const selection of selections) {
                     for (const data of $(selection).select2("data")) {
-                        if (data.selected && data.id == tagName) {
-                            // Workaround - add the option back to this select (TODO - improve)
-                            $(event.target).append(
-                                new Option(
-                                    tagName,
-                                    tagName,
-                                    false,
-                                    false
-                                )
-                            ).trigger("change");
+                        if (data.id == tagName) {
+                            // TODO - Don't remove the tag from this select.
+                            // I'm not sure select2 has a good way of doing this.
 
                             return;
                         }
@@ -87,7 +94,12 @@ $(window).ready(
 
                 // If the function has not ended by now, we can remove the tag.
                 for (const selection of selections) {
-                    $(selection).children(`option[value=${tagName}]`).remove();
+                    (
+                        $(selection).
+                        children(`option[value=${$.escapeSelector(tagName)}]`).
+                        remove()
+                    );
+
                     $(selection).trigger("change");
                 }
             }
diff --git a/static_src/shared/utils.js b/static_src/shared/utils.js
new file mode 100644
index 0000000..7a64d68
--- /dev/null
+++ b/static_src/shared/utils.js
@@ -0,0 +1,5 @@
+const escapeHTML = (source) => {
+    return new Option(source).innerHTML;
+}
+
+export { escapeHTML };
-- 
GitLab