Dynamické přídání položek do formuláře

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

Zdravím,
v seznamování s Nette jsem narazil na další „problém“. Řeším teď následující:

  1. Základní formulář bude mít 2 inputy – Datum a input s číslem. Do DB budu ukládat číselnou hodnotu a datum kdy byla naměřena.
  2. Potřebuji, aby se pomocí tlačítka přidal další pár inputů. Těchto párů může být 1-N .
  3. Potřebuji tedy vyřešit dynamické přidávání páru inputů (i jejich odebrání ??) a následné zpracování pro uložení do DB.
  4. Při načtení formuláře potřebuji zobrazit 0-N vyplněných párů inputů (data z DB).

Procházel jsem forum a narazil jsem na Kdyby/Replicator.

Chci se tedy zeptat, jestli je Kdyby/Replicator ideální řešení na můj případ a hlavně jestli je použitelný s poslední verzí Nette (2.3.4).

Díky moc

romiix.org
Člen | 343
+
0
-

Hodí sa to na to, smelo do toho ;)

Croc
Člen | 270
+
0
-

Mám problém s instalací přes composer: ZDE

Nevíte jak to vyřešit?

romiix.org
Člen | 343
+
+1
-

Akým príkazom sa to snažíš nainštalovať?

composer require kdyby/forms-replicator:@dev
Croc
Člen | 270
+
+1
-

Zkoušel jsem ten co je uvedený v pokynech instalace:

composer require kdyby/forms-replicator:~1.1

Ten co si postnul funguje :) Díky

Croc
Člen | 270
+
0
-

Zkouším implementovat následující:

<?php

namespace App\Forms;

use Nette,
    App\Model\UserManager,
    Nette\Application\UI\Form,
    App\Model,
    Nette\Forms\Container,
    Nette\Forms\Controls\SubmitButton;


class WeightFormFactory extends Nette\Object
{
    /** @var Nette\Security\User */
    public $user;

    /** @var \App\Model\UserManager */
    public $userManager;

    /** @var \App\Model\UtilsManager */
    public $utilsManager;


    public function __construct(UserManager $userManager, Nette\Security\User $user, Model\UtilsManager $utilsManager)
    {
        $this->userManager = $userManager;
        $this->user = $user;
        $this->utilsManager = $utilsManager;
    }

    /**
     * @return Form
     */
    public function create($id)
    {

        $form = new Form;

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

        // name, factory, default count
        $users = $form->addDynamic('users', function (Container $user) use ($removeEvent) {
            $user->addText('date','Datum:');

            $user->addSubmit('remove', 'Remove')
                ->setValidationScope(FALSE) # disables validation
                ->onClick[] = $removeEvent;
        }, 1);

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

        $form->addProtection('Vypršel časový limit, odešlete formulář znovu');
        $form->addSubmit('send', 'Odeslat');
	    $form->onSuccess[] = array($this, 'formSucceeded');
		return $form;
	}

    public function formSucceeded($form, $values)
    {
     //.....
    }

    public function WeightFormAddElementClicked(SubmitButton $button)
    {
        $users = $button->parent;

        // count how many containers were filled
        if ($users->isAllFilled()) {
            // add one container to replicator
            $button->parent->createOne();
        }
    }

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

Ať kliknu na tlačítko Add, Remove nebo Odeslat, dostanu následující chybu:

Notice
Undefined property: Nette\Utils\ArrayHash::$temp

File: G:\workspace\vendor\nette\utils\src\Utils\ArrayHash.php:77

67:            $this->$key = $value;
68:        }
69:
70:
71:        /**
72:         * Returns a item.
73:         * @return mixed
74:         */
75:        public function offsetGet($key)
76:        {
77:            return $this->$key;
78:        }
79:
80:
81:        /**

Bohužel netuším kde je chyba. Postupoval jsem dle návodu.

EDIT: Vypadá to že tlačítka Add a Remove mají funkci odeslání formuláře. Zkusím zjistit více.

Editoval Croc (23. 8. 2015 12:35)

Joe Kolář
Člen | 13
+
0
-

Někde přistupuješ pravděpodobně do $values->temp, ale hodnota temp ve values není.
Napřistupuješ tak ve WeightFormFactory::formSucceeded?

Croc
Člen | 270
+
0
-

To už jsem vyřešil. Opravdu jsem přistupoval k $values->temp ve formSucceeded.

Částečně jsem to rozchodil pomocí tohoto vlákna.

Zobrazí se mi nastavený počet inputů, můžu je mazat a zase přidávat, ale nemůžu jich přidat více než byla defaultní hodnota, což je problém.

Kód mám nyní takhle:

  $form = new Form;

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

        // name, factory, default count
        $users = $form->addDynamic('users', function (Container $user) use ($removeEvent) {
            $user->addText('date','Datum:');

            $user->addSubmit('remove', 'Remove')
                ->setValidationScope(FALSE) # disables validation
                ->addRemoveOnClick();
        }, 1);

        $users->addSubmit('add', 'Add')
            ->setValidationScope(FALSE)
            ->addCreateOnClick(/*parametr TRUE umozni pridat radky dopredu, aniz by musely byt vyplneny*/);

        $form->addProtection('Vypršel časový limit, odešlete formulář znovu');
        $form->addSubmit('send', 'Odeslat');
	    $form->onSuccess[] = array($this, 'formSucceeded');
		return $form;
	}

Už to funguje :) Nepřečetl jsem si pořádně dokumentaci a použil jsem variantu, kdy musí být první pole vyplněné aby šlo přidat nové. Pokud tedy vyplním první pole a chci přidat nové, vše funguje jak má :)

Editoval Croc (25. 8. 2015 10:44)