Nette 2.3.8 – Multiplier a nepochop(it)e(l)né schování

Upozornění: Tohle vlákno je hodně staré a informace nemusí být platné pro současné Nette.
F.Raven
Člen | 12
+
0
-

Dobrý den,
mám komponentu, která dědí od Control. V této komponentě mám továrničku s Multiplierem.

<?php
protected function createComponentInputElement()
	{
		$that = $this;
		return new Multiplier(function($id, $control) use ($that){
			$parts = explode("XXXXX", $id);
			if(count($parts) != 2)
			{
				throw new Exception("Invalid form name - ".$id.".");
			}
			$rowId = $parts[0];
			$column = $parts[1];

			$form = new Form;
			$form->getElementPrototype()->class = "ajax";
			$form->getElementPrototype()->id = $that->getName().'-'.$that->tableName.'-'.$control->getName().'-'.$id;
			$form->addHidden('rowid', $rowId);
			$form->addHidden('column', $column);

			$component = $that->columnFormDefinitions[$column];
			$component->setDefaultValue($that->table[$rowId][$column]);
			$component->setAttribute('id', $form->getElementPrototype()->id.'-value');
			$component->setParent(NULL); // bez toho to (nefunguje) hlasí, že to už rodiče má (dumpuje to ale NULL)
			$form->addComponent($component, 'value');

			$form->addSubmit('send', 'Upravit!');
			$form->onSuccess[] = array($that, 'inputElementSubmitted');
			return $form;
		});
	}
?>

Inputy (ty co jsou v poli $that->columnFormDefinitions) si tvořím (zatím) v metodě foo.

<?php
	private function foo()
	{
		$selectBox = new SelectBox($this->loadColumns['status'].":", array(0 => 'Nový', 1 => 'Zadaný', 2 => 'Makový', 3 => 'Načerpaný', -1 => 'Storno'));
		$selectBox->setRequired('Hodnota musí být vybrána.');
		$this->columnFormDefinitions['status'] = $selectBox;

		$textInput = new TextInput($this->loadColumns['targetAmount'].":");
		$textInput->setRequired('Hodnota musí být vyplněna.');
		$textInput->addRule(Form::NUMERIC, 'Hodnota musí být celé číslo.');
		$textInput->addRule(Form::RANGE, 'Hodnota musí být mezi 0 a 600 000.', array(0, 600000));
		$this->columnFormDefinitions['targetAmount'] = $textInput;
	}
?>

V šabloně si instance Multiplieru vyvolávám makrem.

	<div class="modal-container modal-div" style="display: none;">
	{control inputElement-$row[$identificator]XXXXX$column}
</div>

O vyhodnocení formulářů se stará metoda inputElementSubmitted($form, $values).

<?php
	public function inputElementSubmitted($form, $values)
	{
		if(in_array($values['column'], $this->allowedUpdateColumns))
		{
			$this->dibi->query('UPDATE %n SET %a WHERE %n = %i', $this->tableName, array($values['column'] => $values['value']), $this->identificator, $values['rowid']);
			$this->flashMessage('Úprava byla úspěšně provedena.', 'flash-success');
		}
		else
		{
			$this->flashMessage('Nemáte pravomoci provést tuto úpravu.', 'flash-danger');
		}
		$this->table = $this->loadTable();
		//$this->presenter->redirect('this'); - toto funguje perfektně, až na to, že to pak nejede kompletně ajaxově
		//$this->invalidateControl('table-content'); - table-content je název snippetu
		$this->redrawControl();
	}
?>

Pokusím se vysvětlit v čem je problém. Když načtu stránku, vše se vyrenderuje přesně, jak má, všechno naprosto sedí (nebo jsem alespoň nenašel nic co by bylo v nepořádku). Pokud jakýkoliv formulář uploadnu, tak se naprosto korektně uloží do databáze a dokonce se mně asynchronně vrátí data na přerenderování (ty už správně úplně nejsou). Teď tedy k tomu, co nefunguje. Jde o 2 věci. Výsledek je tabulka, kde v každé kolonce, každého řádku je multiplier formulář, který slouží na úpravu hodnoty dané kolonky.
1) Když vyplním kolonku v prvním řádku a uploadnu formulář, tak se změny zanesou asynchronně do databáze, dokonce se data v celé tabulce korektně přerenderují, ale špatně se přerenderují dané multiplier formuláře. Konkrétně je špatně multiplier ve stejné kolonce ve druhém řádku (všechno ostatní je (asi) naprosto v pořádku). Špatně znamená, že jeho default value je nastavena na hodnotu právě upraveného prvního multiplieru ve stejné kolonce v prvním řádku. Toto chování je stejné pro libovolnou kolonku, vždy je po uploadu a přerenderování špatně stejná kolonka ve druhém řádku.
2) Když submitnu libovolnou kolonku v jiném, než prvním řádku, tak se opět upraví hodnota v databázi a tabulka se přerenderuje. Ale nyní je problém v tom, že mi komponenta z daného formuláře v dané kolonce se jménem value (ta co nese hodnotu dané kolonky ve formuláři) zmizí úplně, prostě tam chybí, je tam jen tlačítko upravit. Absolutně to nechápu. Vyzkoušel jsem různě invalidovat co šlo, zkoušel jsem redrawControl a vůbec nic to neřeší. Jediné, co to opraví je redirectnutí presenteru (natvrdo refreshnout stránku).

Budu rád za každou radu, kdyby jste potřebovali, abych někam hodil zdroják, asi s tím nemám problém, ale myslím, že jsem uvedl všechno důležité.

David Matějka
Moderator | 6445
+
+2
-

problem je asi v tom, ze pouzivas stejnou instanci inputu (selectbox/textinput) pro vsechny formy (a proto musis i nastavovat setParent atd.).. vytvor si vzdy novou instanci

F.Raven
Člen | 12
+
0
-

Funguje, děkuji za brilantní vhled a pomoc.