Autor Zpráva
anonym_
Profil *
Ahoj,

peru se s následujícím kódem, který mi z nějakého důvodu občas nefunguje. Nějak nemůžu přijít na to, proč.

Můj kód:

for (var i = 0; i < rows.length; i++) {
    var row = $(rows[i]);

    if (row.find('[name="item[]"]').val() !== '') {
        items.push({
            name: row.find('[name="item[]"]').val(),
            date: row.find('[name="date[]"]').val(),
            time: row.find('[name="time[]"]').val()
        });
    }
}

console.log(items + 'xx'); // vůbec se neprovede, konzole je prázdná... ani to "xx" tam není :-(

$.ajax({
    url: '/ajax.php?type=order&ajax=1',
    method: 'POST',
    data: {
        name: $('#name').val(),
        items: items
    }
})

Pokud je položek více, proměnná items se odešle až na druhý klik na odesílací tlačítko. Jako kdyby se ten $.ajax zavolal dříve, než se naplní pole items.

Pro jednu položku to fungovalo dobře.

Když jsem přidal console.log, tak se mi zdá, že se data na server předají i při více položkách (nevím, jak bych ověřil, zda tomu tak je vždy, při několika testovacích objednávkách se data na server dostala, ale to je takové... neprůkazné). Jako kdyby se ten AJAX tady zdržel a měl pak data k dispozici. Divné ale je, že je konzola prázdná...

Přehlížím něco?
Díky.


Tak opravuji, konzola se propisuje dobře, měl jsem tam po aktualizaci prohlížeče zaškrtnuté jen "chyby", nikoliv "vše".

Každopádně fakt, že pokud tam console.log je, data se na server pošlou hned, a pokud chybí, pošlou se až na druhý pokud, trvá.
Kajman
Profil
items je definovano v jakém kontextu?
anonym_
Profil *
Kajman:
Teď nevím, jestli ti rozumím úplně dobře :-)

var items = [];

Těsně nad tím for cyklem. Mohl jsem tam ten řádek přidat. Divné je, že to hapruje jen při vícepoložkových objednávkách, a to ještě jen někdy. Po přidání console.log jsem už problém nepozoroval při několika testovacích pokusech, ale to neznamená, že není (vložení nesouvisejícího kódu jako řešení problému neberu) :-) Proto se mé myšlenky stáčely k tomu, jestli se nemůže AJAX vykonat dříve, než se to pole naplní, než se projdou ty jednotlivé položky. Jednopoložkové se propsaly snad všechny (alespoň ty, o kterých vím), s kontextem proměnné (že by to padalo na tom, že není deklarovaná) by být neměl.
Keeehi
Profil
anonym:
Spíš bych čekal, že v proměnné rows není to co čekáš, že tam je. Takže ten cyklus vygeneruje něco jiného než si myslíš že by generovat měl.
anonym_
Profil *
Keeehi:
Mělo by tam být to, co tam být má.

Scénáře, které nastaly:
- pokud pošlu jednu položku, v proměnné je to, co tam má být (ty objednávky se poslaly vždy, alespoň ty, o kterých vím)
- pokud pošlu více položek, v proměnné není občas nic, občas tam je těch více položek
- pokud pošlu více položek a v proměnné není nic, stačí druhý stisk buttonu (bez dalších úprav ve formuláři) a v proměnné je to, co tam má být

JS je v době zpracování 100% načtený celý, protože formulář se pomocí JS zobrazuje (a řádky klonují).

To zvýrazněné občas nechápu, kdy k němu dochází. Vstup je vždy stejný (hodnota se může pochopitelně lišit, ale zadává se stejným způsobem) a zadávají ho pověření lidé, kteří jsou proškoleni - jedná se o select, kdy je nejprve jeden, ale mohou vzniknout další pomocí .clone. K tomu jsou další textová pole, která se neklonují (jméno, telefon, adresa, ...), ale ty problém nedělají, ty se pošlou vždy.

Situace, kdy by někdo testoval možnosti systému, zkoušel modifikovat JS nebo HTML, jsou vyloučené. Jedná se o interní systém pro netechnické uživatele. Navíc se chyba občas projevila i mně.
Keeehi
Profil
anonym:
Kde se tedy rows bere?
anonym_
Profil *
Keeehi:
Proměnná rows se bere o řádek výše. Nepovažoval jsem to za nutné ji zmiňovat, když to občas funguje, čili že je definovaná správně :-)

Takhle vypadá celá ta funkce. Na formuláři je klasicky onsubmit="return check_form(this)".

function check_form(el) {
    var form = $(el);
    var inputs = form.find('input');

    for (var i = 0; i < inputs.length; i++) {
        var input = $(inputs[i]);

        if (input.attr('type') === 'text' || input.attr('type') === 'mail') {
            // pokud neni pole vyplnene, nebo nema spravny format, priradi se labelu class=error
            check_empty_value(input, input.val());
        }
    }

    var service_inputs = $('.row [name="service[]"]');
    for (var i = 0; i < service_inputs.length; i++) {
        if ($(service_inputs[i]).val() === '') {
            $(service_inputs[i]).next('.srctop').addClass('error');
        }
    }

    // pokud je nektere pole spatne vyplnene, zobraz error
    if (form.find('label.error').length >= 1) {
          form.find('span.error').text('Prosíme, vyplňte chybějící údaje').animate({opacity: 1}, 300);
    } else {
        // vse spravne vyplneno

        // disabled na button kvuli dblclicku
        $('button').prop('disabled', true);

        var rows = $('.row');
        var items = [];

        // naplneni items
        for (var i = 0; i < rows.length; i++) {
            var row = $(rows[i]);

            if (row.find('[name="service[]"]').val() !== '') {
                items.push({
                    name: row.find('[name="service[]"]').val(),
                    date: row.find('[name="date[]"]').val(),
                    time: row.find('[name="time[]"]').val()
                });
            }
        }

        console.log(items);

        $.ajax({
            url: '/ajax.php?type=reservation&ajax=1',
            method: 'POST',
            data: {
                name: $('#name').val(),
                phone: $('#phone').val(),
                mail: $('#mail').val(),
                message: $('#message').val(),
                items: items
            }
        }).done(function(data) {
            if (data === 'success') {
                $('#msg').text('Uloženo');
            } else if (data === 'error') {
                // tohle jsem pridal ted, aby uzivatel videl alespon hlasku, ze se formular neodeslal

                // umozni znovu kliknout na button a odeslat formular
                $('button').prop('disabled', false);
                $('span.error').text('Odeslání formuláře se nezdařilo.').animate({opacity: 1}, 300);

                console.log('error');
            }
        });
        // zkousel jsem pridat i FAIL event, ale do toho to nepadalo. AJAX se provede vzdy, jen obcas bez dat ze seelctu, cili v .DONE(), na serveru pak vracim bud 'success' nebo 'error'
    }

    return false;
}
Kajman
Profil
A žádný jiný javascript nemění obsah v .row?

Jinak je divné, že občas pracujete s řádky v celém dokumentu (nastavení erroru při prázdném service[] a odeslání) a občas pracujete jen s řádky uvnitř form elementu (kontrola, zda tam není nějaký error). Ale to by spíš mělo být v items více věcí než méně.

Také pozor na podmínku row.find('[name="service[]"]').val() !== '', kdy val pro nenalezenou sadu elementu vrací undefined, proto se to nerovná prázdné hodnotě, stejně, jako by byla vyplněná. Tady bych vypustit !== ''. Ale také zde platí, že v items by naopak mělo být více řádků (i když s nedefinovanými hodnotami).
anonym_
Profil *
Kajman:
Ne, žádný jiný js v této oblasti není, jen tento.

Element service[] je přítomny vždy, a buď hodnotu má (byla skrze js vložena), nebo je prázdný (defautlni stav, nic nebylo vybráno, tedy chyba). Elementy .row jsou jen v rámci tohoto formu, tam mas pravdu, ze je nekonzistence v selektorech, ale to na věc nemá vliv. Jsou to stále tytéž elementy.

Jinak dodám, ze v kódu mám stále přidany ten console.log a s nim se formulář odeslal vždy korektně. Koukal jsem do kódu znovu a znovu s odstupem, ale fakt to pořad nechápu. A spokojit se s tím, ze tam ten log nechám, mi přijde hloupé (nevadi mi, ze se něco píše do konzole, ale ze to je absurdní a není to řešení toho problému, který se děje/děl).
Kajman
Profil
anonym:
Ne, žádný jiný js v této oblasti není, jen tento.

buď hodnotu má (byla skrze js vložena)

To si přece odporuje.
anonym_
Profil *
Kajman:
Pardon. Není žádný, který by to měnil obsah .row. Hodnota se dosahuje jednoduchým onchangem v selectu.

Kód, který jsem uvedl výše, je ten, který je relevantni. Jiné js samozřejmě jsou, ale s těmi problém není. Na 100%.

Asi se nedobereme výsledku, ten js výše se zda být asi ok. Tak to zkusím kdyžtak nějak přepracovat a ponořit se do toho znovu poradně :-)
anonym_
Profil *
Podstatne je, ze jsem hned na začátku psal, ze to většinou funguje a jen někdy ne. Tzn. data se tam předávají správně, jinak by to nefungovalo nikdy.

Moje idea byla, jestli ten ajax neprobehne dříve, než ta data dostane. Za nějakých okolnosti, které přehlížím. Ale asi ne, protože byste to viděli vy, když ne já :-)

Hledat v tomhle vláken syntaktické nebo podobne chyby je tudíž zbytecne. Stejně tak chyby třeba v ošetření vstupu, při stejném způsobu zadání to někdy proběhne, jindy ne. Tam tedy chyba také není.

Ale jak jsem psal, dat si od toho oddych (teď jsem do toho teda par dni nekoukal), mrknu na to s odstupem a když nic nevymyslím, zkusím to přepsat, nebo s tím něco udělat.

Díky vám oběma za vás čas.
Kajman
Profil
Když bude items prázdné a rows neprázdné, může se na server poslat logovací požadavek, kde bude např. identifikace prohlížeče a další informace, co mohou pomoci najít rozdíly ve stavech, kdy se to podaří a kdy ne.
anonym_
Profil *
Kajman:
To zní jako dobrý nápad. Sice na prohlížeči to primárně nezávisí (mě se povedlo ze stejného browseru na stejném stroji při stejném nastavení odeslat i neodeslat), ale třeba nějakou anomalii najdu :-)

Díky.
blaaablaaa
Profil
Pak si na server loguj kazdy krok skriptu, abys dokazal dohledat, co a proc se deje.
_es
Profil
Funkcia v .done(... sa ti zavolá, až keď server vráti dáta, vtedy už funkcia check_form dávno skončila. Môže nastať situácia, že požiadavky na server nebudú vrátené v takom poradí, v akom boli zavolané. Keď ešte k tomu meníš funkčnosť tlačítka počas toho, ako sa naň kliká, môže byť znefunkčnené predtým, než sa stihlo kliknúť. Celé to nejako zjednoduš, aby ti bolo jasné, kedy sa ktorý kus kódu vykoná, nie hentaký „špagetový“ kód.
anonym_
Profil *
_es:
Funkcia v .done(... sa ti zavolá, až keď server vráti dáta, vtedy už funkcia check_form dávno skončila.
Ano, to je pravda. A? Nechápu, kam tím míříš, nikdo nikde netvrdí opak.

Keď ešte k tomu meníš funkčnosť tlačítka počas toho, ako sa naň kliká, môže byť znefunkčnené predtým, než sa stihlo kliknúť.
To určitě ne. Tlačítko je disabled v momentě, kdy se ta funkce zavolá. Čili po kliku na button (nikoliv v průběhu klikání, než před klikem), nebo odeslání formuláře jinou metodou. Nedovedu si představit situaci, kdy by se tlačítko disablovalo dříve.

Celé to nejako zjednoduš, aby ti bolo jasné, kedy sa ktorý kus kódu vykoná
Já si myslím, že mi to jasné je, kdy se který kus kódu vykonává.

Jinak i tobě děkuji za reakci, kde jsem se sice nedozvěděl nic nového, ale i tak dík (jestli jsem něco nepřehlédl mezi řádky) :-) Informace od kolegů výše mi byly nápomocnější, ještě jednou děkuji všem zúčastněným. Mrknu na to.
_es
Profil
anonym:
console.log(items + 'xx'); // vůbec se neprovede, konzole je prázdná... ani to "xx" tam není :-(
No keď tam nič není, asi sa kód nevykonáva vtedy, keď si myslíš. Čo očakávaš od výsledku pole + "xx"? Aby si mal lepší prehľad, použi namiesto console.log funkciu alert alebo sa nauč lepšie pracovať s debuggerom.
Nemáš poriadnu kontrolu nad tým znefunkčňovaným tlačítkom a ďalšími vecami, čo keď server úspešne nevráti text "succes" alebo "error" napríklad vráti niečo iné alebo nevráti nič?
Nemáš tam nejaké ďalšie JS kódy na menenie formulárových polí či formulára, ktoré by to komplikovali?
Nenastáva trebárs menenie elementov formulára až po udalosti jeho odoslania a pod.?
Nenastáva udalosť odoslania formulára aj inokedy ako si myslíš, napríklad enterom na nejakom formulárovom poli?
Tipol by som si, že je formulár odoslaný, možno len niekedy, priskoro a nejaké dynamické generovanie elementov formulára nastáva až neskôr.
anonym_
Profil *
_es:
Sorry, na tohle reagovat nebudu. Přečti si to, co bylo napsáno výše (konkrétně ten console.log se vypíše vždy, jen jsem se překoukl). Nebo raději nereaguj, pokud chceš být ofenzivní a nekonstruktivní.

Odpovědi na tvoje dotazy začínající "Nenastává/nemáš": Ne, nenastává/nemám, viz výše.
Formulář je odeslaný vždy, ale to jsem taky psal.

Debata ubírající se tímhle stylem mě nebaví, co jsem potřeboval vědět, jsem se dozvěděl od kolegů. Ještě jednou děkuji všem za účast a tímto bych to uzavřel. Díky.
_es
Profil
anonym:
No ako myslíš, snažil som sa pomôcť, asi bude chyba inde, než v tom kóde, čo si tu dal, možno by pomohla živá ukážka.

JS je v době zpracování 100% načtený celý, protože formulář se pomocí JS zobrazuje (a řádky klonují).
To zvýrazněné občas nechápu, kdy k němu dochází.
Ako som už písal, tipujem, že to „klonovanie“ je („občas“) až po odoslaní formulára, môže to závisieť od toho, na čo sa klikne, či aká klávesa sa stlačí a pod. Alebo ak je to „klonovanie“ závislé od nejakej odpovede servera a nemáš ošetrené čakanie na odpoveď, tak je už možno problém odhalený.
anonym_
Profil *
_es:
Promiň, vymýšlíš konstrukty, které nenastavaji a je fakt zbytecne se jimi zabývat (klonování nemá s odesláním nic společného, k odeslání dojde vždy (a ne jen někdy), vždy je odpoved serveru success/error, jiný js chybu způsobovat nemůže, atd). Kod, který jsem zde uvedl, je maximálně separovany a musí se pracovat jen s nim.

Živou ukázku nevím, jak bych ti připravil, když se bavíme o ajaxovem volání, ale fakt to nechme. I tobě dekuji za snahu pomoci a omlouvám se, pokud jsem reagoval moc příkře. Každopádně tvé rady jsou o několik znalostních levelu níže, než bych potřeboval (ve smyslu, ze předpokládás, ze mám nějakou banální chybu jinde, což 100% nemám. Rozhodne tím necílim na tvoje js schopnosti a znalosti, to bych si nedovolil).

Zacal jsem to důkladně logovat a uvidim, co zjistím. Pokud něco, dam vědět, protože to je pro mě docela záhada (pro mě coby člověka, který se kolem js nějakým způsobem 10 let potlouka, byť nejsem plnouvazkove js vývojář).

Ještě jednou díky, vážím si snahy všech.
_es
Profil
anonym:
Nejako si odporuješ, píšeš, že iný kód to spôsobovať nemôže, pritom tvrdíš, že dynamicky do formulára cez JS pridávaš ďalšie elementy a práve tie dynamicky vytvorené elementy sa ti občas neodosielajú (ak som tomu správne porozumel). Pritom si neprezradil, ako formulár odosielaš, ani ako a kedy dynamicky pridávaš formulárové prvky. Logicky by som predpokladal problém tam. Píšeš, že opakované odoslanie formulára je už správne, takže mi z toho logicky vyplýva, že pri prvom odoslaní bol formulár odoslaný predčasne. Funkcia check_form v sebe nijaké náhodné chovanie neobsahuje, čiže problém musí byť niekde inde.

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:

0