-
diff --git a/groups/Tapops/js/main.js b/groups/Tapops/js/main.js
index 949cab2..1633c26 100644
--- a/groups/Tapops/js/main.js
+++ b/groups/Tapops/js/main.js
@@ -423,14 +423,23 @@ class DocumentRepository {
this.filterWrapper = document.getElementById('tag-filter-wrapper');
this.mobileFilterWrapper = document.getElementById('mobile-tag-filter-wrapper');
this.searchInput = document.getElementById('doc-search');
- this.dateStartInput = document.getElementById('date-start');
- this.dateEndInput = document.getElementById('date-end');
this.sortFilterWrapper = document.getElementById('sort-filter-wrapper');
// Hero stat values (filled from real API data after fetch).
this.statActiveEl = document.getElementById('stat-active-value');
this.statUpdatesEl = document.getElementById('stat-updates-value');
+ this.dateStartParts = {
+ dd: document.getElementById('date-start-dd'),
+ mm: document.getElementById('date-start-mm'),
+ yyyy: document.getElementById('date-start-yyyy'),
+ };
+ this.dateEndParts = {
+ dd: document.getElementById('date-end-dd'),
+ mm: document.getElementById('date-end-mm'),
+ yyyy: document.getElementById('date-end-yyyy'),
+ };
+
this.cards = [];
this.paginationContainer = null;
this.state = {
@@ -443,6 +452,52 @@ class DocumentRepository {
};
}
+ // Returns YYYY-MM-DD string only when dd, mm, and yyyy are all filled and valid.
+ _getDateString(parts) {
+ const dd = parts.dd?.value.trim() || '';
+ const mm = parts.mm?.value.trim() || '';
+ const yyyy = parts.yyyy?.value.trim() || '';
+
+ if (!dd || !mm || yyyy.length < 4) return '';
+
+ const d = parseInt(dd, 10);
+ const m = parseInt(mm, 10);
+ const y = parseInt(yyyy, 10);
+
+ if (isNaN(d) || isNaN(m) || isNaN(y)) return '';
+ if (d < 1 || d > 31 || m < 1 || m > 12 || y < 1 || y > 9999) return '';
+
+ return `${String(y).padStart(4, '0')}-${String(m).padStart(2, '0')}-${String(d).padStart(2, '0')}`;
+ }
+
+ // Wire up a set of dd/mm/yyyy text inputs:
+ // • numeric-only keydown guard
+ // • auto-advance dd→mm after 2 chars, mm→yyyy after 2 chars
+ // • backspace from empty field navigates back
+ // • calls onUpdate() on every change
+ _bindDateParts(parts, onUpdate) {
+ const { dd, mm, yyyy } = parts;
+ const CTRL_KEYS = new Set(['Backspace', 'Delete', 'Tab', 'ArrowLeft', 'ArrowRight', 'Home', 'End', 'Enter']);
+
+ const setup = (input, prev, next) => {
+ if (!input) return;
+ input.addEventListener('keydown', (e) => {
+ if (!/^\d$/.test(e.key) && !CTRL_KEYS.has(e.key)) e.preventDefault();
+ if (e.key === 'Backspace' && !input.value && prev) prev.focus();
+ });
+ input.addEventListener('input', () => {
+ input.value = input.value.replace(/\D/g, '');
+ onUpdate();
+ const max = parseInt(input.getAttribute('maxlength'), 10);
+ if (next && input.value.length >= max) next.focus();
+ });
+ };
+
+ setup(dd, null, mm);
+ setup(mm, dd, yyyy);
+ setup(yyyy, mm, null);
+ }
+
async init() {
if (!this.gridContainer) return;
this._bindControls();
@@ -581,40 +636,20 @@ class DocumentRepository {
}
_bindControls() {
- // Limit date inputs to a 4-digit year (max 9999).
- [this.dateStartInput, this.dateEndInput].forEach(input => {
- if (!input) return;
- input.setAttribute('max', '9999-12-31');
- input.setAttribute('min', '1000-01-01');
- // Clamp year on both input (fires while typing) and change (fires on blur).
- const clampYear = () => {
- if (!input.value) return;
- const parts = input.value.split('-');
- if (parts.length !== 3) return;
- const year = parseInt(parts[0], 10);
- if (!Number.isNaN(year) && year > 9999) {
- parts[0] = '9999';
- input.value = parts.join('-');
- }
- };
- input.addEventListener('input', clampYear);
- input.addEventListener('change', clampYear);
- });
-
this.searchInput?.addEventListener('input', (e) => {
this.state.search = e.target.value.toLowerCase().trim();
this.state.page = 1;
this._applyFilters();
});
- this.dateStartInput?.addEventListener('change', (e) => {
- this.state.startDate = e.target.value;
+ this._bindDateParts(this.dateStartParts, () => {
+ this.state.startDate = this._getDateString(this.dateStartParts);
this.state.page = 1;
this._applyFilters();
});
- this.dateEndInput?.addEventListener('change', (e) => {
- this.state.endDate = e.target.value;
+ this._bindDateParts(this.dateEndParts, () => {
+ this.state.endDate = this._getDateString(this.dateEndParts);
this.state.page = 1;
this._applyFilters();
});