Replace datalist autocomplete with select dropdown for brand fields
datalist only shows suggestions when typing, not on click. Switched to a <select> showing all known brands plus a 'New brand...' option that reveals a text input for entering a new brand name.
This commit is contained in:
@@ -7,12 +7,17 @@
|
|||||||
<div class="card">
|
<div class="card">
|
||||||
<form method="post" action="{{ url_for('battery_add') }}">
|
<form method="post" action="{{ url_for('battery_add') }}">
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="brand">Brand <span class="text-danger">*</span></label>
|
<label for="brand-select">Brand <span class="text-danger">*</span></label>
|
||||||
|
<select id="brand-select" onchange="brandSelectChanged(this, 'brand')">
|
||||||
|
<option value="">— select a brand —</option>
|
||||||
|
{% for b in brands|default([]) %}
|
||||||
|
<option value="{{ b }}">{{ b }}</option>
|
||||||
|
{% endfor %}
|
||||||
|
<option value="__new__">➕ New brand…</option>
|
||||||
|
</select>
|
||||||
<input type="text" id="brand" name="brand" value="{{ form_brand|default('') }}"
|
<input type="text" id="brand" name="brand" value="{{ form_brand|default('') }}"
|
||||||
placeholder="e.g. Panasonic Eneloop" list="brand-list" required>
|
placeholder="Type new brand name" required
|
||||||
<datalist id="brand-list">
|
style="display:none;margin-top:0.4rem;">
|
||||||
{% for b in brands|default([]) %}<option value="{{ b }}">{% endfor %}
|
|
||||||
</datalist>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
@@ -32,4 +37,34 @@
|
|||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
function brandSelectChanged(sel, inputId) {
|
||||||
|
var input = document.getElementById(inputId);
|
||||||
|
if (sel.value === '__new__' || sel.value === '') {
|
||||||
|
input.style.display = '';
|
||||||
|
input.value = '';
|
||||||
|
input.focus();
|
||||||
|
} else {
|
||||||
|
input.style.display = 'none';
|
||||||
|
input.value = sel.value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Restore state on error re-render (form_brand set)
|
||||||
|
(function () {
|
||||||
|
var input = document.getElementById('brand');
|
||||||
|
var sel = document.getElementById('brand-select');
|
||||||
|
if (!input.value) return;
|
||||||
|
for (var i = 0; i < sel.options.length; i++) {
|
||||||
|
if (sel.options[i].value === input.value) {
|
||||||
|
sel.value = input.value;
|
||||||
|
input.style.display = 'none';
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
sel.value = '__new__';
|
||||||
|
input.style.display = '';
|
||||||
|
}());
|
||||||
|
</script>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|||||||
@@ -29,22 +29,43 @@
|
|||||||
<h2>Install Batteries</h2>
|
<h2>Install Batteries</h2>
|
||||||
{% set free_slots = device.battery_slots - device.installed_count() %}
|
{% set free_slots = device.battery_slots - device.installed_count() %}
|
||||||
<p class="text-muted" style="margin-bottom:0.75rem;">{{ free_slots }} slot(s) free</p>
|
<p class="text-muted" style="margin-bottom:0.75rem;">{{ free_slots }} slot(s) free</p>
|
||||||
<datalist id="brand-list">
|
|
||||||
{% for b in brands|default([]) %}<option value="{{ b }}">{% endfor %}
|
|
||||||
</datalist>
|
|
||||||
<form method="post" action="{{ url_for('device_install', device_id=device.id) }}">
|
<form method="post" action="{{ url_for('device_install', device_id=device.id) }}">
|
||||||
<div style="display:grid;grid-template-columns:1fr auto;gap:0.4rem;max-width:360px;align-items:center;margin-bottom:0.75rem;">
|
<div style="display:grid;grid-template-columns:1fr auto;gap:0.4rem;max-width:400px;align-items:start;margin-bottom:0.75rem;">
|
||||||
<span style="font-weight:600;font-size:0.85rem;color:#64748b;">Brand</span>
|
<span style="font-weight:600;font-size:0.85rem;color:#64748b;">Brand</span>
|
||||||
<span style="font-weight:600;font-size:0.85rem;color:#64748b;">Qty</span>
|
<span style="font-weight:600;font-size:0.85rem;color:#64748b;">Qty</span>
|
||||||
{% for _ in range(4) %}
|
{% for i in range(1, 5) %}
|
||||||
<input type="text" name="brand[]" placeholder="e.g. Eneloop"
|
<div>
|
||||||
list="brand-list" style="padding:0.3rem 0.5rem;">
|
<select onchange="brandSelectChanged(this, 'brand-{{ i }}')">
|
||||||
|
<option value="">— select —</option>
|
||||||
|
{% for b in brands|default([]) %}
|
||||||
|
<option value="{{ b }}">{{ b }}</option>
|
||||||
|
{% endfor %}
|
||||||
|
<option value="__new__">➕ New brand…</option>
|
||||||
|
</select>
|
||||||
|
<input type="text" id="brand-{{ i }}" name="brand[]" value=""
|
||||||
|
placeholder="Type brand name"
|
||||||
|
style="display:none;margin-top:0.3rem;padding:0.3rem 0.5rem;">
|
||||||
|
</div>
|
||||||
<input type="number" name="qty[]" value="0" min="0"
|
<input type="number" name="qty[]" value="0" min="0"
|
||||||
style="padding:0.3rem 0.5rem;width:4rem;text-align:center;">
|
style="padding:0.3rem 0.5rem;width:4rem;text-align:center;">
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</div>
|
</div>
|
||||||
<button class="btn btn-primary" type="submit">Install</button>
|
<button class="btn btn-primary" type="submit">Install</button>
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
function brandSelectChanged(sel, inputId) {
|
||||||
|
var input = document.getElementById(inputId);
|
||||||
|
if (sel.value === '__new__' || sel.value === '') {
|
||||||
|
input.style.display = sel.value === '__new__' ? '' : 'none';
|
||||||
|
input.value = '';
|
||||||
|
if (sel.value === '__new__') input.focus();
|
||||||
|
} else {
|
||||||
|
input.style.display = 'none';
|
||||||
|
input.value = sel.value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="card">
|
<div class="card">
|
||||||
|
|||||||
Reference in New Issue
Block a user