fix(tapops): perlebar field tanggal dan tambah kembali tombol kalender dengan picker tersembunyi

This commit is contained in:
Dodo
2026-06-04 17:09:33 +07:00
parent 9c1de91a82
commit 46d9b1677d
3 changed files with 70 additions and 11 deletions
+35 -4
View File
@@ -365,6 +365,7 @@
/* Custom dd/mm/yyyy date input */ /* Custom dd/mm/yyyy date input */
.custom-date-input { .custom-date-input {
position: relative;
display: flex; display: flex;
align-items: center; align-items: center;
gap: 1px; gap: 1px;
@@ -376,7 +377,8 @@
font-weight: 700; font-weight: 700;
color: #94a3b8; color: #94a3b8;
user-select: none; user-select: none;
padding: 0 1px; padding: 0 2px;
flex-shrink: 0;
} }
.date-part { .date-part {
@@ -387,14 +389,14 @@
font-weight: 700; font-weight: 700;
color: var(--primary-blue); color: var(--primary-blue);
text-align: center; text-align: center;
padding: 2px 3px; padding: 2px 4px;
border-radius: 3px; border-radius: 3px;
transition: background 0.15s ease; transition: background 0.15s ease;
min-width: 0; min-width: 0;
} }
.date-dd, .date-mm { width: 2.2ch; } .date-dd, .date-mm { width: 34px; }
.date-yyyy { width: 4.2ch; } .date-yyyy { width: 56px; }
.date-part::placeholder { .date-part::placeholder {
color: #94a3b8; color: #94a3b8;
@@ -406,6 +408,35 @@
background: rgba(0, 49, 80, 0.07); background: rgba(0, 49, 80, 0.07);
} }
.date-calendar-btn {
background: none;
border: none;
cursor: pointer;
color: #94a3b8;
padding: 4px 2px 4px 6px;
display: flex;
align-items: center;
font-size: 0.9rem;
flex-shrink: 0;
transition: color 0.2s ease;
}
.date-calendar-btn:hover {
color: var(--primary-blue);
}
.date-hidden-picker {
position: absolute;
opacity: 0;
pointer-events: none;
width: 1px;
height: 1px;
border: none;
padding: 0;
margin: 0;
overflow: hidden;
}
.range-divider { .range-divider {
font-size: 0.7rem; font-size: 0.7rem;
font-weight: 800; font-weight: 800;
+8
View File
@@ -952,6 +952,10 @@
<input type="text" inputmode="numeric" maxlength="2" placeholder="MM" class="date-part date-mm" id="date-start-mm" autocomplete="off"> <input type="text" inputmode="numeric" maxlength="2" placeholder="MM" class="date-part date-mm" id="date-start-mm" autocomplete="off">
<span class="date-sep">/</span> <span class="date-sep">/</span>
<input type="text" inputmode="numeric" maxlength="4" placeholder="YYYY" class="date-part date-yyyy" id="date-start-yyyy" autocomplete="off"> <input type="text" inputmode="numeric" maxlength="4" placeholder="YYYY" class="date-part date-yyyy" id="date-start-yyyy" autocomplete="off">
<button type="button" class="date-calendar-btn" id="date-start-cal-btn" aria-label="Pilih tanggal mulai">
<i class="far fa-calendar-alt"></i>
</button>
<input type="date" class="date-hidden-picker" id="date-start-picker" tabindex="-1" aria-hidden="true">
</div> </div>
<span class="range-divider" data-tp-i18n="range_divider">s/d</span> <span class="range-divider" data-tp-i18n="range_divider">s/d</span>
<div class="input-wrapper custom-date-input"> <div class="input-wrapper custom-date-input">
@@ -960,6 +964,10 @@
<input type="text" inputmode="numeric" maxlength="2" placeholder="MM" class="date-part date-mm" id="date-end-mm" autocomplete="off"> <input type="text" inputmode="numeric" maxlength="2" placeholder="MM" class="date-part date-mm" id="date-end-mm" autocomplete="off">
<span class="date-sep">/</span> <span class="date-sep">/</span>
<input type="text" inputmode="numeric" maxlength="4" placeholder="YYYY" class="date-part date-yyyy" id="date-end-yyyy" autocomplete="off"> <input type="text" inputmode="numeric" maxlength="4" placeholder="YYYY" class="date-part date-yyyy" id="date-end-yyyy" autocomplete="off">
<button type="button" class="date-calendar-btn" id="date-end-cal-btn" aria-label="Pilih tanggal selesai">
<i class="far fa-calendar-alt"></i>
</button>
<input type="date" class="date-hidden-picker" id="date-end-picker" tabindex="-1" aria-hidden="true">
</div> </div>
</div> </div>
</div> </div>
+21 -1
View File
@@ -433,11 +433,15 @@ class DocumentRepository {
dd: document.getElementById('date-start-dd'), dd: document.getElementById('date-start-dd'),
mm: document.getElementById('date-start-mm'), mm: document.getElementById('date-start-mm'),
yyyy: document.getElementById('date-start-yyyy'), yyyy: document.getElementById('date-start-yyyy'),
picker: document.getElementById('date-start-picker'),
calBtn: document.getElementById('date-start-cal-btn'),
}; };
this.dateEndParts = { this.dateEndParts = {
dd: document.getElementById('date-end-dd'), dd: document.getElementById('date-end-dd'),
mm: document.getElementById('date-end-mm'), mm: document.getElementById('date-end-mm'),
yyyy: document.getElementById('date-end-yyyy'), yyyy: document.getElementById('date-end-yyyy'),
picker: document.getElementById('date-end-picker'),
calBtn: document.getElementById('date-end-cal-btn'),
}; };
this.cards = []; this.cards = [];
@@ -474,9 +478,10 @@ class DocumentRepository {
// • numeric-only keydown guard // • numeric-only keydown guard
// • auto-advance dd→mm after 2 chars, mm→yyyy after 2 chars // • auto-advance dd→mm after 2 chars, mm→yyyy after 2 chars
// • backspace from empty field navigates back // • backspace from empty field navigates back
// • calendar button opens native date picker; selection syncs to text inputs
// • calls onUpdate() on every change // • calls onUpdate() on every change
_bindDateParts(parts, onUpdate) { _bindDateParts(parts, onUpdate) {
const { dd, mm, yyyy } = parts; const { dd, mm, yyyy, picker, calBtn } = parts;
const CTRL_KEYS = new Set(['Backspace', 'Delete', 'Tab', 'ArrowLeft', 'ArrowRight', 'Home', 'End', 'Enter']); const CTRL_KEYS = new Set(['Backspace', 'Delete', 'Tab', 'ArrowLeft', 'ArrowRight', 'Home', 'End', 'Enter']);
const setup = (input, prev, next) => { const setup = (input, prev, next) => {
@@ -496,6 +501,21 @@ class DocumentRepository {
setup(dd, null, mm); setup(dd, null, mm);
setup(mm, dd, yyyy); setup(mm, dd, yyyy);
setup(yyyy, mm, null); setup(yyyy, mm, null);
// Calendar button → open native picker, then sync selection back to text inputs.
if (calBtn && picker) {
calBtn.addEventListener('click', () => {
try { picker.showPicker(); } catch { picker.click(); }
});
picker.addEventListener('change', () => {
if (!picker.value) return;
const [y, m, d] = picker.value.split('-');
if (dd) dd.value = d;
if (mm) mm.value = m;
if (yyyy) yyyy.value = y;
onUpdate();
});
}
} }
async init() { async init() {