addCheckboxList s AJAX nepřenese hodnoty

admin@easyweb4u.cz
Backer | 143
+
0
-

Asi mě nakopete, nemůžu vyřešit úplnou blbost, navíc mi ten addCheckboxList fungoval v trochu jiné logice, od které jsem pak upustil…

mám service

<?php
    public function showVariety($sortimentid) {

        $variety = [];

				$categoryid = 0;

				$row = $this->database->table('sortiment_1')->get($sortimentid);

				$categoryid = $row['categoryid'];

				// navazane na kategorii
        $select = $this->database->table('variety_1')->where('categoryid', $categoryid)->order('ord')->fetchAll();

        if ($select != null) {

					foreach ($select as $s) {

							$variety[$s->id] = $s->variety;

					}

				}

        return $variety;
    }

		public function defaultVariety($sortimentid) {

        $default = [];

        $select = $this->database->table('variety')->where('sortimentid = ?', $sortimentid)->fetchAll();

        if ($select != null) {

					foreach ($select as $s) {

							$default[] = $s->varietyid;

					}

        }

        return $default;

    }
?>

v presenteru pak

<?php
$this->sortimentid = intval($this->request->getParameter('sortimentid'));

$this->variety = $this->sortiment->showVariety($this->sortimentid);

$this->default = $this->sortiment->defaultVariety($this->sortimentid);
?>

a dále formulář

<?php

	protected function createComponentVarietyForm() {

		$form = new Form;

		$form->addProtection();

		$form->addHidden('sortimentid');

		$data = [];

		if ($this->variety != null) {

			$data = $this->variety;
		}

		$form->addCheckboxList('variety', 'Varianty:', $data)
						->setAttribute('class', 'check');

		if ($this->default != null) {

			$form->setDefaults([
					'sortimentid' => $this->sortimentid,
					'variety' => $this->default,
			]);

		} else {

			$form->setDefaults([
					'sortimentid' => $this->sortimentid
			]);
		}

		$form->addSubmit('send', 'Změnit')
						->setAttribute('class', 'btn btn-success');

		$form->getElementPrototype()->class('ajax');

		$form->onSuccess[] = [$this, 'varietyFormSucceeded'];

		return $form;
	}

	public function varietyFormSucceeded($form, $values) {

		if (!$this->isAjax()) {

			$this->flashMessage('Error');
		} else {

			try {

				$select = $this->database->table('variety')->where('sortimentid', $values->sortimentid)->fetchAll();

				if ($select != null) {

					$delete = $this->database->table('variety')
									->where('sortimentid', $values->sortimentid)
									->delete();
				}

				if ($values->variety != null) {

					foreach ($values->variety as $v) {

							$this->database->query('INSERT INTO variety', [
									'varietyid' => $v,
									'sortimentid' => $values->sortimentid,
							]);
					}

					$this->flashMessage('Editace variant byla úspěšná.');

				} else {

					$this->flashMessage('No action! ');
				}

			} catch (Exception $e) {

				echo 'Caught exception: ', $e->getMessage(), "\n";
			}
		}

		$this->redrawControl('flashesAdmin');
	}
?>

Hodnota $values->variety je prázdná, ale pokud do funkce

$this->variety = $this->sortiment->showVariety(6);

zadám natvrdo hodnotu pro příslušný sortiment, hodnoty se přenesou a normálně zapíšou do databáze. Ono to po odeslání formuláře znovu volá funkci

$this->variety = $this->sortiment->showVariety($this->sortimentid);

ale $this->sortimentid je 0. Proboha proč?

V laděnce vidím
method private ⇒ „POST“
url private =>
post private =>
variety =>
0 ⇒ „11“
1 ⇒ „10“
2 ⇒ „36“
_token_ ⇒ „u1sl0aki6nWhgSzlhMdcSWNcgHVShLiLuhy60=“
sortimentid ⇒ „6“
_do ⇒ „varietyForm-submit“
send ⇒ „Změnit“

i když $this->sortimentid nemám zadané natvrdo

Díky

Editoval admin@easyweb4u.cz (13. 4. 2020 19:12)

F.Vesely
Člen | 368
+
+1
-

A kde v Presenteru to volas? Poradi je totiz action, form onSuccess, render viz https://doc.nette.org/…n/presenters#…

admin@easyweb4u.cz
Backer | 143
+
0
-

Ty funkce ze service volám ve startup(). Ono to ale nefunguje i když kód vrazim rovnou do formuláře. Divný je, že v httpRequest to pole z addCheckboxList vidim, sortimentid vidim, ale do successFrom příjde pole prázdné, sortimentid je OK. A navíc se jakoby znova volá ten formulář, ale se sortimentid = 0 … ten formulář se na začátku zobrazí správně. Není to něco s headers sent?

Editoval admin@easyweb4u.cz (14. 4. 2020 10:11)

F.Vesely
Člen | 368
+
0
-

Jak ma vlastne fungovat to sortimentId?

Pokud se ti do formulare dostavaji data podle sortimentId, tak by to mel byt parametr pro akci, neco jako:

final class FooPresenter extends Nette\Application\UI\Presenter
{
	private $sortimentId;

	public function actionDefault($sortimentId)
	{
		// overeni, zda sortimentId existuje a kdyztak vypsat hlasku, presmerovat, vyhodit 404, ...

		$this->sortimentId = $sortimentId;
		// pripadne nacteni dalsich dat podle $sortimentId
	}
}

Pak uz nemusis mit ve formulari hiddenInput pro sortimentId a slozite ho nastavovat. Pri vytvareni i zpracovani formulare sahas jen na $this->sortimentId.

admin@easyweb4u.cz
Backer | 143
+
0
-

F.Vesely napsal(a):

Jak ma vlastne fungovat to sortimentId?

Pokud se ti do formulare dostavaji data podle sortimentId, tak by to mel byt parametr pro akci, neco jako:

final class FooPresenter extends Nette\Application\UI\Presenter
{
	private $sortimentId;

	public function actionDefault($sortimentId)
	{
		// overeni, zda sortimentId existuje a kdyztak vypsat hlasku, presmerovat, vyhodit 404, ...

		$this->sortimentId = $sortimentId;
		// pripadne nacteni dalsich dat podle $sortimentId
	}
}

Pak uz nemusis mit ve formulari hiddenInput pro sortimentId a slozite ho nastavovat. Pri vytvareni i zpracovani formulare sahas jen na $this->sortimentId.

No já nevím, jestli si zrovna tímhle pomůžu (zkusím). Takže, když volám ten presenter z šablony linkem <a n:href="… a v parametru mám sortinentid, přijde automaticky jako argument funkce actionDefault? Potom bych nemusel volat $this->sortimentid = intval($this->request->getParameter(‚sortimentid‘)); jak to mám ve startup() (mně ale tyhle konstrukce běžně fungují.)? Mně spíš přijde, že tam dochází k nějakýmu opakovanýmu načítání toho formuláře.

Editoval admin@easyweb4u.cz (14. 4. 2020 12:38)

admin@easyweb4u.cz
Backer | 143
+
0
-

admin@easyweb4u.cz napsal(a):

F.Vesely napsal(a):

Jak ma vlastne fungovat to sortimentId?

Pokud se ti do formulare dostavaji data podle sortimentId, tak by to mel byt parametr pro akci, neco jako:

final class FooPresenter extends Nette\Application\UI\Presenter
{
	private $sortimentId;

	public function actionDefault($sortimentId)
	{
		// overeni, zda sortimentId existuje a kdyztak vypsat hlasku, presmerovat, vyhodit 404, ...

		$this->sortimentId = $sortimentId;
		// pripadne nacteni dalsich dat podle $sortimentId
	}
}

Pak uz nemusis mit ve formulari hiddenInput pro sortimentId a slozite ho nastavovat. Pri vytvareni i zpracovani formulare sahas jen na $this->sortimentId.

No já nevím, jestli si zrovna tímhle pomůžu (zkusím). Takže, když volám ten presenter z šablony linkem <a n:href="… a v parametru mám sortinentid, přijde automaticky jako argument funkce actionDefault? Potom bych nemusel volat $this->sortimentid = intval($this->request->getParameter(‚sortimentid‘)); jak to mám ve startup() (mně ale tyhle konstrukce běžně fungují.)? Mně spíš přijde, že tam dochází k nějakýmu opakovanýmu načítání toho formuláře.

Tak jsem udělal tu actionDefault($sortimentid) a funguje to. Kdo by to byl řek… Díky kámo. Tak jsem to 3 roky dělal blbě? Lze vůbec inicializovat proměnné ve startup()? Když bych inicializaci přesunul do actionDefault, k čemu pak používat startup()?

Editoval admin@easyweb4u.cz (14. 4. 2020 17:43)

F.Vesely
Člen | 368
+
+1
-

startup() je volan tesne pred action*(), takze teoreticky v nem inicializovat promenne muzes. Je lepsi to ale delat v action metode pres parametr, protoze Nette ti i hlida, aby ten parametr byl v requestu, pokud neni nepovinnej. Taky ti hlida i jeho typ.

Navic ve startup by mel byt kod, ktery je pro cely Presenter. Osobne startup moc nepouzivam.

U tebe byl podle me problem, ze jsi mel stejne pojmenovany parametr v GET i POST promennych a nejak sis ho tam prepisoval.

admin@easyweb4u.cz
Backer | 143
+
0
-

F.Vesely napsal(a):

startup() je volan tesne pred action*(), takze teoreticky v nem inicializovat promenne muzes. Je lepsi to ale delat v action metode pres parametr, protoze Nette ti i hlida, aby ten parametr byl v requestu, pokud neni nepovinnej. Taky ti hlida i jeho typ.

Navic ve startup by mel byt kod, ktery je pro cely Presenter. Osobne startup moc nepouzivam.

U tebe byl podle me problem, ze jsi mel stejne pojmenovany parametr v GET i POST promennych a nejak sis ho tam prepisoval.

Jo jo, tomu rozumím. Podle mě byl problém v

$this->sortimentid = intval($this->request->getParameter(‚sortimentid‘));

já jsem hledal metodu postParameter(), ale nenašel. Formuláře jsou přitom POST. Tak jsem usoudil, že metoda getParameter je univerzální. Pletu se nebo ne? Metoda getParameter() vlastně chytá parametry z linků, to by bylo v pořádku, ale když se odešlou hodnoty z formuláře metodou POST, tak to asi způsobilo tu nefunkčnost. Ještě jednou dík :-)

Editoval admin@easyweb4u.cz (15. 4. 2020 11:14)

dakur
Člen | 493
+
0
-

@adminaeasyweb4ucz K těm by ses měl dostat přes $this->request->getPost('sortimentId') (je to teda trochu divný název)

Editoval dakur (15. 4. 2020 14:26)

dakur
Člen | 493
+
0
-

@adminaeasyweb4ucz Jinak teda z presenteru je lepší přistupovat k hodnotám z formuláře vyšší vrstvou. Form je podkomponentou presenteru a checkbox list zase podkomponentou formu, takže v presenteru se k tomu přes $this->getComponent('varietyForm')->getComponent('sortimentId')->getValue() dostaneš a máš ošetřené, že tam někdo nevložil nějakou hodnotu, kterou jsi v addCheckboxList() vůbec nedefinoval. Zkráceně lze také $this['varietyForm']['sortimentId']->getValue() – záleží, zda preferuješ kratší zápis nebo typovost.

Editoval dakur (15. 4. 2020 14:26)

admin@easyweb4u.cz
Backer | 143
+
0
-

dakur napsal(a):

@adminaeasyweb4ucz Jinak teda z presenteru je lepší přistupovat k hodnotám z formuláře vyšší vrstvou. Form je podkomponentou presenteru a checkbox list zase podkomponentou formu, takže v presenteru se k tomu přes $this->getComponent('varietyForm')->getComponent('sortimentId')->getValue() dostaneš a máš ošetřené, že tam někdo nevložil nějakou hodnotu, kterou jsi v addCheckboxList() vůbec nedefinoval. Zkráceně lze také $this['varietyForm']['sortimentId']->getValue() – záleží, zda preferuješ kratší zápis nebo typovost.

Rozumím tomu tak, že:

<?php
public function varietyFormSucceeded(UI\Form $form) {

// nepoužiju v argumentech $values a

$values = $this->getComponent('varietyForm')->getComponent('sortimentId')->getValue(); // nebo zkrácený zápis

}
?>

Je to tak? Nebo $values získávám někde mimo varietyFormSucceeded()? Spíš teda vlastně

$sortimentId = $this->getComponent(‚varietyForm‘)->getComponent(‚sortimentId‘)->getValue();

Editoval admin@easyweb4u.cz (24. 4. 2020 11:38)