Files

160 lines
6.4 KiB
HTML
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
{% extends "base.html" %}
{% block title %}Add Batteries — Battery Tracker{% endblock %}
{% block content %}
<h1>Add Batteries</h1>
<div class="card">
<form method="post" action="{{ url_for('battery_add') }}">
<div class="form-grid-2col" style="display:grid;grid-template-columns:1fr 1fr;gap:0 1rem;">
<div class="form-group" style="grid-column:1/-1;">
<label for="brand-select">Brand <span class="text-danger">*</span></label>
<select id="brand-select" onchange="metaSelectChanged(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('') }}"
placeholder="Type new brand name" required
style="display:none;margin-top:0.4rem;">
</div>
<div class="form-group">
<label for="count">Quantity</label>
<input type="number" id="count" name="count" value="{{ form_count|default(1) }}" min="1" max="50">
<small class="text-muted">Labels are auto-generated (e.g. Eneloop 001, Eneloop 002)</small>
<div style="margin-top:0.4rem;">
<label style="display:inline-flex;align-items:center;gap:0.4rem;font-weight:normal;cursor:pointer;">
<input type="checkbox" id="include_size_in_label" name="include_size_in_label">
Include size in label (e.g. Eneloop AAA 001)
</label>
</div>
<div id="label-preview" style="font-size:0.85rem;color:var(--link);margin-top:0.3rem;font-weight:500;min-height:1.2em;"></div>
</div>
<div class="form-group">
<label for="capacity_mah">Capacity (mAh)</label>
<input type="number" id="capacity_mah" name="capacity_mah" min="0"
value="" placeholder="e.g. 2000 — optional">
</div>
<div class="form-group">
<label>Size</label>
<select id="size-select" onchange="metaSelectChanged(this,'size')">
<option value="">— none —</option>
{% for opt in ['AA','AAA','C','D','9V','18650','21700','14500','26650','CR2032','CR123A'] %}
<option value="{{ opt }}">{{ opt }}</option>
{% endfor %}
<option value="__new__">Other…</option>
</select>
<input type="text" id="size" name="size" value=""
placeholder="Enter size" style="display:none;margin-top:0.4rem;">
</div>
<div class="form-group">
<label>Chemistry</label>
<select id="chemistry-select" onchange="metaSelectChanged(this,'chemistry')">
<option value="">— none —</option>
{% for opt in ['NiMH','Alkaline','Li-ion','LiFePO4','NiCd','Zinc-Carbon','Li-MnO2'] %}
<option value="{{ opt }}">{{ opt }}</option>
{% endfor %}
<option value="__new__">Other…</option>
</select>
<input type="text" id="chemistry" name="chemistry" value=""
placeholder="Enter chemistry" style="display:none;margin-top:0.4rem;">
</div>
<div class="form-group">
<label for="purchase_date">Purchase Date</label>
<input type="date" id="purchase_date" name="purchase_date" value="">
</div>
</div>
<div class="form-group">
<label>Storage Location</label>
<select id="storage-select" onchange="metaSelectChanged(this,'storage_location')">
<option value="">— none —</option>
{% for loc in storage_locations|default([]) %}
<option value="{{ loc }}">{{ loc }}</option>
{% endfor %}
<option value="__new__"> New location…</option>
</select>
<input type="text" id="storage_location" name="storage_location" value=""
placeholder="e.g. Drawer 2, Toolbox, Shelf A"
style="display:none;margin-top:0.4rem;">
</div>
<div class="form-group">
<label for="notes">Notes</label>
<textarea id="notes" name="notes"
placeholder="Optional notes applied to all batteries…">{{ form_notes|default('') }}</textarea>
</div>
<div class="form-actions">
<button class="btn btn-primary" type="submit">Add Batteries</button>
<a class="btn btn-secondary" href="{{ url_for('dashboard') }}">Cancel</a>
</div>
</form>
</div>
<script>
var prefixMaxNums = {{ prefix_max_nums|default({})|tojson }};
function metaSelectChanged(sel, inputId) {
var input = document.getElementById(inputId);
if (sel.value === '__new__') {
input.style.display = '';
input.value = '';
input.focus();
} else {
input.style.display = 'none';
input.value = sel.value;
}
if (inputId === 'brand' || inputId === 'size') updateLabelPreview();
}
function updateLabelPreview() {
var brand = document.getElementById('brand').value.trim();
var size = document.getElementById('size').value.trim();
var includeSize = document.getElementById('include_size_in_label').checked;
var count = parseInt(document.getElementById('count').value, 10) || 1;
var preview = document.getElementById('label-preview');
if (!brand) { preview.textContent = ''; return; }
var prefix = (includeSize && size) ? brand + ' ' + size : brand;
var existing = prefixMaxNums[prefix] !== undefined ? prefixMaxNums[prefix] : 0;
var first = existing + 1;
var last = existing + count;
var pad = function(n) { return n.toString().padStart(3, '0'); };
preview.textContent = count === 1
? 'Will create: ' + prefix + ' ' + pad(first)
: 'Will create: ' + prefix + ' ' + pad(first) + ' \u2192 ' + prefix + ' ' + pad(last);
}
document.getElementById('count').addEventListener('input', updateLabelPreview);
document.getElementById('brand').addEventListener('input', updateLabelPreview);
document.getElementById('size').addEventListener('input', updateLabelPreview);
document.getElementById('include_size_in_label').addEventListener('change', updateLabelPreview);
// Restore brand state on error re-render
(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 %}