Klijent: validacija JMBG (13 cifara) i kontakt osoba za pravno lice

parseFormuKlijenta i mozdaKreirajKlijenta proveravaju JMBG kad je izabran taj
tip identifikacije. Forma pravnog lica dobija sekciju Kontakt osoba (ime/prezime);
neaktivna sekcija se onemogućava da server ne dobije duplu vrednost. renderujStandalone
parsira šablon sa root imenom i šablonskim funkcijama (kao kreirajKes).
This commit is contained in:
2026-06-21 19:07:38 +02:00
parent a744317316
commit 3def86ddb9
4 changed files with 57 additions and 10 deletions
+2 -1
View File
@@ -182,7 +182,8 @@ func (h *Handler) renderujStandalone(w http.ResponseWriter, ime string, podaci a
tmpl = t tmpl = t
} else { } else {
var err error var err error
if tmpl, err = template.ParseFS(h.TemplatesFS, "web/templates/stranice/"+ime+".html"); err != nil { // kao u kreirajKes: root mora biti ime+".html" i moraju biti registrovane šablonske funkcije
if tmpl, err = template.New(ime+".html").Funcs(sablonskeFunkcije).ParseFS(h.TemplatesFS, "web/templates/stranice/"+ime+".html"); err != nil {
slog.Error("greška pri parsiranju šablona", "ime", ime, "error", err) slog.Error("greška pri parsiranju šablona", "ime", ime, "error", err)
http.Error(w, "Greška pri učitavanju stranice", http.StatusInternalServerError) http.Error(w, "Greška pri učitavanju stranice", http.StatusInternalServerError)
return return
+26 -1
View File
@@ -278,6 +278,24 @@ func (h *Handler) ObrisiKlijenta(w http.ResponseWriter, r *http.Request) {
http.Redirect(w, r, "/klijenti?obrisan=1", http.StatusSeeOther) http.Redirect(w, r, "/klijenti?obrisan=1", http.StatusSeeOther)
} }
// validirajJMBG proverava da li uneti JMBG ima tačno 13 cifara. Prazan broj je
// dozvoljen (polje nije obavezno). Vraća srpsku poruku o grešci ili prazan string.
// Broj lične karte se ne proverava jer mu se format razlikuje između izdanja.
func validirajJMBG(broj string) string {
if broj == "" {
return ""
}
if len(broj) != 13 {
return "JMBG mora imati tačno 13 cifara."
}
for _, c := range broj {
if c < '0' || c > '9' {
return "JMBG sme sadržati samo cifre."
}
}
return ""
}
// parseFormuKlijenta čita polja iz HTTP forme, validira ih i vraća model i eventualnu grešku // parseFormuKlijenta čita polja iz HTTP forme, validira ih i vraća model i eventualnu grešku
func parseFormuKlijenta(r *http.Request) (model.Klijent, string) { func parseFormuKlijenta(r *http.Request) (model.Klijent, string) {
tip := r.FormValue("tip") tip := r.FormValue("tip")
@@ -306,11 +324,18 @@ func parseFormuKlijenta(r *http.Request) (model.Klijent, string) {
tipIdent = "jmbg" tipIdent = "jmbg"
} }
jmbg := strings.TrimSpace(r.FormValue("jmbg"))
if tipIdent == "jmbg" {
if greska := validirajJMBG(jmbg); greska != "" {
return model.Klijent{Tip: tip}, greska
}
}
return model.Klijent{ return model.Klijent{
Tip: tip, Tip: tip,
Ime: ime, Ime: ime,
Prezime: strings.TrimSpace(r.FormValue("prezime")), Prezime: strings.TrimSpace(r.FormValue("prezime")),
JMBG: strings.TrimSpace(r.FormValue("jmbg")), JMBG: jmbg,
TipIdentifikacije: tipIdent, TipIdentifikacije: tipIdent,
NazivFirme: nazivFirme, NazivFirme: nazivFirme,
PIB: strings.TrimSpace(r.FormValue("pib")), PIB: strings.TrimSpace(r.FormValue("pib")),
+8 -1
View File
@@ -625,11 +625,18 @@ func (h *Handler) mozdaKreirajKlijenta(ctx context.Context, r *http.Request, nal
tipIdent = "jmbg" tipIdent = "jmbg"
} }
jmbg := strings.TrimSpace(r.FormValue("jmbg"))
if tipIdent == "jmbg" {
if greska := validirajJMBG(jmbg); greska != "" {
return greska
}
}
klijent := model.Klijent{ klijent := model.Klijent{
Tip: tip, Tip: tip,
Ime: ime, Ime: ime,
Prezime: strings.TrimSpace(r.FormValue("prezime")), Prezime: strings.TrimSpace(r.FormValue("prezime")),
JMBG: strings.TrimSpace(r.FormValue("jmbg")), JMBG: jmbg,
TipIdentifikacije: tipIdent, TipIdentifikacije: tipIdent,
NazivFirme: nazivFirme, NazivFirme: nazivFirme,
PIB: strings.TrimSpace(r.FormValue("pib")), PIB: strings.TrimSpace(r.FormValue("pib")),
+21 -7
View File
@@ -110,6 +110,20 @@
placeholder="npr. 123456789"> placeholder="npr. 123456789">
</div> </div>
</div> </div>
<!-- kontakt osoba u firmi — čuva se u poljima Ime/Prezime klijenta -->
<div class="sekcija-naslov">Kontakt osoba</div>
<div class="forma-grid-2">
<div>
<label class="polje-labela">Ime</label>
<input type="text" name="ime" value="{{.Klijent.Ime}}"
placeholder="npr. Marko">
</div>
<div>
<label class="polje-labela">Prezime</label>
<input type="text" name="prezime" value="{{.Klijent.Prezime}}"
placeholder="npr. Petrović">
</div>
</div>
</div> </div>
<!-- kontakt --> <!-- kontakt -->
@@ -158,13 +172,13 @@
function promenaTipa(tip) { function promenaTipa(tip) {
var secFiz = document.getElementById('sec-fizicko'); var secFiz = document.getElementById('sec-fizicko');
var secPrav = document.getElementById('sec-pravno'); var secPrav = document.getElementById('sec-pravno');
if (tip === 'pravno') { var pravno = tip === 'pravno';
secFiz.style.display = 'none'; secFiz.style.display = pravno ? 'none' : 'flex';
secPrav.style.display = 'flex'; secPrav.style.display = pravno ? 'flex' : 'none';
} else { // skrivena polja se i dalje šalju; pošto obe sekcije imaju name="ime"/"prezime",
secFiz.style.display = 'flex'; // onemogućavamo polja neaktivne sekcije da server ne dobije pogrešnu vrednost
secPrav.style.display = 'none'; secFiz.querySelectorAll('input,select').forEach(function (el) { el.disabled = pravno; });
} secPrav.querySelectorAll('input,select').forEach(function (el) { el.disabled = !pravno; });
} }
// pri učitavanju prikazujemo ispravnu sekciju // pri učitavanju prikazujemo ispravnu sekciju
(function() { (function() {