Dynamické přídání položek do formuláře se provede jenom jednou

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

Ahoj, v šabloně mám button a na jeho klik mám navázáno zavolání handle a přídání dalších dvou text inputů. Po prvním kliku na button se vše přidá v pořadku ale po druhém kliku už ne, přitom ve firebugu žádná chyba, vše se odešle v pořádku, odpověď je taky správně, ale jakoby se napodruhé už snippet nepřekreslil. Tady je kód:

šablona

{snippet variants}
	{control addMortiseForm}
{/snippet}
<input type="button" class="addVariant ajax" value="Přidat variantu" />

<script type="text/javascript">

	$('.addVariant').on('click', function() {
	    $.nette.ajax({
		type: 'GET',
		url: {link addVariant!},
		data: {
		    'value': $('.unitTitle').length + 1,
		}
	    });
	});


</script>

Handle:

public function handleAddVariant($value)
{
    $this['addMortiseForm']->addText('unitTitle' . $value, 'Název:')->setAttribute('class', 'unitTitle');
    $this['addMortiseForm']->addText('unit' . $value, 'Jednotka:');
    $this->invalidateControl('variants');
}

v js jsem přidával i

$.nette.init();
$.nette.ext('load', {
    success: function () {
        $.nette.load();
    }
});

ale pořád nic.
Nevíte kde mám co špatně?

Díky za rady

Editoval spiider (31. 7. 2014 11:05)

David Matějka
Moderator | 6445
+
0
-

Tohle ti nebude fungovat. Nette pokazde vytvari formular znovu – pravdepobodne se ti tedy asi nepridavaji ty predchozi inputy z handleAddVariant
reseni: pouzij kdyby/replicator

spiider
Člen | 162
+
0
-

Aha, ja použil postup tady tak sem myslel, že to pojede, zkusim to co jsi poslal teda.

Díky

spiider
Člen | 162
+
0
-

Tak jsem to zkusil použít takhle, ale vrací mi to fatal error Class ‚Nette\Utils\Callback‘ not found
Kod vytvoření formuláře:

$form = new Form;
$form->addText('title', 'Název:');
$form->addTextArea('description', 'Popis:');
$form->addDynamic('variants', function(Container $variants) {
	$variants->addText('unitTitle1', 'Název:')->setAttribute('class', 'unitTitle');
	$variants->addText('unit1', 'Jednotka:');
}, 1);

$form->addSubmit('save', 'Uložit');
$form->onSuccess[] = $this->saveForm;
return $form;

A handle pro dynamické přidaní text inputu:

$this['addMortiseForm']->addDynamic('variants', function(Container $variants) {
	$variants->addText('unitTitle' . $value, 'Název:')->setAttribute('class', 'unitTitle');
	$variants->addText('unit' . $values, 'Jednotka:');
}, 1);

Neporadíte co dělám špatně…s kdyby pracuju poprve.
Díky

iguana007
Člen | 970
+
0
-

Replicator jsem ještě nepoužil, ale jestli to nebude tím, že Callback je v Nette 2.2 deprecated – viz.: https://api.nette.org/…allback.html

Už se o tomto ví a asi se to i řeší – více bude vědět autor @FilipProcházka – viz.: https://help.kdyby.org/question/?…

David Matějka
Moderator | 6445
+
0
-

nainstaloval si to pres composer? ten by si mel ohlidat spravnou verzi, jelikoz Nette\Utils\Callback, ktery je od 2.2 (a ty mas asi 2.1, ze?), je pouzit az v masteru

Editoval matej21 (1. 8. 2014 12:18)

spiider
Člen | 162
+
0
-

Pres composer jsem to neinstaloval, stáhnul jsem ho z githubu a nakopíroval do libs. Nette mam 2.0.10…takže mam přejít na nette 2.2 doporučujete?

David Matějka
Moderator | 6445
+
+2
-

Hlavne doporucuji prejit na composer :) (nebo si pro 2.0 stahni verzi z prislusne branche: https://github.com/…ee/nette-2.0)

Prechod z 2.0 na 2.2 by nebyl bezbolestny, takze zalezi na tobe.. Minimalne ale updatuj na 2.0.15.

spiider
Člen | 162
+
0
-

oki, mozna zkusim 2.2 nemam zase tak velkou aplikaci zatim takze tech uprav snad nebude tolik doufam :) s composeru mam trošku vítr, ale zkusím to taky, asi to bude lepší. díky

spiider
Člen | 162
+
0
-

Tak jsem aktualizoval nette na 2.1, stáhnul kdyby a přidal do formuláře:

$form->addDynamic('variants', function(Container $variants) {
			$variants->addText('unitTitle1', 'Název:')->setAttribute('class', 'unitTitle');
			$variants->addText('unit1', 'Jednotka:');
		}, 1);

Handler mám pak takto:

$form = $this['addMortiseForm'];
	    $variants = $form['variants'];
	    $variants->addText('unitTitle' . $value, 'Název:')->setAttribute('class', 'unitTitle');
	    $variants->addText('unit' . $value, 'Jednotka:');
	    $this->invalidateControl('variants');

Nicméně se to chová úplně stejně jako bez použití kdyby. Přidá se po kliku na tlačítko textbox ale po dalším kliku už ne :(
Nenapadá někoho kde dělám chybu?

Díky

David Matějka
Moderator | 6445
+
0
-
$form->addDynamic('variants', function(Container $variants) {
    $variants->addText('unitTitle', 'Název:')->setAttribute('class', 'unitTitle');
    $variants->addText('unit', 'Jednotka:');
}, 1);
$form['variants']->addSubmit('add', 'Přidat')
->setValidationScope(FALSE)
->addCreateOnClick(/*parametr TRUE umozni pridat radky dopredu, aniz by musely byt vyplneny*/);

Editoval matej21 (19. 8. 2014 11:26)

spiider
Člen | 162
+
0
-

Hele funguje to, super, ještě by mě zajímalo jak to vyřešit aby to fungovalo ajaxem…třídu ajax jsem tomu tlačítku přiřadil, ale pořád se to refreshuje…díky moc

David Matějka
Moderator | 6445
+
0
-

A ostatni veci ti ajaxove fungujou?

spiider
Člen | 162
+
0
-

Nic jiného tam ajaxem nepotřebuju řešit. Požadavek se odešle v pořádku, ale přidané textboxy se nevykreslej vubec. Nemá se někam ještě přidat invalidateControl ?

Editoval spiider (19. 8. 2014 12:03)

iguana007
Člen | 970
+
0
-

A co se ti při tom ajax volání vrátí v response, když se podíváš do záložky Network v Developer tools/Firebugu?

spiider
Člen | 162
+
0
-

Tak už to funguje, dal jsem do renderDefault

if ($this->isAjax()) {
	$this->invalidateControl('variants');
}

Snad to není nějaká prasárnička

spiider
Člen | 162
+
0
-

Ještě dotaz jenom…když bych chtěl u dynamicky přidaných textboxů mít vždy s číslem např. Název 1, Název 2 atd. jak se to tady dělá pls.

Díky

David Matějka
Moderator | 6445
+
0
-

Asi pro to nebude zadna zkratka, budes to muset vyresit rucne, zkus:

$i = 1;
$form->addDynamic('variants', function(Container $variants) use(&$i) {
    $variants->addText('unitTitle', "Název $i:")->setAttribute('class', 'unitTitle');
    $variants->addText('unit', 'Jednotka:');
    $i++;
}, 1);
spiider
Člen | 162
+
0
-

Super, funguje, díky moc ještě zkouším tlačítko na odebrání udělat, což se mi zatím nedaří, ale budu se snažit sám ještě :)

spiider
Člen | 162
+
0
-

Tak při použití toho addRemovOnClick mi to píše Nette\InvalidArgumentException
Given component 1 is not children of items. Našel jsem tady, že jde o bug, ale popsané řešení nepomohlo a chyba je pořád stejná…nevíte prosím jak to řešit?

David Matějka
Moderator | 6445
+
0
-

@spiider ukaz kod jak to mas..

spiider
Člen | 162
+
0
-

To je i s tou upravou podle toho na githubu

$form['variants']->addSubmit('add', 'Přidat')->setValidationScope(FALSE)
		    ->addCreateOnClick(TRUE)->setAttribute('class', 'ajax');
		$self = $this;
		$form['variants']->addSubmit('del', 'Odebrat')->setValidationScope(FALSE)
		    ->addRemoveOnClick(function($replicator, $container) use($self) {
			if ($self->presenter->isAjax()) {
			    $self->presenter->invalidateControl('variants');
			}
			else {
			    $self->presenter->redirect('this');
			}
		    })
		    ->setAttribute('class', 'ajax');

		$form->onSuccess[] = $this->saveMortise;
David Matějka
Moderator | 6445
+
0
-

@spiider ten delete button neni pro cely form, ale pro jednotlive dynamicke containery – musi byt tedy uvnitr te closury (jak jinak by to vedelo, ktery prvek chces smazat, ze? :))

$i = 1;
$form->addDynamic('variants', function(Container $variants) use(&$i) {
    $variants->addText('unitTitle', "Název $i:")->setAttribute('class', 'unitTitle');
    $variants->addText('unit', 'Jednotka:');
    $variants->addSubmit('del')->addRemoveOnClick();
    $i++;
}, 1);
spiider
Člen | 162
+
0
-

No myslel jsem že to smaže vždycky ten poslední :) ale už je to ok, tak díky za rady.