[ emperor @ 13.03.2001. 15:01 ] @
pozdrav drugari

dakle treba mi ako neko zna da napravi formu u html ali da dugme SUBMIT bude zasenceno sve dok se u svako poslje neunese vrednost znaci da ne moze da se izvrsi forma ako nema sve podatke upisane
bio bi zahvalan ako bi neko da kod ovde


pozdrav svima
[ noviKorisnik @ 26.04.2004. 21:47 ] @
Jes da je iz arhive, ali je dobro za vežbu.

Recimo da je formular

Code:
<form action="dodaj.cgi" method="post">
ime <input type="text" name="ime" /><br />
prezime <input type="text" name="prezime" /><br />
e-mail <input type="text" name="email" /><br />
<input type="submit" value="prosledi" />
</form>


Pitanje je postavljeno pre više od 3 godine - kako organizovati javascript da submit dugme bude onemogućeno do trenutka kada su popunjena sva polja formulara?
[ bluesman @ 27.04.2004. 02:37 ] @
Evo na brzaka:

Code:

<form name="test">
<a href="javascript:enableSubmit();">sisa</a>
<input name=s type="submit" value="sdadsfa" disabled=true>
</form>

<SCRIPT LANGUAGE="JavaScript" TYPE="text/javascript">
<!--
function enableSubmit()
    {
    document.forms['test'].s.disabled = false;
    }
//-->
</SCRIPT>


E sad, to sto tebi treba je malo teze, odnosno, morao bi da proveravas konstantno da li su sva polja popunjena. Prva ideja je na onfocus, onblur za svako polje pozivas neku JS funkciju koja ce da proverava. medutim, tu treba biti oprezan, i dobro istestirati.

Mislim generalno da je to zbunjujuce, bolje da mu napises "popuni sva polja" pa na submit da radis proveru i ako nije ne dozvolis da submituje.
[ noviKorisnik @ 27.04.2004. 11:02 ] @
Naravno da je bolje da se napiše "popuni sva polja", jer ova postavka ima veći broj manjkavosti. Idemo redom:

1. ako je u browseru kojim slučajem isključen JS, ovo submit dugme zauvek ostaje onemogućeno.
2. ako u formularu postoji recimo tekstualno polje, pritiskom na Enter dok je fokus na takvom polju izvršava se submitovanje formulara.

Rešenje problema pod 2 zahteva dosta posla:
Code:
<form action="dodaj.cgi" method="post" onsubmit="proveri (this); return false;">
<input type="text" name="ime" value="" onchange="proveri (this.form);" />
<input type="submit" name="s" value="prosledi" onclick="this.form.submit ();" disabled />
</form>
<script>
function proveri (form)
{
    form.s.disabled = form.ime.value == '';
}
</script>

Funkcija proveri () omogućava ili onemogućava submit dugme u zavisnosti da li je unešena neka vrednost u tekstualno polje. Poziva se s dva mesta - u elementu formulara prilikom pritiska na Enter (problem 2) i prilikom promene vrednosti u polju.
U formularu kod onsubmit stoji i "return false;" što sprečava prosleđivanje formulara na Enter. Iz istog razloga formular ne bi bio prosleđen ni klikom na submit dugme, čak ni kada je omogućeno, pa se kod dugmeta dodaje direktan poziv metoda za proleđivanje formulara.

Moguće je da i u ovoj postavci još uvek nešto škripi, ali bih da se nastavi dalje:
- imamo n tekstualnih koja moraju biti popunjena da bi bilo omogućeno submit dugme, a pored tekstualnih polja u formularu se nalaze i drugi elementi (selekti, radio dugmad, čekboksovi...).
[ -zombie- @ 30.04.2004. 01:11 ] @
mislio sam da je pitanje postavljeno čisto kao vežba, pa nisam ni hteo da odgovaram.. ;)

evo, recimo ovako nešto:

Code:

function validate_not_null(form, fields, submit) {
    
    function validate() {
        submit.disabled=true;
        for (i in fields) {
            f = fields[i];
            if (f.type=='text' && !f.value.length) return;
            if (f.type=='checkbox' && !f.checked) return;
            if (f.type=='radio' && !f.checked) return;
            if (f.tagName.toLowerCase()=='select' && !f.selectedIndex) return;
        }
        submit.disabled=false;
        return true;
    }
    
    form = document.forms[form];
    form.onsubmit = function() {return !!validate()};

    for (i in fields) {
        fields[i] = form.elements[fields[i]];
        fields[i].onchange = fields[i].onkeyup = fields[i].onclick = validate;
    }

    submit = form.elements[submit];
    submit.disabled = true;
}


poziva se otprilike sa validate_not_null('imeForme', ['ime', 'prezime', 'email'], 'dugmePošalji'); samo što poziv mora da ide u body.onload, jer elementi forme nisu dostupni preko DOMa pre nego se stranica učita..

sa onchange, onkeyup i onclick mislim da sam pokrio sve moguće vidove editovanja (tastaturom i mišem), a sa form.onsubmit sam rešio drugi problem.

radi za sve tipove inputa, stim da je za checkboxove malo besmisleno checkbox je savršeno legalan ako se ne čekira, osim ako nije "čekiranjem potvrđujete da ste pročitali uslove licence, bla, bla..", pa se za to može koristiti.

select uvek ima neko polje selektovano, tako da je i to pomalo besmisleno, ali može kao prvo (default selektovano) polje da se ostavi prazno ili ono "--please-select--", pa primorati korisnika da odabere neki drugi (zato proveravam da li je selectedIndex veći od nula)..


funkcija pretpostavlja jedino da forma i submit dugme imaju imena, i mada je moglo i bez toga, mislim da to nije bitno (ovako je kod čistiji).. znači cela forma može da ostane netaknuta (bez dodavanja raznih eventa), funkcija sve sama završi..

sve u svemu, jednostavno je, elegantno, i sviđa mi se.. ;)
[ bluesman @ 30.04.2004. 02:10 ] @
Ja vidim samo jedan "mali" problem sa ovim kodom. Po njemu, sva polja u formularu moraju biti popunjena (to je zahtev ako se dobro secam) ali i svi checkbox-ovi moraju biti check-irani, kao i iz svakog select mora biti izabrana vrednost.

Sto se tice checkbox, recimo mozda postoji :
[ ] pretplati me na newsleter
a korisnik to ne zeli, ali da bi submitovao formu mora da izabere i ovu opciju. Ako je vec tako, onda ovo nije opcija nego "moranje", a onda gubi i svaki smisao stavljati ovakav checkbox na formular kada ionako "mora" :-)

Sto se select tice, klasican primer su countries + US states, ako izabere drzavu koja nije USA, onda se obicno state ostavi prazno. Po ovom kodu - to nije dozvoljeno, pa ce recimo biti korisnika iz drzave Srbija i Crna gora, a state recimo Alabama. Jos ako se obracunava neki state tax ili nesto ... eto problema.

Mozda staviti neki array polja koja su "must" pa proveravati samo njih, ako se koristi vec ovakvo "genericko" resenje.

// izmena: e jbg tomice, nisam citao tvoju poruku do kraja, samo kod pa sam brzopleto odgovorio, sada je gre'ota da brisem sve
[ -zombie- @ 30.04.2004. 04:22 ] @
hehe.. ;)

smešno mi je zato što sam baš počeo da razmišljam tako generalizovano.. prva ideja mi je bila da funkciji prosledim samo ime forme, pa da ona pronađe sve elemente forme, da im doda evente, i da sama pronađe submit dugme i disejbluje ga..

tj, čak ni ime forme ne bi bilo obavezno, jer bi onda funkcija koristila prvu formu na stranici.. a ne bi ni morala da se poziva iz body.onload, jer bi i to mogao da dodam kao event..

e to bi bila žešće automatizovana funkcija.. ;)

e sad, kada sam malo pauzirao i razmislio, shvatio sam da previše automatizacije i nije uvek tako dobro.. ;)

ovako, proslede se lepo required polja, pa onda i checkboxovi i selecti imaju (ponekad) smisla..

zaboravih i da napomenem da ako JS nije uključen sve radi regularno, i da funkcija za validaciju može lako da se proširi ako je potrebno nešto specifično proveriti..


nego, kada sam ponovo pogledao uslove (i proverio da i select ima type property), shvatih da validate() funkcija može da bude još jednostavnija i elegantnija..

Code:

props = {text: 'value', checkbox: 'checked', radio: 'checked', 
            'select-one': 'selectedIndex'};

function validate() {
    submit.disabled=true;
    for (i in fields) {
        if (!fields[i][props[fields[i].type]]) return;
    }
    submit.disabled=false;
    return true;
}


koristim props objekat kao asocijativni niz.. fino, a? ;)
[ noviKorisnik @ 30.04.2004. 08:01 ] @
U čemu je razlika između
Code:
<form>
<input type="radio" name="radijo" value="0" />
<input type="button" value="provijeri radijo"
  onclick="alert (this.form.radijo.type);" />
</form>

i
Code:
<form>
<input type="radio" name="radijo" value="0" />
<input type="radio" name="radijo" value="1" />
<input type="button" value="provijeri radijo"
  onclick="alert (this.form.radijo.type);" />
</form>

?

U ovom drugom slučaju this.form.radio je niz i nije mu definisano svojstvo type.
Čak i kada se uđe u taj niz, najviše jedan član niza ima setovano svojstvo checked.

Selekt
Code:
<form>
<select name="selekt" size="2">
<option value="0">0</option>
<option value="1">1</option>
</select>
<input type="button" value="provijeri selekt"
  onclick="alert (!!this.form.selekt.selectedIndex);" />
</form>

- ovaj je i dalje tipa select-one, ali mu je selectedIndex inicijalno -1, pa prolazi validaciju. Malo mi je nezgodno žrtvovanje prvog elementa niza opcija zbog kraćeg koda. Setovanje size atributa u selektu je ipak stvar dizajna formulara i ne treba da funkcionalnost zavisi od toga.
[ bluesman @ 30.04.2004. 14:51 ] @
Tomice, znas sta moze da se koristi, to sam jednom probao (u IE) i radilo je ok. Ti mozes svakom elementu da dodas neki svoj atribut (koji ne postoji u HTML-u)

recimo, mozes
<input type="text" name="neki_tekst" value="" required="da">

a onda proveravas
if (document.forms[n].elements[n].required == "da")
{
proveri da li je prazno
}

tako moze stvarno da se generalizuje tvoj script.
[ -zombie- @ 02.05.2004. 16:47 ] @
noviKorisnik: za radio dugmiće nisam proveravao (nisam se setio), tako da si u pravu, ono neće raditi. ali za select nisam upoređivao sa nulom (umesto sa -1) zato što mi nisu pali na pamet višeredni selekti (a oni se ionako uglavnom koriste kada je multiselekt, što nema smisla proveravati ovakvom funkcijom), a ne da bi skratio kod.

kod sam znatno skratio tek naknadno (u drugoj poruci) kada sam video da je to moguće uraditi..

dakle, evo ispravljene verzije, koja radi i sa radio dugmićima i sa višerednim selektima..

Code:

function validate_required(form, elements, submit) {
    
    function validate() {
        submit.disabled=true;
        if (this.type=='radio' && this.checked) {
            form[this.name].checked = true;
        }
        for (var i in elements) {
            var e = elements[i];
            if (e.type=='text' && !e.value.length) return;
            if (e.type=='checkbox' && !e.checked) return;
            if (e.type=='radio' && !form[e.name].checked) return;
            if (e.type=='select-one' && e.selectedIndex<(e.size<2)) return;
        }
        submit.disabled=false;
        return true;
    }
    
    form = document.forms[form];
    form.onsubmit = function() {return !!validate()};
    
    submit = form.elements[submit];
    
    for (var i in elements) {
        for (var j=0; j<form.length; j++) {
            var e = form[j];
            if (elements[i]==e.name || elements[i].name==e.name) {
                elements[i] = e;
                e.onchange = e.onkeyup = e.onclick = validate;
                e.onchange();
            }
        }
    }
}


poziva se isto kao i prethodna, i važi sve što sam rekao za nju.. kada je selekt jednoredni, opet mora da se žrtvuje prva opcija da glumi neselektovanu. kada je višeredni, onda ne mora..

btw, ovo je vrlo dobar primer da je validate() funkcija lako proširiva..


bluesman: znam da može tako, i to bi recimo još više uprostilo onu duplu petlju u funkciji, ali nisam tako hteo iz dva razloga:
- neko je možda čistunac, pa želi da mu html bude validan, tj bez dodatnih atributa. (mada, ovo se može rešiti sa atributima u novom namespace-u, ali to je komplikovanje..)
- i nekako mi se više sviđa ideja da na jednom mestu lepo pozovem funkciju, sa svim potrebnim parametrima, nego da jurim elemente i dodajem im atribute (isto kao što nisam voleo da im dodajem evente ručno..)

mada definitivno je ideja dobra, i nekome se može svideti. ako neko želi, mogu da odradim i tu verziju funkcije..