Je možné nastavit, aby se return value z filtru u inputu nenastavovala jako hodnota inputu?

Polki
Člen | 553
+
0
-

Čau. Nadpis řekl vše.

Jde mi o toto:

$form->addCheckboxList('mujInput', "Vyberte jednu či více možností", [
    1 => 'prvni',
    2 => 'druha',
    4 => 'treti',
    8 => 'ctvrta'
])
->addCondition(UI\Form::FILLED)
->addFilter(function ($value) {
    $retVal = 0;
    foreach ($value as $checkedCHB) {
        $retVal += $checkedCHB;
    }
    return $retVal;
});

No a tím jsem dosáhl, že když uživatel některé checkboxy zaklikne, tak mi vrátí mujInput součet hodnot a místo 4 sloupců v db mám jen jeden.

Jednoduše tedy pokud si uživatel zaklikne ‚druha‘ a ‚ctvrta‘, tak mujInput vrátí číslo 10. To se uloží do DB a při načtení z DB se rozparsuje podle masky. Takže vím, že když mám v DB číslo 10, neboli 1010, tak je zakliknutý chb ‚ctvrta‘ a chb ‚druha‘

Problém je, že při nepodařeném pokusu o vyhodnocení nastane to, že filtr nastaví setValue u inputu na 10 a laděnka vyhodí error 10 are out of allowed set…

Takže.

  1. Je možnost nějak zakázat toto chování nastavování výchozí hodnoty? Podle projití kódu bych řekl ne. Ale kdo ví možná jste chytřejší.
  2. pokud ne je možnost do metody setValue předat callback, který ji přepíše, takže si v ní budu parsovat 10 na 4 a 2? Podmínkou je, abych nemusel tvořit vlastní komponentu.
  3. pokud nelze ani 2, je možné udělat něco jako addFilter ale pro vstup do inputu?

Dík za rady

MajklNajt
Člen | 471
+
0
-

Ahoj, prečo tu logiku jednoducho nepresunieš tam, kam patrí – do modelu? Predpokladám, že dáta z DB parsuješ hneď, keď ich vytiahneš v modeli…

Kamil Valenta
Člen | 758
+
+1
-

Nebo bych to řešil na nějakém předkovi, ze kterého všechny formy budou dědit.
Aby ses nemusel všude tahat s tím ->addFilter,
napsal bych si v předkovi něco jako ->addBinCheckboxList, který by vrátil addCheckboxList, ale hned by na něm zavolal addFilter.
Pak by sis přepsal setDefaults(), která by v případě checkboxlistů nastavila jednotlivé položky.

Bylo by to vše na jednom místě a neroztahovalo by se to po jednotlivých modelech…

Polki
Člen | 553
+
0
-

@MajklNajt Udělal jsem to tak, ale jde mi o to, že chci zachovat a přijde mi kouzelnější toto:

Komponenta formuláře:

public function onSuccess($form) {
	$this->manager->addItem($form->getValues());
}

manager:

public function addItem($values) {
    $this->db->table('myTable')->insert($values);
}

Protože podle principu Nette: ‚Less CODE ⇒ More security.‘

@kamil_v Good point. Ovšem jde o to, že jsem převzal projekt po jiných lidech. Jistě, že první, co mě napadlo tak to řešit traitou, kterou by implementoval formulář, který by se tvořil jako základ do jednotlivých komponent, na což se snaží nasměrovat i samo nette v sandboxu, ale tito lidi byli slušně řečeno vymykající se a napsali si většinu formulářů natvrdo do presenterů, kde je vytvářeli pomocí new Form(); přímo v metodě createComponent… místo tvorby továrničky. A přepisovat toto do továrniček je práce navíc, takže jsem to zatím dočasně řešil tím modelem, jak říkal MajklNajt bohužel.

Kamil Valenta
Člen | 758
+
0
-

Pokud jsou komponenty tvořeny přes new Form();, tak je to jen otázka aktualizace use.
Což by mělo jít refactorovat celkem automatizovaně.

Polki
Člen | 553
+
0
-

Kruci už mám asi nějaké zatmění. Neuvědomil jsem si že můžou místo formu od nette tvořit můj form. :D diky