Autor Zpráva
Fibi
Profil
Nejprve nástin situace:
Mám na webu formulář k registraci pobytu. A snažím se vyřešit, aby po odeslání formuláře, proběhla jak kontrola správnosti položek, tak ještě kontrola obsazenosti ve vnitřní DB mimo web pomocí AJAX požadavku. Tedy volám kontrolní funkci v události OnSubmit formuláře onsubmit="return rezervace_kontrola(this)".
Ovšem je tam drobný problém, ten AJAX požadavek na obsazenost může trvat nechutně dlouho a v tom případě jej potřebuji utnout a jen si do skrytého pole dát informaci pro další zpracování.
K práci s JS využívám služeb jquery.

Můj dosavadní postup:
1 - našel jsem že jquery volání ajax se dá zavolat s nastavením timeout, takže první verze vypadala nějak takto :
var pozadavek = $.ajax({
            dataType: "json",
            url: "http://"+window.location.hostname+"/pro_ajax.php",
            timeout: 500,
            ...
        });
Dokud jsem měl na testování v kontrolní funkci na konci return false, aby se mi formulř neodesílal a jen jsem kontroloval AJAX požadavky atd, tak to makalo krásně, jenže když jsem vrátil true, tedy že kontrola doběhla OK, tak se už metoda pozadavek.done vůbec neprovedla a rovnou se spustila metoda pozadavek.fail(), tedy selhání požadavku.
Přitom požadavek na URL pro_ajax.php byl v pořádku odeslán a ten vracel správná data a velmi rychle, rozhodně výrazně pod timeoutem.
Navíc i když jsem dal timeout třeba 5000, okamžitě po odeslání formuláře se spustila metoda pozadavek.fail()
2 - zkusil jsem přepnout požadavky na synchronní, jestli nebude situace lepší a nebyla, bez ohledu na timeout, script vždy čekal na dokončení volaného php scriptu.
3 - zkusil jsem ještě extra nastavit metodu setTimeout a zavolat v ní pozadavek.abort() po nastaveném čase, ale opět provedlo se až po dokončení ajax požadavku.
setTimeout(function(){
    $('form#rezervace_formular input[name="fb_status"]').val('false');//status v FB na 0, tedy vyprsel timeout
    alert('timeout'); 
    pozadavek.abort();
}, 1000);
4 - zkusil jsem všechno ohledně AJAXu dát do extra funkce, abych jakoby přinutil tu kontrolní metodu donutil čekat na její výsledek, ale opět se mi hned vrátil timeout stav :-(

Jediné na co jsem přišel, když jsem na konec kontrolní funkce přidal alert('Text'), tak se začal script chovat dle očekávání, ale to není není příliš funkční řešení pro uživatele :-)
Vše jsem zkoušel i ve stylu zápisu s $.getJSON místo $.ajax a chovalo se to vždy úplně stejně :-)

Prosím tedy o radu.
napadají mně tři cesty :
- nějak zařídit aby kontrolní funkce čekala na výsledek ajaxu
- najít způsob jak ukončit probíhající synchronní ajax požadavek
- nějakým způsobem donutit $.ajax aby po uplynutí timeoutu v sync múodu skončil

Ale ani jedno řešení nevím jak zařídit.
V JS jsem v zásadě začátečník, pár věcí s využitím jquery a tím to u mně hasne.

Ještě aktuální část zdrojáku :
function rezervace_kontrola(formular) {
    var navrat;
    ...
    //cast testujici, jestli jsou zadane udaje OK, pokud jsou dam do navrat hodnotu tru
    
    navrat = true ;//jen  na testovani
    
    if (navrat == true) {
        var pozadavek = $.ajax({
            dataType: "json",
            url: "http://"+window.location.hostname+"/pro_ajax.php",
            timeout: 500,
            async: true,
            data: { 
                co: "10",
                id_obj: $('form#rezervace_formular input[name="id_obj"]').val(),
                odkdy: $('form#rezervace_formular input[name="odkdy"]').val(),
                dokdy: $('form#rezervace_formular input[name="dokdy"]').val()
            }
        });
        
        pozadavek.done(function(objekt_status){
            alert('Status: '+objekt_status);
            if (objekt_status == false) {
                alert('je to obsazene);
                location.reload(true);
            } else {
                $('form#rezervace_formular input[name="fb_status"]').val('true');//status v FB na 1, tedy je volno
            };
        });
        
        pozadavek.fail(function(){
            alert('Asi timeout');
            $('form#rezervace_formular input[name="fb_status"]').val('false');//status v FB na 0, tedy vyprsel timeout
        });
        
        alert('Info okno');
        
    };//konec podminky na navrat true    
    
};//konec funkce rezervace_kontrola
_es
Profil
Fibi:
aby po odeslání formuláře, proběhla jak kontrola správnosti položek, tak ještě kontrola obsazenosti ve vnitřní DB mimo web pomocí AJAX požadavku.
Nemyslíš pred odoslaním formulára - po požiadavke návštevníka na odoslanie formulára?
Fibi
Profil
_es:
Jo jasně, přesně tak :-)
Každopádně, také se už někomu stalo, že těsně potom, co pošle dotaz do poradny, na to řešení přijde ?
No tak pro tento případ jsem našel řešení prostě v tom, že tu kontrolu nevážu na událost onsubmit formuláře, ale na událost onclick odesílacího talčítka a když kontrola proběhne celá OK, pomocí jqery formulář odešlu.
Tak to jen tak pro příště :-)
Keeehi
Profil
Fibi:
A co když ten formulář odešlu entrem?
Nezkoušel jsem, jen se ptám.
Fibi
Profil
Keeehi:
Aha vida, chyba v matrixu, to mně nenapadlo.
Pak jsem tak nějak v háji řekl bych :-)
I když takových asi moc nebude, je to rezervační formulář a co jsem sledoval uživatele, vždycky klikli na tlačítko.
Asi budu muset kontroly rozdělit, kontrola pro správnost položek pověsit na onsubmit a kontrolu s nutností timeoutu na ten onclick u tlačítka.
Ale že by to bylo nějak extra elegantní řešení, to teda není :-(
Keeehi
Profil
Fibi:
Určitě to vyřešit jen s vazbou na událost onsubmit. Nejsem však schopen to teď zkoušet.
Chamurappi
Profil
Reaguji na Keeehiho:
A co když ten formulář odešlu entrem?
Tak se vyvolá onclick na prvním <input type="submit">.


Reaguji na Fibiho:
jenže když jsem vrátil true, tedy že kontrola doběhla OK, tak se už metoda pozadavek.done vůbec neprovedla a rovnou se spustila metoda pozadavek.fail()
Pokud vrátíš true, tak se formulář normálně odešle, tudíž se okamžitě odchází ze stránky. Nehledě na to, co si někdy později usmyslí AJAX.
Musíš odeslání zrušit vždy. Jde o poměrně častý problém, viz třeba ajax, false reakce na návratovou hodnotu a Odeslání formuláře javascriptem.
Keeehi
Profil
Chamurappi:
Tak se vyvolá onclick na prvním <input type="submit">.
Myslel jsem si že už jsem to od tebe někde viděl. Je to ale u všech prohlížečů?
Fibi
Profil
No to by samozřejmě bylo nejlepší, ale to je právě to, co mi ani zaboha nešlo.
Prostě funkce pověšená na té události nebyla ochotná čekat na dokončení AJAXového požadavku.


Chamurappi:
Aha to je ode mně nepřesné.
Já provádím dvě kontroly, první, která jen kontroluje jestli jsou kolonky OK ve smyslu email má zavináč apod.
A když tahle kontrola dopadne OK, zapíšu si do proměnné navrat hodnotu true.
A následně, když mám splněno že navrat == true, tak teprve začínám ten problematický požadavek.
Zkoušel jsem to pověsit na OnSubmit a když proběhne vše OK, dát odeslat formulář, ale dostanu se do smyčky :-(
Keeehi
Profil
Na onsubmit by se měl provést takovýto kód.
if (checked == true) {
    return true;
}

// kontrola
// volání ajaxu

return false;

Při obdržení dat z AJAX dotazu
if(bylo to ověřeno) {
    checked = true;
    formulář.submit()
}
Chamurappi
Profil
Reaguji na Fibiho:
Mimochodem, není trochu krkolomné posílat na server data z formuláře za účelem zjištění, jestli se smí odeslat na server data z formuláře? Kontrola AJAXem by mi dávala větší smysl, kdyby byla průběžná, ne až v okamžiku odeslání.

když proběhne vše OK, dát odeslat formulář, ale dostanu se do smyčky :-(
Pochybuji.


Reaguji na Keeehiho:
Je to ale u všech prohlížečů?
Jsem si tím celkem jistý. Ale rozsáhlé testy jsem neprováděl a sám používám vždy onsubmit, protože mi to přijde normálnější.

Na onsubmit by se měl provést takovýto kód.
Při odeslání formuláře metodou submit() se nevyvolává událost onsubmit. Nevím tedy, co s tím přesně dělá jQuery, ale nečekal bych, že toto opravuje.
Fibi
Profil
Chamurappi:
Ano je to trochu krkolomné, souhlasím.
Tam je důvod skryt v tom, že si před odesláním formuláře ještě ověřuji na serveru, jestli je v rezervovaném objektu volno, i když ta šance na obsazení je malá. A tahle kontrola, právě může někdy selhat/trvat velmi dlouho z důvodu zatížení cílové DB. Takže když to trvá moc dlouho, radši to risknu a rezervaci pošlu dál, aby mi to uživatelé nezkoušeli stokrát za sebou jak jsem nedávno zaznamenal :-)

Ohledně toho co vyvolá submit v jquery.
Při použití jquery opravdu submit na fomuláři vyvolá událost OnSubmit, kdežto v čistém JS se tak neděje.

Tedy názorně :
function kontrola(formular) {
    alert('Kontrola');
    $(formular).submit();
    return false ;
}
Tento kód bude donekonečna zobrazovat Alert "Kontrola".

function kontrola(formular) {
    alert('Kontrola');
    var formik = document.getElementById('id_formulare');
    formik.submit();
    return false ;
}
A tento kód jednou zobrazí alert "Kontrola" a pak formulář odešle.

To jen tak pro přenost.
A to je také důvod proč jsem se opravdu dostal do smyčky :-)
Každopádně teď už mi to funguje jak má, takže všem velice děkuji za rady.
Nakonec to nebylo tak těžké, klíčové bylo vždy vracet události onsubmit false a odeslání zajistit pomocí funkce submit přímo, použil jsem jquery a radu [#10] Keeehi .

Vaše odpověď

Mohlo by se hodit

Neumíte-li správně určit příčinu chyby, vkládejte odkazy na živé ukázky.
Užíváte-li nějakou cizí knihovnu, ukažte odpovídajícím, kde jste ji vzali.

Užitečné odkazy:

Prosím používejte diakritiku a interpunkci.

Ochrana proti spamu. Napište prosím číslo dvě-sta čtyřicet-sedm: