Kdyby/Replicator – $form->onSuccess[]

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

Dobrý den,

prosím vás, začal jsem lehce používat Kdyby/Replicator a narazil jsem na menší problém.

Problém je v tom, že metoda myFormSucceeded($form) je volána při použití kteréhokoliv ze tří tlačítek (remove, add a send). Rád bych aby se tato metoda volala jen při použití tlačítka Send.

Určitě se jedná jen o nějakou blbou chybu, jsem začátečník.

Děkuji.

protected function createComponentMyForm()
	{
		$form = new Nette\Application\UI\Form;

		$removeEvent = callback($this, 'MyFormRemoveElementClicked');

		// name, factory, default count
		$users = $form->addDynamic('users', function (Container $user) use ($removeEvent) {
		    $user->addText('name', 'Name');
		    $user->addText('surname', 'surbame');
		    $user->addSubmit('remove', 'Remove')
			->setValidationScope(FALSE) # disables validation
			->onClick[] = $removeEvent;
		}, 1);

		$users->addSubmit('add', 'Add next person')
		    ->setValidationScope(FALSE)
		    ->onClick[] = callback($this, 'MyFormAddElementClicked');

		$form->addSubmit('send', 'Send');

		$form->onSuccess[] = array($this, 'myFormSucceeded');

		return $form;
	}

	public function MyFormAddElementClicked(SubmitButton $button)
	{
	    $button->parent->createOne();
	}

	public function MyFormRemoveElementClicked(SubmitButton $button)
	{
	    // first parent is container
	    // second parent is it's replicator
	    $users = $button->parent->parent;
	    $users->remove($button->parent, TRUE);
	}

	public function myFormSucceeded($form)
	{
		foreach ($form['users']->values as $user)
		{
			echo $user['name'];
		}
	}
MartinitCZ
Člen | 580
+
+1
-

Nepoužívej onSuccess[], ale navěš si na hlavní button, v tvém případě send, onClick[].

Relapse
Člen | 34
+
0
-

Mám to tedy uděláné takto:

protected function createComponentMyForm()
	{
		$form = new Nette\Application\UI\Form;

		$removeEvent = callback($this, 'MyFormRemoveElementClicked');

		// name, factory, default count
		$users = $form->addDynamic('users', function (Container $user) use ($removeEvent) {
		    $user->addText('name', 'Name');
		    $user->addText('surname', 'surbame');
		    $user->addSubmit('remove', 'Remove')
			->setValidationScope(FALSE) # disables validation
			->onClick[] = $removeEvent;
		}, 1);

		$users->addSubmit('add', 'Add next person')
		    ->setValidationScope(FALSE)
		    ->onClick[] = callback($this, 'MyFormAddElementClicked');

		$form->addSubmit('send', 'Potvrdit')
		   ->onClick[] = array($this, 'myFormSucceeded');

		return $form;
	}

	public function MyFormAddElementClicked(SubmitButton $button)
	{
	    $button->parent->createOne();
	}

	public function MyFormRemoveElementClicked(SubmitButton $button)
	{
	    // first parent is container
	    // second parent is it's replicator
	    $users = $button->parent->parent;
	    $users->remove($button->parent, TRUE);
	}

	public function myFormSucceeded($form)
	{
		$values = $form->getValues();

		foreach ($form['users']->values as $user)
		{
			echo $user['name'];
			//foreach($value as $val)
			//{
			//	echo $val['name'];
			//}
		}
	}

Ted mi to ale na řádku:

$values = $form->getValues();

hází chybu: Call to undefined method Nette\Forms\Controls\SubmitButton::getValues().

Jak se tedy dostanu k datum z formuláře, když nebude používat onSuccess[] ?

Děkuji

MartinitCZ
Člen | 580
+
0
-
	public function myFormSucceeded(SubmitButton $button)
    {
        $values = $button->form->getValues();

        foreach ($form['users']->values as $user)
        {
            echo $user['name'];
            //foreach($value as $val)
            //{
            //  echo $val['name'];
            //}
        }
    }
David Matějka
Moderator | 6445
+
+3
-

v kdyby/replicator jsou nejaky nezdokumentovany featury, muzes pouzit addCreateOnClick a addRemoveOnClick a smazat custom callbacky a setValidationScope. stejne tak muzes pouzit onSuccess, celkem to bude vypadat takto:

protected function createComponentMyForm()
{
    $form = new Nette\Application\UI\Form;

    // name, factory, default count
    $users = $form->addDynamic('users', function (Container $user) {
        $user->addText('name', 'Name');
        $user->addText('surname', 'surbame');
        $user->addSubmit('remove', 'Remove')
        ->addRemoveOnClick();
    }, 1);

    $users->addSubmit('add', 'Add next person')
        ->addCreateOnClick();

    $form->addSubmit('send', 'Send');

    $form->onSuccess[] = array($this, 'myFormSucceeded');

    return $form;
}


public function myFormSucceeded($form)
{
    foreach ($form['users']->values as $user)
    {
        echo $user['name'];
    }
}
Relapse
Člen | 34
+
0
-

Super. Děkuji vám za odpovědi.

matopeto
Člen | 395
+
0
-

To bohuzial nefunguje, ked checkujem success v akcii:

<?php
	public function actionDefault() {
		/** @var Nette\Application\UI\Form $form */
		$form = $this['replicatorForm'];

		if ($form->isSuccess()) {
			echo "Success 2";
		}
	}
?>

$form->isSuccess() je true i pri stlaceni tlacitka add.

Je to chyba alebo vlastnost?

Edit: HM, ta je to asi vlastnosti, pretoze form sa spracuvava az po „akcii“

Editoval matopeto (27. 10. 2014 16:19)

Zax
Člen | 370
+
-1
-

Replicator jsem zatím nikdy nepoužil, ale chtěl bych jenom zmínit, že jde velmi snadno rozlišit, kterým tlačítkem byl formulář odeslán:

function createComponentMyForm() {
	$form = new Form;
	// ...
	$form->addSubmit('send', 'Send');
	$form->onSuccess[] = [$this, 'myFormSubmitted'];
	return $form;
}

function myFormSubmitted(Form $form) {
	if($form->submitted === $form['send']) {
		// odesláno pomocí "send"
	}
}
Relapse
Člen | 34
+
0
-

Prosím vás, ještě jsem narazil na problém při vykreslování tohoto formuláře.

public function create()
    {
        $form = new Form;

            $form->addText('param1', 'Param1:')
                ->setRequired('Zadejte param1.');

            $form->addText('param2', 'Param2:')
                ->setRequired('Zadejte param2.')
                ->addRule(Form::INTEGER, 'param2 musí být číslo');

            $products = $form->addDynamic('products', function (Container $product) {

                $product->addSelect('product', 'Produkt:', self::FselectArray())
                    ->setPrompt('Vyberte produkt');
                $product->addText('quantity', 'Množství:');
                $product->addSubmit('remove', 'Odebrat')
			->addRemoveOnClick();
            }, 1);

            $products->addSubmit('add', 'Přidat produkt')
		    ->addCreateOnClick();

            $form->addSubmit('send', 'Potvrdit');

        return $form;
    }

Kód pro manuální vykreslení formuláře.
Problém je v tom, že se mi nedaří vykreslit tlačítko „add“ Přidat produkt.

{form orderForm}
            <ul class="errors" n:if="$form->hasErrors()">
                <li n:foreach="$form->errors as $error">{$error}</li>
            </ul>

            <table>
                <tr class="required">
                    <th>{label param1 /}</th>
                    <td>{input param1}</td>
                </tr>
                <tr class="required">
                    <th>{label param2 /}</th>
                    <td>{input param2}</td>
                </tr>
                {foreach $form['products']->containers as $id => $product}
                    <tr class="required">
                        <th>{label products-$id-product /}</th>
                        <td>{input products-$id-product}</td>
                    </tr>
                    <tr class="required">
                        <th>{label products-$id-quantity /}</th>
                        <td>{input products-$id-quantity}</td>
                    </tr>
                {/foreach}

                <tr class="required">
                        <th></th>
                        <td>{vykreslení tlačítka add} </td>
                    </tr>

                <tr class="required">
                    <th></th>
                    <td>{input send}</td>
                </tr>
            </table>
        {/form}

Děkuji.

David Matějka
Moderator | 6445
+
0
-
{input products-add}
Relapse
Člen | 34
+
0
-

Děkuji. Zkoušel jsem {input products->add} :D .

FJP
Člen | 124
+
0
-

Ahoj, toto vlákno mi pomohlo, ale narazil jsem: mám formulář v jednom z tabů twitter bootstrapu.

když jakkoli upravím akci formuláře (kvůli přidání id příslušného tabu: #pridat).. vsechny inputy přidané pomocí replikátoru se ztratí. nenapadá mě jak to jinak udělat.

edit>nakonec to vyřešilo:

   public function MyFormAddElementClicked(SubmitButton $button) {
        $button->parent->createOne();
        $button->form->setAction('#pridat');
    }

Editoval FJP (21. 4. 2016 21:07)