Add label range filter (two inputs) to dashboard

This commit is contained in:
2026-05-02 03:45:45 -05:00
parent fa22e98060
commit de986a9305
+20 -2
View File
@@ -129,6 +129,10 @@
</select> </select>
<input type="text" id="filter-text" oninput="applyFilters()" placeholder="Search…" <input type="text" id="filter-text" oninput="applyFilters()" placeholder="Search…"
style="padding:0.25rem 0.5rem;font-size:0.85rem;border:1px solid #cbd5e1;border-radius:4px;width:140px;"> style="padding:0.25rem 0.5rem;font-size:0.85rem;border:1px solid #cbd5e1;border-radius:4px;width:140px;">
<input type="number" id="filter-range-from" oninput="applyFilters()" placeholder="# from"
style="padding:0.25rem 0.5rem;font-size:0.85rem;border:1px solid #cbd5e1;border-radius:4px;width:70px;">
<input type="number" id="filter-range-to" oninput="applyFilters()" placeholder="# to"
style="padding:0.25rem 0.5rem;font-size:0.85rem;border:1px solid #cbd5e1;border-radius:4px;width:70px;">
<button type="button" id="select-all-btn" onclick="mobileSelectAll()" class="btn btn-sm btn-secondary" style="display:none;">Select all</button> <button type="button" id="select-all-btn" onclick="mobileSelectAll()" class="btn btn-sm btn-secondary" style="display:none;">Select all</button>
<button type="button" onclick="resetFilters()" class="btn btn-sm btn-secondary" id="filter-reset" style="display:none;">✕ Reset</button> <button type="button" onclick="resetFilters()" class="btn btn-sm btn-secondary" id="filter-reset" style="display:none;">✕ Reset</button>
<span id="filter-count" style="font-size:0.8rem;color:#64748b;"></span> <span id="filter-count" style="font-size:0.8rem;color:#64748b;"></span>
@@ -219,7 +223,7 @@
</thead> </thead>
<tbody> <tbody>
{% for b in batteries %} {% for b in batteries %}
<tr data-brand="{{ b.brand }}" data-size="{{ b.size or '' }}" data-status="{{ b.status }}" data-storage="{{ b.storage_location or '' }}"> <tr data-brand="{{ b.brand }}" data-size="{{ b.size or '' }}" data-status="{{ b.status }}" data-storage="{{ b.storage_location or '' }}" data-label="{{ b.label }}">
<td data-label=""><input type="checkbox" name="battery_ids" value="{{ b.id }}" class="row-cb"></td> <td data-label=""><input type="checkbox" name="battery_ids" value="{{ b.id }}" class="row-cb"></td>
<td data-label="Label" data-sort-col="label" data-sort="{{ b.label }}"><a href="{{ url_for('battery_detail', battery_id=b.id) }}"><strong>{{ b.label }}</strong></a></td> <td data-label="Label" data-sort-col="label" data-sort="{{ b.label }}"><a href="{{ url_for('battery_detail', battery_id=b.id) }}"><strong>{{ b.label }}</strong></a></td>
<td data-label="Brand" data-sort-col="brand" data-sort="{{ b.brand }}">{{ b.brand }}</td> <td data-label="Brand" data-sort-col="brand" data-sort="{{ b.brand }}">{{ b.brand }}</td>
@@ -371,7 +375,11 @@ function applyFilters() {
var size = document.getElementById('filter-size').value; var size = document.getElementById('filter-size').value;
var storage = document.getElementById('filter-storage').value; var storage = document.getElementById('filter-storage').value;
var text = document.getElementById('filter-text').value.trim().toLowerCase(); var text = document.getElementById('filter-text').value.trim().toLowerCase();
var anyActive = (status && status !== 'active') || brand || size || storage || text; var rangeFromVal = document.getElementById('filter-range-from').value.trim();
var rangeToVal = document.getElementById('filter-range-to').value.trim();
var rangeMin = rangeFromVal !== '' ? parseInt(rangeFromVal, 10) : null;
var rangeMax = rangeToVal !== '' ? parseInt(rangeToVal, 10) : null;
var anyActive = (status && status !== 'active') || brand || size || storage || text || rangeFromVal || rangeToVal;
document.getElementById('filter-reset').style.display = anyActive ? '' : 'none'; document.getElementById('filter-reset').style.display = anyActive ? '' : 'none';
var rows = document.querySelectorAll('tbody tr[data-brand]'); var rows = document.querySelectorAll('tbody tr[data-brand]');
@@ -387,6 +395,14 @@ function applyFilters() {
if (size && row.dataset.size !== size) show = false; if (size && row.dataset.size !== size) show = false;
if (storage && row.dataset.storage !== storage) show = false; if (storage && row.dataset.storage !== storage) show = false;
if (text && row.textContent.toLowerCase().indexOf(text) === -1) show = false; if (text && row.textContent.toLowerCase().indexOf(text) === -1) show = false;
if (rangeMin !== null || rangeMax !== null) {
var lbl = row.dataset.label || '';
var m = lbl.match(/(\d+)\s*$/);
var n = m ? parseInt(m[1], 10) : null;
if (n === null) show = false;
else if (rangeMin !== null && n < rangeMin) show = false;
else if (rangeMax !== null && n > rangeMax) show = false;
}
row.dataset.filteredOut = show ? '' : '1'; row.dataset.filteredOut = show ? '' : '1';
if (show) filtered++; if (show) filtered++;
}); });
@@ -468,6 +484,8 @@ function resetFilters() {
document.getElementById(id).value = ''; document.getElementById(id).value = '';
}); });
document.getElementById('filter-text').value = ''; document.getElementById('filter-text').value = '';
document.getElementById('filter-range-from').value = '';
document.getElementById('filter-range-to').value = '';
applyFilters(); applyFilters();
} }