Formulářové checkboxy vracejí jen false

grovik
Člen | 54
+
0
-

Mám takový problém.
Mám formulář kde je poměrně hodně checkboxů.
Když ho odešlu, tak všechny ostatní pole se odešlou v pořádku, ale chceckbox se bez ohledu na zaškrtnutí se to vrací jako false.
Jde to dokonce tak daleko, že zaškrtávátko na GDPR, které musí být zaškrtnuté, tak i když se zaškrtne stále se chová jako nezaškrtnuté.

hodím sem zdroják, to co je zakomentované jsou věci, které jsem vyhodil kvůli testování. Problémy jsem prostě v těch Checkboxech.

protected function createComponentContactsForm(): Form
{
    $form = new Form;
    $locales = new Locale($this->database);

    $form->addGroup('Rizika');
    $form->addCheckbox('pracovnineschopnost');
    $form->addCheckbox('krytihypoteky');

    $form->addCheckbox('invalidita');

    $form->addCheckbox('urazy');

    $form->addCheckbox('hospitalizace');

    $form->addCheckbox('smrt');

    $form->addCheckbox('ostatni');

    $form->addCheckbox('zavaznaonemocneni');

    foreach ($locales->getLocale() as $hodnoty){

            $polelocale[$hodnoty->locale_id] = $hodnoty->locale_name;
         }
    $form->addGroup('Lokalita');
    $form->addSelect('locale', 'Oblast:', $polelocale)
         ->setRequired('Vyberte prosím oblast.')
         ->setPrompt('--- vyberte oblast ---')
         ->addCondition(Form::FILLED)
         ->addRule(Form::INTEGER, 'Vyberte platnou oblast.');
    $form->addGroup('Kontakt');
    $form->addText('phone', 'Telefonní číslo:')

       //->addRule(Form::PATTERN, 'Telefonní číslo není platné', '/^[1-9][0-9]{8}$/')
       // ->addRule(function ($control) {return Validators::isNumericInt($control->getValue()) && Validators::length($control->getValue(), 9, 9);}, 'Telefonní číslo není platné.')
       //->addRule(function ($control) {return preg_match('/^[1-9][0-9]{8}$/', str_replace([' ', '-', '/'], '', $control->getValue()));}, 'Telefonní číslo není platné.')
       ->addCondition(Form::FILLED);


    $form->addText('email', 'Email:')
        ->setHtmlAttribute('class', 'inputform')

        ->addRule(Form::EMAIL, 'Zadejte prosím platnou emailovou adresu.')
        ->addCondition(Form::FILLED);



        $form->addCheckbox('gdpr', Nette\Utils\Html::el('a')->href('https://liveproperty.cz/home/gdpr')
            ->setText('Souhlasím s podmínkami a GDPR'), ['gdpr' => 'Souhlasím s podmínkami a GDPR'])
            //->setRequired('Je potřeba souhlasit s podmínkami a GDPR');
      ;
    $form->addHidden('form_name')
         ->setDefaultValue($this->getAction());
    $form->addSubmit('submit', 'Odeslat');
/*
    $form->addButton('prev', 'Předchozí')
         ->setHtmlAttribute('class', 'btn btn-primary prev-step');
         //->setValidationScope(NULL);
    $form->addButton('next', 'Další')
         ->setHtmlAttribute('class', 'btn btn-primary next-step');


    $renderer = $form->getRenderer();
    $renderer->wrappers['controls']['container'] = 'div class=form-group';
    $renderer->wrappers['pair']['container'] = NULL;
    $renderer->wrappers['label']['container'] = 'div class="form-group"';
    $renderer->wrappers['control']['container'] = 'div class="form-group"';
*/

    $form->onSuccess[] = [$this, 'contactsFormSucceeded'];
    $form->onError[] = function($form){
        bdump($form->getErrors());
    };

    bdump($form);
    return $form;
}

Tohle vypadne z formuláře:

`Nette\Utils\ArrayHash
pracovnineschopnost: false
krytihypoteky: false
invalidita: false
urazy: false
hospitalizace: false
smrt: false
ostatni: false
zavaznaonemocneni: false
locale: 3
phone: ‚774472939‘
email: ‚aro@jnc.cz'
gdpr: false
form_name: 'zivotnipojisteni‘`

Editoval grovik (20. 6. 2023 11:49)

m.brecher
Generous Backer | 763
+
0
-

@grovik

ale chceckbox se bez ohledu na zaškrtnutí se to vrací jako false

Jestli je testovací výstup tak jak máš v ukázce kódu:

protected function createComponentContactsForm(): Form
{
    // .....

    bdump($form);
    return $form;
}

tak potom dump proměnných nezobrazuje věrně submitnuté $values formuláře. Odeslaná data formuláře jsou k dispozici až v další fázi životního cyklu. Je to z bezpečnostních důvodů.

Otestuj odeslaná data formuláře až v události formuláře onRender tímto způsobem:

protected function createComponentContactsForm(): Form
{
   // .....
        $form->onRender[] = fn(Form $form) => bdump($form->getUntrustedValues());  // getUntrustedValues() jen kvůli testování !!

    return $form;
}

pro testování použij getUntrustedValues(), abys viděl i nevalidní data, ale v produkci toto nikdy nepoužívej, používej bezpečné getValues()

Editoval m.brecher (20. 6. 2023 12:25)

grovik
Člen | 54
+
0
-

Takže musím použít getValues() abych dostal stavy těch formulářů. OK.
A co ten GDPR co by se měl zaškrtnout a bez něj by to nemělo jít odeslat?

m.brecher
Generous Backer | 763
+
0
-

@grovik

A co ten GDPR co by se měl zaškrtnout a bez něj by to nemělo jít odeslat?

To tam máš – setRequired(‚…‘):

$form->addCheckbox('gdpr',
        \Nette\Utils\Html::el('a')
                ->href('https://liveproperty.cz/home/gdpr')
                ->setText('Souhlasím s podmínkami a GDPR'))
    ->setRequired('Je potřeba souhlasit s podmínkami a GDPR');
Pavel Kravčík
Člen | 1182
+
0
-

Ještě si raději nastav na produkci, aktuálně máš tracy přístupnou pro všechny: https://doc.nette.org/en/application/bootstrap ;)

grovik
Člen | 54
+
0
-

Pavel Kravčík napsal(a):

Ještě si raději nastav na produkci, aktuálně máš tracy přístupnou pro všechny: https://doc.nette.org/en/application/bootstrap ;)

Vím zapl jsem to pro teď. Jako i jiné věci… tam jsou dočasně ;-).

grovik
Člen | 54
+
0
-

m.brecher napsal(a):

@grovik

A co ten GDPR co by se měl zaškrtnout a bez něj by to nemělo jít odeslat?

To tam máš – setRequired(‚…‘):

$form->addCheckbox('gdpr',
        \Nette\Utils\Html::el('a')
                ->href('https://liveproperty.cz/home/gdpr')
                ->setText('Souhlasím s podmínkami a GDPR'))
    ->setRequired('Je potřeba souhlasit s podmínkami a GDPR');

Mám právě, jenže pokud to zapnu v tom formuláři nejde odeslat. Prostě nikdy. I když ho zaškrtnu tak prostě nejde. :-/ měl jsem za to, že to souvisí s tím stavem False na chceckboxech.

nightfish
Člen | 474
+
0
-

@grovik

  • zdrojový kód pole gdpr vypadá dost podivně: <input id="frm-contactsForm-gdpr" type="checkbox" name="gdpr[]" class="form-check-input" value=""> – zaprvé si nemyslím, že by v name měly být ty hranaté závorky, zadruhé by mohla dělat problém ta prázdná value.
  • nikde nenačítáš netteForms.js (https://doc.nette.org/…in-presenter#…), takže se ti validace provádí až na serveru a nikoliv hned v prohlížeči
nightfish
Člen | 474
+
+2
-

@grovik Používáš pro vykreslení formulář automatické renderování ({control contactsForm}) nebo manuálně renderuješ po jednotlivých polích? Pokud ano, tak jak vypadá tvá šablona? (Hlavně co se týká checkboxů, které ti nefungují.)

m.brecher
Generous Backer | 763
+
+1
-

@nightfish @grovik

@grovik Mám právě, jenže pokud to zapnu v tom formuláři nejde odeslat. Prostě nikdy.

@nightfish zdrojový kód pole gdpr vypadá dost podivně: .....

Poslal jsem správný kód gdpr checkboxu, kde jsem odstranil 3 parametr ['gdpr' => 'Souhlasím s podmínkami a GDPR'] , který tam nemá co dělat a otestoval to, tento kód funguje:

$form->addCheckbox('gdpr',
        \Nette\Utils\Html::el('a')
                ->href('https://liveproperty.cz/home/gdpr')
                ->setText('Souhlasím s podmínkami a GDPR'))
    ->setRequired('Je potřeba souhlasit s podmínkami a GDPR');

Popsané potíže zřejmě způsobuje ten 3. parametr. Pokud ne, je potřeba pátrat dál ;)

Editoval m.brecher (20. 6. 2023 15:17)

m.brecher
Generous Backer | 763
+
+1
-

@grovik

Tento kód také není správně:

$form->addSelect('locale', 'Oblast:', $polelocale)
         ->setRequired('Vyberte prosím oblast.')
         ->setPrompt('--- vyberte oblast ---')
         ->addCondition(Form::FILLED)
         ->addRule(Form::INTEGER, 'Vyberte platnou oblast.');

Nette formuláře automaticky nejprve validují required podmínku a dokud není prvek vyplněn tak se další validační pravidla neuplatní. Je tedy zbytečné přidávat ->addCondition(Form::FILLED), protože to Nette dělá automaticky. Nette navíc automaticky kontroluje, zda souhlasí odeslaná hodnota prvku select s výchozí sadou položek selectu. Takže je také naprosto zbytečné dělat nějakou podobnou kontrolu. Navíc se defaultní chování Nette a ručně doplněné mohou tlouct. Stačí to napsat takhle:

$form->addSelect('locale', 'Oblast:', $polelocale)
         ->setPrompt('--- vyberte oblast ---')
         ->setRequired('Vyberte prosím oblast.')
grovik
Člen | 54
+
0
-

Díky všem za rady.
Jdu to prozkoumat a vyzkoušet :D.
Pak dám vědět kde byl problém.

grovik
Člen | 54
+
0
-

Tak jsem zkusil variantu s getValues()

  $hodnoty = $form->getValues();

    bdump($hodnoty);

`Nette\Utils\ArrayHash
checkboxes: array (0)
pracovnineschopnost: false
krytihypoteky: false
invalidita: false
urazy: false
hospitalizace: false
smrt: false
ostatni: false
zavaznaonemocneni: false
locale: 7
phone: ''
email: ‚foto@josefnemec.cz'
gdpr: false
form_name: 'zivotnipojisteni‘`

Jak vidno Checkoboxy stále vrací FALSE a to i ten GDPR co má jako podmínku, že musí být zaškrtnutý.
Nevím co je blbě. Fakt nad tím kroutím hlavou.

getUntrustedValues() Vrátí stejný výsledek.

Ještě se to vygeneruje do HTML:

<input id="frm-contactsForm-pracovnineschopnost" type="checkbox" name="pracovnineschopnost[]" value="">

Tady je ukázka ze šablony.

<input n:name=gdpr type="checkbox" name="gdpr" class= "form-check-input" value="" />

Editoval grovik (13. 7. 2023 11:29)

Marek Bartoš
Nette Blogger | 1177
+
+2
-

name, type a value ti vyplní makro n:name

<input n:name="gdpr" class="form-check-input"/>

Když ti u formuláře nefunguje ani getUntrustedValues(), tak je čas se podívat, co ti vůbec chodí v requestu za data – $this->getHttpRequest()->getRawBody()
Udělal jsem na to i Tracy panel, co ti request/response zobrazí https://github.com/…cs/README.md#…

Editoval Marek Bartoš (13. 7. 2023 12:19)

grovik
Člen | 54
+
0
-

Marek Bartoš napsal(a):

name, type a value ti vyplní makro n:name

<input n:name="gdpr" class="form-check-input"/>

Když ti u formuláře nefunguje ani getUntrustedValues(), tak je čas se podívat, co ti vůbec chodí v requestu za data – $this->getHttpRequest()->getRawBody()
Udělal jsem na to i Tracy panel, co ti request/response zobrazí https://github.com/…cs/README.md#…

Díky vyzkouším!

getRawBody() vrací:

'pracovnineschopnost=&krytihypoteky=&invalidita=&locale=12&phone=&email=foto%40josefnemec.cz&gdpr=&form_name=zivotnipojisteni&_submit=Odeslat&_do=contactsForm-submit'

Není mi jasné proč se to vrací prázdné.
Protože reálně třeba ten gdpr prostě je zaškrtnutý což je fyzicky vidět, ale i když se kouknu do toho co se odeslalo, přes http tak je to prázdné v prohlížeči.
Fakt divné nikdy jsem se s tímhle, v takovém stavu nesetkal.

Editoval grovik (13. 7. 2023 18:32)

mystik
Člen | 292
+
+3
-

Problem je ze tam natvrdo nastavujes v sablone value="" (proc?), takze se ti pak pri odeslani nastavi value pracovnineschopnost na "".

grovik
Člen | 54
+
0
-

mystik napsal(a):

Problem je ze tam natvrdo nastavujes v sablone value="" (proc?), takze se ti pak pri odeslani nastavi value pracovnineschopnost na "".

že by? Zkusím vrátím se s výsledkem a díky.

grovik
Člen | 54
+
0
-

mystik napsal(a):

Problem je ze tam natvrdo nastavujes v sablone value="" (proc?), takze se ti pak pri odeslani nastavi value pracovnineschopnost na "".

Tak to bylo ono jsem to, ale osel.
Kéž bych dělal méně takhle blbých chyb :-) hlavně kolem toho chodím a pořád jsem si říkal jestli by to tak nemělo být.
Inu život :D. Díky moc.