From d3ccd2ed71d638cb1b96448cc6f83c2873b1f72c Mon Sep 17 00:00:00 2001
From: Robert Goldmann <deadlocker@gmx.de>
Date: Sun, 20 Jan 2019 17:05:00 +0100
Subject: [PATCH] Fixed #391 - improve global datepicker

---
 src/main/resources/languages/_de.properties   |  3 +-
 src/main/resources/languages/_en.properties   |  3 +-
 .../static/css/dark/globalDatepicker.css      | 28 +++++++++
 .../resources/static/css/globalDatepicker.css | 28 +++++++++
 src/main/resources/static/js/datePicker.js    |  8 ---
 .../resources/static/js/globalDatePicker.js   | 60 +++++++++++++++++++
 .../templates/helpers/datePicker.ftl          | 57 +++++++++++++-----
 .../resources/templates/reports/reports.ftl   |  3 +-
 .../templates/transactions/transactions.ftl   |  3 +-
 9 files changed, 166 insertions(+), 27 deletions(-)
 create mode 100644 src/main/resources/static/css/dark/globalDatepicker.css
 create mode 100644 src/main/resources/static/css/globalDatepicker.css
 delete mode 100644 src/main/resources/static/js/datePicker.js
 create mode 100644 src/main/resources/static/js/globalDatePicker.js

diff --git a/src/main/resources/languages/_de.properties b/src/main/resources/languages/_de.properties
index dbcac04ec..48ef1dfe6 100644
--- a/src/main/resources/languages/_de.properties
+++ b/src/main/resources/languages/_de.properties
@@ -32,7 +32,8 @@ title.category.new=Neue Kategorie
 title.category.edit=Kategorie bearbeiten
 title.transaction.edit=Buchung bearbeiten
 title.transaction.new=Neue Buchung
-title.datepicker=Datum w�hlen
+title.datepicker.year=Jahr w�hlen
+title.datepicker.month=Monat w�hlen
 title.account.new=Neues Konto
 title.account.edit=Konto bearbeiten
 title.category.budgets=Verbrauch nach Kategorien
diff --git a/src/main/resources/languages/_en.properties b/src/main/resources/languages/_en.properties
index 495a1f7f9..43abb2edd 100644
--- a/src/main/resources/languages/_en.properties
+++ b/src/main/resources/languages/_en.properties
@@ -32,7 +32,8 @@ title.category.new=New Category
 title.category.edit=Edit Category
 title.transaction.edit=Edit Transaction
 title.transaction.new=New Transaction
-title.datepicker=Choose date
+title.datepicker.year=Choose year
+title.datepicker.month=Choose month
 title.account.new=New Account
 title.account.edit=Edit Account
 title.category.budgets=Consumption by categories
diff --git a/src/main/resources/static/css/dark/globalDatepicker.css b/src/main/resources/static/css/dark/globalDatepicker.css
new file mode 100644
index 000000000..3fee6d76d
--- /dev/null
+++ b/src/main/resources/static/css/dark/globalDatepicker.css
@@ -0,0 +1,28 @@
+.global-datepicker-table {
+    font-weight: bold;
+    border-collapse: separate;
+}
+
+.global-datepicker-table td {
+    text-align: center;
+    padding-top: 1.5rem;
+    padding-bottom: 1.5rem;
+    border: 2px solid rgba(0, 0, 0, 0);
+}
+
+.global-datepicker-table td:hover {
+    cursor: pointer;
+    border: 2px solid rgba(255, 255, 255, 0.5);
+}
+
+.global-datepicker-selected {
+    background-color: rgba(255, 255, 255, 0.125);
+}
+
+.global-datepicker-button {
+    -webkit-transform: rotate(90deg);
+    -moz-transform: rotate(90deg);
+    -ms-transform: rotate(90deg);
+    -o-transform: rotate(90deg);
+    transform: rotate(90deg);
+}
\ No newline at end of file
diff --git a/src/main/resources/static/css/globalDatepicker.css b/src/main/resources/static/css/globalDatepicker.css
new file mode 100644
index 000000000..b8ebf5278
--- /dev/null
+++ b/src/main/resources/static/css/globalDatepicker.css
@@ -0,0 +1,28 @@
+.global-datepicker-table {
+    font-weight: bold;
+    border-collapse: separate;
+}
+
+.global-datepicker-table td {
+    text-align: center;
+    padding-top: 1.5rem;
+    padding-bottom: 1.5rem;
+    border: 2px solid rgba(0, 0, 0, 0);
+}
+
+.global-datepicker-table td:hover {
+    cursor: pointer;
+    border: 2px solid rgba(0, 0, 0, 0.25);
+}
+
+.global-datepicker-selected {
+    background-color: rgba(0, 0, 0, 0.08);
+}
+
+.global-datepicker-button {
+    -webkit-transform: rotate(90deg);
+    -moz-transform: rotate(90deg);
+    -ms-transform: rotate(90deg);
+    -o-transform: rotate(90deg);
+    transform: rotate(90deg);
+}
\ No newline at end of file
diff --git a/src/main/resources/static/js/datePicker.js b/src/main/resources/static/js/datePicker.js
deleted file mode 100644
index ff6341411..000000000
--- a/src/main/resources/static/js/datePicker.js
+++ /dev/null
@@ -1,8 +0,0 @@
-$(document).ready(function () {
-    $("#buttonChooseDate").click(function () {
-        var month = $("#selectMonth").val();
-        var year = $("#selectYear").val();
-        var dateString = "01." + month + "." + year;
-        document.cookie = "currentDate=" + dateString;
-    });
-});
\ No newline at end of file
diff --git a/src/main/resources/static/js/globalDatePicker.js b/src/main/resources/static/js/globalDatePicker.js
new file mode 100644
index 000000000..636083b4b
--- /dev/null
+++ b/src/main/resources/static/js/globalDatePicker.js
@@ -0,0 +1,60 @@
+$(document).ready(function () {
+    M.Modal.init(document.getElementById("modalDate"), {
+        onOpenStart: function f() {
+            cleanup();
+        }
+    });
+
+    $("#global-datepicker-previous").click(function () {
+        updateYearGrid(-11, document.getElementById('currentYear').innerHTML);
+    });
+
+    $("#global-datepicker-next").click(function () {
+        updateYearGrid(11, document.getElementById('currentYear').innerHTML);
+    });
+
+    $("#global-datepicker-select-year .global-datepicker-item").click(function () {
+        selectYear(this.innerText);
+    });
+
+    $("#global-datepicker-select-month .global-datepicker-item").click(function () {
+        selectMonth($("#global-datepicker-select-month .global-datepicker-item").index(this) + 1);
+    });
+});
+
+var year;
+
+
+function cleanup() {
+    year = undefined;
+    $("#global-datepicker-select-year").show();
+    $("#global-datepicker-select-month").hide();
+}
+
+function updateYearGrid(modifier, currentYear) {
+    var items = $("#global-datepicker-select-year .global-datepicker-item");
+    var firstYear = parseInt(items[0].innerText);
+    var newFirstYear = firstYear + modifier;
+
+    for (var i = 0; i < items.length; i++) {
+        items[i].innerText = newFirstYear + i;
+        if (items[i].innerText === currentYear) {
+            items[i].classList.add("global-datepicker-selected");
+        }
+        else {
+            items[i].classList.remove("global-datepicker-selected");
+        }
+    }
+}
+
+function selectYear(selectedYear) {
+    year = selectedYear;
+    $("#global-datepicker-select-year").hide();
+    $("#global-datepicker-select-month").show();
+}
+
+function selectMonth(selectedMonth) {
+    var dateString = "01." + selectedMonth + "." + year;
+    document.cookie = "currentDate=" + dateString;
+    document.getElementById('buttonChooseDate').click();
+}
\ No newline at end of file
diff --git a/src/main/resources/templates/helpers/datePicker.ftl b/src/main/resources/templates/helpers/datePicker.ftl
index ac588cc51..d60a4b6d4 100644
--- a/src/main/resources/templates/helpers/datePicker.ftl
+++ b/src/main/resources/templates/helpers/datePicker.ftl
@@ -11,22 +11,17 @@
     <!-- modal to select specific month and year -->
     <div id="modalDate" class="modal modal-fixed-footer">
         <div class="modal-content background-color">
-            <h4>${locale.getString("title.datepicker")}</h4>
-            <div class="input-field col s12">
-                <select id="selectMonth">
-                    <#list helpers.getMonthList() as monthName>
-                        <option <#if currentDate.getMonthOfYear() == monthName?index + 1>selected</#if> value="${monthName?index + 1}">${monthName}</option>
-                    </#list>
-                </select>
-                <label for="selectMonth">${locale.getString("datepicker.label.month")}</label>
+
+            <#assign currentYear = currentDate.getYear()/>
+            <div id="global-datepicker-select-year">
+                <@datepickerGridYear currentYear-7 currentYear/>
             </div>
-            <div class="input-field col s12">
-                <select id="selectYear">
-                    <#list helpers.getYearList() as year>
-                        <option <#if currentDate.getYear() == year>selected</#if> value="${year?c}">${year?c}</option>
-                    </#list>
-                </select>
-                <label for="selectYear">${locale.getString("datepicker.label.year")}</label>
+
+            <div id="global-datepicker-select-month">
+                <h4>${locale.getString("title.datepicker.month")}</h4>
+                <#assign montList = helpers.getMonthList()/>
+                <#assign currentMonth = montList[currentDate.getMonthOfYear() - 1]/>
+                <@datepickerGrid montList currentMonth/>
             </div>
         </div>
         <div class="modal-footer background-color">
@@ -36,6 +31,38 @@
     </div>
 </#macro>
 
+<#macro datepickerGridYear startYear currentYear>
+    <h4>${locale.getString("title.datepicker.year")}</h4>
+
+    <div class="hidden" id="currentYear">${currentYear?c}</div>
+
+    <div class="center-align">
+        <a class="waves-effect text-color global-datepicker-button" id="global-datepicker-previous"><i class="material-icons icon-chevron">chevron_left</i></a>
+        <a class="waves-effect text-color global-datepicker-button" id="global-datepicker-next"><i class="material-icons icon-chevron">chevron_right</i></a>
+    </div>
+
+    <#assign years = [] />
+    <#list startYear..startYear + 11 as i>
+        <#assign years = years + [i?c] />
+    </#list>
+    <@datepickerGrid years currentYear?c/>
+</#macro>
+
+<#macro datepickerGrid items currentItem>
+<table class="no-border-table global-datepicker-table">
+    <#list items as item>
+        <#if item?index == 0 || item?index == 3 || item?index == 6 || item?index == 9>
+            <tr>
+        </#if>
+        <td class="global-datepicker-item <#if item == currentItem>global-datepicker-selected</#if>">${item}</td>
+        <#if item?index == 2 || item?index == 5 || item?index == 8 || item?index == 11>
+            </tr>
+        </#if>
+    </#list>
+</table>
+
+</#macro>
+
 <#macro datePickerLocalization>
     <#-- localization for scripts -->
     <script>
diff --git a/src/main/resources/templates/reports/reports.ftl b/src/main/resources/templates/reports/reports.ftl
index 771028bc1..61c28c980 100644
--- a/src/main/resources/templates/reports/reports.ftl
+++ b/src/main/resources/templates/reports/reports.ftl
@@ -3,6 +3,7 @@
         <#import "../helpers/header.ftl" as header>
         <@header.header "BudgetMaster"/>
         <@header.style "reports"/>
+        <@header.style "globalDatepicker"/>
         <#import "/spring.ftl" as s>
     </head>
     <body class="budgetmaster-blue-light">
@@ -100,7 +101,7 @@
         <@scripts.scripts/>
         <script src="<@s.url '/sortable-1.8.1/Sortable.min.js'/>"></script>
         <script src="<@s.url '/js/reports.js'/>"></script>
-        <script src="<@s.url '/js/datePicker.js'/>"></script>
+        <script src="<@s.url '/js/globalDatePicker.js'/>"></script>
         <script>document.cookie = "currentDate=${helpers.getDateString(currentDate)}";</script>
     </body>
 </html>
\ No newline at end of file
diff --git a/src/main/resources/templates/transactions/transactions.ftl b/src/main/resources/templates/transactions/transactions.ftl
index e0d814ade..828adaa66 100644
--- a/src/main/resources/templates/transactions/transactions.ftl
+++ b/src/main/resources/templates/transactions/transactions.ftl
@@ -3,6 +3,7 @@
         <#import "../helpers/header.ftl" as header>
         <@header.header "BudgetMaster"/>
         <@header.style "categories"/>
+        <@header.style "globalDatepicker"/>
         <#import "/spring.ftl" as s>
     </head>
     <body class="budgetmaster-blue-light">
@@ -114,7 +115,7 @@
         <#import "../helpers/scripts.ftl" as scripts>
         <@scripts.scripts/>
         <script src="<@s.url '/js/transactions.js'/>"></script>
-        <script src="<@s.url '/js/datePicker.js'/>"></script>
+        <script src="<@s.url '/js/globalDatePicker.js'/>"></script>
         <script>document.cookie = "currentDate=${helpers.getDateString(currentDate)}";</script>
     </body>
 </html>
\ No newline at end of file
-- 
GitLab