Servis detalji: select umesto datalist, bez skoka i treperenja
Izbor usluge/artikla je sada običan <select> (otvara se jednim klikom, ima native pretragu kucanjem, prikazuje samo naziv bez '(N kom)') umesto datalist combobox-a koji je tražio dvostruki klik. Kategorija filtrira artikle, 'U magacinu' i kontrole su poravnate u istom redu. Skok na vrh rešen čuvanjem/vraćanjem scrollTop pravog scroll kontejnera (#sadrzaj), uz bez-anim protiv treptaja.
This commit is contained in:
@@ -173,12 +173,10 @@
|
|||||||
<div style="display:grid;grid-template-columns:1fr 80px 120px auto;gap:10px;align-items:flex-end;">
|
<div style="display:grid;grid-template-columns:1fr 80px 120px auto;gap:10px;align-items:flex-end;">
|
||||||
<div>
|
<div>
|
||||||
<label style="font-size:12px;color:var(--tekst-sporedni);display:block;margin-bottom:4px;">Usluga</label>
|
<label style="font-size:12px;color:var(--tekst-sporedni);display:block;margin-bottom:4px;">Usluga</label>
|
||||||
<input type="text" id="rad-usluga-pretraga" list="usluge-datalist" autocomplete="off"
|
<select name="usluga_id" id="rad-usluga" style="width:100%;" required>
|
||||||
placeholder="Pretraži uslugu..." style="width:100%;">
|
<option value="">— odaberi uslugu —</option>
|
||||||
<datalist id="usluge-datalist">
|
{{range .Usluge}}<option value="{{.ID}}" data-cena="{{.Cena}}">{{.Naziv}}</option>{{end}}
|
||||||
{{range .Usluge}}<option value="{{.Naziv}}" data-id="{{.ID}}" data-cena="{{.Cena}}">{{end}}
|
</select>
|
||||||
</datalist>
|
|
||||||
<input type="hidden" name="usluga_id" id="rad-usluga">
|
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<label style="font-size:12px;color:var(--tekst-sporedni);display:block;margin-bottom:4px;">Kol.</label>
|
<label style="font-size:12px;color:var(--tekst-sporedni);display:block;margin-bottom:4px;">Kol.</label>
|
||||||
@@ -256,14 +254,13 @@
|
|||||||
<div style="display:grid;grid-template-columns:1fr 70px 80px 120px auto;gap:10px;align-items:flex-end;">
|
<div style="display:grid;grid-template-columns:1fr 70px 80px 120px auto;gap:10px;align-items:flex-end;">
|
||||||
<div>
|
<div>
|
||||||
<label style="font-size:12px;color:var(--tekst-sporedni);display:block;margin-bottom:4px;">Artikal</label>
|
<label style="font-size:12px;color:var(--tekst-sporedni);display:block;margin-bottom:4px;">Artikal</label>
|
||||||
<input type="text" id="deo-artikal-pretraga" list="artikli-datalist" autocomplete="off"
|
<select name="artikal_id" id="deo-artikal" style="width:100%;" required>
|
||||||
placeholder="Pretraži artikal..." style="width:100%;">
|
<option value="">— odaberi artikal —</option>
|
||||||
<datalist id="artikli-datalist"></datalist>
|
</select>
|
||||||
<input type="hidden" name="artikal_id" id="deo-artikal">
|
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<label style="font-size:12px;color:var(--tekst-sporedni);display:block;margin-bottom:4px;">U magacinu</label>
|
<label style="font-size:12px;color:var(--tekst-sporedni);display:block;margin-bottom:4px;">U magacinu</label>
|
||||||
<div id="deo-umagacinu" style="font-size:14px;font-weight:500;color:var(--tekst-glavni);text-align:center;padding:8px 0;">—</div>
|
<div id="deo-umagacinu" style="font-size:14px;font-weight:500;color:var(--tekst-glavni);text-align:center;padding:8px 0;border:0.5px solid transparent;">—</div>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<label style="font-size:12px;color:var(--tekst-sporedni);display:block;margin-bottom:4px;">Kol.</label>
|
<label style="font-size:12px;color:var(--tekst-sporedni);display:block;margin-bottom:4px;">Kol.</label>
|
||||||
@@ -345,50 +342,28 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
// veže pretraživo polje (datalist) na skriveni ID + auto-popunu cene.
|
// Radovi: pri izboru usluge iz <select>-a popuni predloženu cenu (data-cena).
|
||||||
// Korisnik kuca i bira stavku iz padajuće liste; iz izabrane opcije čitamo
|
(function () {
|
||||||
// data-id (pravi ID za server) i data-cena (predlog cene).
|
var sel = document.getElementById('rad-usluga');
|
||||||
function vežiCombobox(pretragaId, datalistId, hiddenId, cenaId) {
|
var cena = document.getElementById('rad-cena');
|
||||||
var pretraga = document.getElementById(pretragaId);
|
if (!sel || !cena) return;
|
||||||
var datalist = document.getElementById(datalistId);
|
sel.addEventListener('change', function () {
|
||||||
var hidden = document.getElementById(hiddenId);
|
var opt = sel.options[sel.selectedIndex];
|
||||||
var cena = document.getElementById(cenaId);
|
var c = parseFloat(opt.getAttribute('data-cena'));
|
||||||
if (!pretraga || !datalist || !hidden) return;
|
cena.value = (!isNaN(c) && c > 0) ? c.toFixed(2) : '0';
|
||||||
function uskladi() {
|
});
|
||||||
var izbor = null;
|
})();
|
||||||
var opcije = datalist.options;
|
|
||||||
for (var i = 0; i < opcije.length; i++) {
|
|
||||||
if (opcije[i].value === pretraga.value) { izbor = opcije[i]; break; }
|
|
||||||
}
|
|
||||||
if (izbor) {
|
|
||||||
hidden.value = izbor.dataset.id || '';
|
|
||||||
if (cena) {
|
|
||||||
var c = parseFloat(izbor.dataset.cena);
|
|
||||||
cena.value = (!isNaN(c) && c > 0) ? c.toFixed(2) : '0';
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
hidden.value = '';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
pretraga.addEventListener('input', uskladi);
|
|
||||||
pretraga.addEventListener('change', uskladi);
|
|
||||||
}
|
|
||||||
vežiCombobox('rad-usluga-pretraga', 'usluge-datalist', 'rad-usluga', 'rad-cena');
|
|
||||||
|
|
||||||
// Delovi: kategorija filter + ograničenje količine na magacinsko stanje.
|
// Delovi: kategorija filtrira <select> artikala; izborom artikla popunjavamo
|
||||||
// Datalist se gradi iz JSON-a po izabranoj kategoriji; pri izboru artikla
|
// cenu i prikaz „U magacinu". Običan <select> ima native pretragu kucanjem
|
||||||
// postavljamo cenu, max količine = stanje, i prikaz dostupne količine.
|
// i otvara se jednim klikom (za razliku od datalist-a).
|
||||||
(function () {
|
(function () {
|
||||||
var ARTIKLI = {{json .Artikli}} || [];
|
var ARTIKLI = {{json .Artikli}} || [];
|
||||||
var kategSel = document.getElementById('deo-kategorija');
|
var kategSel = document.getElementById('deo-kategorija');
|
||||||
var pretraga = document.getElementById('deo-artikal-pretraga');
|
var artikalSel = document.getElementById('deo-artikal');
|
||||||
var datalist = document.getElementById('artikli-datalist');
|
|
||||||
var hidden = document.getElementById('deo-artikal');
|
|
||||||
var cena = document.getElementById('deo-cena');
|
var cena = document.getElementById('deo-cena');
|
||||||
var umagacinu = document.getElementById('deo-umagacinu');
|
var umagacinu = document.getElementById('deo-umagacinu');
|
||||||
if (!pretraga || !datalist) return;
|
if (!artikalSel) return;
|
||||||
|
|
||||||
function labela(a) { return a.Naziv + ' (' + a.Kolicina + ' kom)'; }
|
|
||||||
|
|
||||||
if (kategSel) {
|
if (kategSel) {
|
||||||
var kategs = [];
|
var kategs = [];
|
||||||
@@ -401,43 +376,26 @@ vežiCombobox('rad-usluga-pretraga', 'usluge-datalist', 'rad-usluga', 'rad-cena'
|
|||||||
kategs.map(function (k) { return '<option value="' + k + '">' + k + '</option>'; }).join('');
|
kategs.map(function (k) { return '<option value="' + k + '">' + k + '</option>'; }).join('');
|
||||||
}
|
}
|
||||||
|
|
||||||
function popuniDatalist() {
|
function popuniArtikle() {
|
||||||
var izabrana = kategSel ? kategSel.value : '';
|
var izabrana = kategSel ? kategSel.value : '';
|
||||||
datalist.innerHTML = ARTIKLI
|
artikalSel.innerHTML = '<option value="">— odaberi artikal —</option>' +
|
||||||
.filter(function (a) { return !izabrana || (a.KategorijaNaziv || '') === izabrana; })
|
ARTIKLI.filter(function (a) { return !izabrana || (a.KategorijaNaziv || '') === izabrana; })
|
||||||
.map(function (a) {
|
.map(function (a) {
|
||||||
return '<option value="' + labela(a) + '" data-id="' + a.ID +
|
return '<option value="' + a.ID + '" data-cena="' + a.ProdajnaCena +
|
||||||
'" data-cena="' + a.ProdajnaCena + '" data-stanje="' + a.Kolicina + '">';
|
'" data-stanje="' + a.Kolicina + '">' + a.Naziv + '</option>';
|
||||||
}).join('');
|
}).join('');
|
||||||
}
|
|
||||||
popuniDatalist();
|
|
||||||
|
|
||||||
if (kategSel) kategSel.addEventListener('change', function () {
|
|
||||||
popuniDatalist();
|
|
||||||
pretraga.value = '';
|
|
||||||
hidden.value = '';
|
|
||||||
if (umagacinu) umagacinu.textContent = '—';
|
if (umagacinu) umagacinu.textContent = '—';
|
||||||
});
|
|
||||||
|
|
||||||
function uskladi() {
|
|
||||||
var opt = null, opts = datalist.options;
|
|
||||||
for (var i = 0; i < opts.length; i++) {
|
|
||||||
if (opts[i].value === pretraga.value) { opt = opts[i]; break; }
|
|
||||||
}
|
|
||||||
if (opt) {
|
|
||||||
hidden.value = opt.dataset.id || '';
|
|
||||||
if (cena) {
|
|
||||||
var c = parseFloat(opt.dataset.cena);
|
|
||||||
cena.value = (!isNaN(c) && c > 0) ? c.toFixed(2) : '0';
|
|
||||||
}
|
|
||||||
if (umagacinu) umagacinu.textContent = (parseInt(opt.dataset.stanje, 10) || 0);
|
|
||||||
} else {
|
|
||||||
hidden.value = '';
|
|
||||||
if (umagacinu) umagacinu.textContent = '—';
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
pretraga.addEventListener('input', uskladi);
|
popuniArtikle();
|
||||||
pretraga.addEventListener('change', uskladi);
|
if (kategSel) kategSel.addEventListener('change', popuniArtikle);
|
||||||
|
|
||||||
|
artikalSel.addEventListener('change', function () {
|
||||||
|
var opt = artikalSel.options[artikalSel.selectedIndex];
|
||||||
|
var c = parseFloat(opt.getAttribute('data-cena'));
|
||||||
|
if (cena) cena.value = (!isNaN(c) && c > 0) ? c.toFixed(2) : '0';
|
||||||
|
var st = parseInt(opt.getAttribute('data-stanje'), 10);
|
||||||
|
if (umagacinu) umagacinu.textContent = isNaN(st) ? '—' : st;
|
||||||
|
});
|
||||||
})();
|
})();
|
||||||
</script>
|
</script>
|
||||||
{{end}}
|
{{end}}
|
||||||
|
|||||||
@@ -396,6 +396,10 @@
|
|||||||
if (novi && stari) {
|
if (novi && stari) {
|
||||||
// bez-anim spречava treptaj re-animacije kartica pri zameni
|
// bez-anim spречava treptaj re-animacije kartica pri zameni
|
||||||
novi.classList.add('bez-anim');
|
novi.classList.add('bez-anim');
|
||||||
|
var sc = document.scrollingElement || document.documentElement;
|
||||||
|
var syDoc = sc ? sc.scrollTop : 0;
|
||||||
|
var gsStari = document.getElementById('sadrzaj');
|
||||||
|
var syGs = gsStari ? gsStari.scrollTop : 0;
|
||||||
stari.replaceWith(novi);
|
stari.replaceWith(novi);
|
||||||
void novi.offsetHeight;
|
void novi.offsetHeight;
|
||||||
novi.classList.remove('bez-anim');
|
novi.classList.remove('bez-anim');
|
||||||
@@ -406,6 +410,9 @@
|
|||||||
if (old.src) s.src = old.src; else s.textContent = old.textContent;
|
if (old.src) s.src = old.src; else s.textContent = old.textContent;
|
||||||
old.parentNode.replaceChild(s, old);
|
old.parentNode.replaceChild(s, old);
|
||||||
});
|
});
|
||||||
|
if (sc) sc.scrollTop = syDoc;
|
||||||
|
var gsNovi = document.getElementById('sadrzaj');
|
||||||
|
if (gsNovi) gsNovi.scrollTop = syGs;
|
||||||
}
|
}
|
||||||
if (btn) btn.disabled = false;
|
if (btn) btn.disabled = false;
|
||||||
})
|
})
|
||||||
|
|||||||
Reference in New Issue
Block a user