Checkbox v poli
- okrajek
- Člen | 5
Ahoj,
Mám takový problém, už to hledám fakt dlouho a nedaří se mi …
Jak udělat checkbox tak aby se mi po odeslání formuláře přes cyklus vložili zaškrtnutá políčka do DB…
Dejme tomu že mám tabulky
group(id,name)
event(id,description)
group_has_event(group_id,event_id)
A já se tady snažím udělat to aby se vylistovali do formuláře všechny groupy uživatele s checkboxem a po zaškrtání některých z nich se ty co byli zaškrtnutý vložili do group_has_event. Aby v event_id bylo id eventu (to pořešim přes URL) a v group_id id té zaškrtnuté grupy. Jak to mám prosím poskládat dohromady???
PS.: Kdyby se přidala ještě jedna tabulka např. subgroup(id,group_id,parent_id…) a fungovalo by to jako stromová struktura, jak by se to udělalo aby byl ve formuláři výpis nějak takto:
GROUP A
checkbox – subgroup A-A
checkbox – subgroup A-B
checkbox – subgroup A-C
GROUP B
checkbox – subgroup B-A
checkbox – subgroup B-B
checkbox – subgroup B-C
a fungovalo by to stejně, čili že zaškrtám a odešlu tlačítkem a do group_has_event by se zase vložili jenom subgroup_id a event_id…
Díky moc
- Panda
- Člen | 569
Nějak pořádně nechápu ten příklad s databází (pravděpodobně to bude únavou), takže Ti zkusím odpovědět a budu doufat, že Ti to alespoň trochu pomůže.
Při sestavování formuláře použij toto:
<?php
$items = dibi::query('SELECT * FROM `group` WHERE ...');
// Do formuláře přidáme 'jmenný kontejner', do kterého umístíme checkboxy
$containter = $form->addContainer('selected');
foreach ($items as $item) {
// Checkboxy budou mít atribut name nastaven na selected[$id],
// s hodnotami tedy půjde pracovat jako s polem
$container->addCheckbox((string) $item->id, $item->name);
}
?>
A jeho zpracování:
<?php
$values = $form->getValues();
// ...
// Projdeme jmenný kontejner selected s checboxy
foreach ($values['selected'] as $id => $value) {
// Vybrané checkboxy mají hodnotu nastavenou na TRUE, jejich klíč
// v poli je ID skupiny
if ($value) {
dibi::query('INSERT INTO `group_has_event` VALUES(%i, %i)', $id, $event_id);
}
}
// ...
?>
Za chvilku to zkusím ještě nějak okomentovat…
// Doplnění: pokus dokončen.
Editoval Panda (1. 6. 2009 18:38)
- vlki
- Člen | 218
Bojím se, že by to muselo být řešeno složitějším definováním
konstrukcemi addConditionOn
, kde by se vytvořil nějaký
kontrolní prvek (šlo by použít třeba i první checkbox) a tomu nastavit,
aby vykazoval nevaliditu, když je vše nezatrhnuté…
Pokud bych to měl předvést na příkladu výše uvedeném, tak něco v tomto stylu… Píšu z hlavy:
<?php
$items = dibi::query('SELECT * FROM `group` WHERE ...')->fetchAll();
// Do formuláře přidáme 'jmenný kontejner', do kterého umístíme checkboxy
$containter = $form->addContainer('selected');
// potřebujeme aspoň jeden checkbox, který bude ten kontrolní
if (count($items) > 0) {
$firstItem = array_shift($items);
$fluentRule = $container->addCheckbox((string) $firstItem->id, $firstItem->name);
foreach ($items as $item) {
// Checkboxy budou mít atribut name nastaven na selected[$id],
// s hodnotami tedy půjde pracovat jako s polem
$formItem = $container->addCheckbox((string) $item->id, $item->name);
// řetězení podmínek - je checkbox nezatrhnutý?
$fluentRule->addConditionOn($formItem, Form::EQUAL, FALSE);
}
// pokud jsou všechny podmínky definované v cyklu splněné, dojde to až sem,
// kde se zkontroluje, jestli je zatrhnutý ten první. Pokud ano, validace
// projde. Pokud ne, hodí to hlášku...
$fluentRule->addRule(Form::FILLED, 'Musíte něco zatrhnout...!');
}
?>
Druhou možností je využítí CheckboxListu . U něho si ale nejsem jistý čistotou návrhu. Také u něj nefunguje JS validace, která by u výše nastíněného řešení měla fungovat.
Editoval vlki (16. 6. 2009 18:54)
- tondovo
- Člen | 10
Tohle nemůže fungovat, protože $items není pole, nějak to celý moc
nechápu.
Nevedla by cesta přes vlastní validační pravidlo?
<?php
function myValidator($item){
...
}
$container->addCheckbox((string) $item->id, $item->name)
->addRule('myValidator', '');
?>
Něco jsem zkoušel, ale bez úspěchu
- vlki
- Člen | 218
Řešit to vlastním validátorem pro jeden prvek mi to přijde jako silné lámání přes koleno.
V nastíněném řešení nešlo až tak o to okolí, ale přímo o to
řetězení podmínek. Samozřejmě, že $items
nebude pole,
protože dibi::query
vrací DibiResult
. Pole prvků se
z toho vytvoří metodou fetchAll
, takže jsem svůj předchozí
příspěvek opravil a snad by to už i reálně fungovalo.
- Šaman
- Člen | 2659
vlki: Tak jsem to zkoušel použít a nakonec se mi to podařilo rozchodit. Ale s jednou opravou – addConditionOn vrací novou větev validačních pravidel, ale nenastaví jí jako aktivní. Takže se sice přidá nová podmínka, ale další se s ní neřetězí, nýbrž se vyhodnotí nezávisle. Proto se jediné validační pravidlo projevilo vždy, i pokud byly některé checkboxy zatržené.
Takže finální verze vypadá takhle:
<?php
$items = dibi::query('SELECT * FROM `group` WHERE ...')->fetchAll();
// Do formuláře přidáme 'jmenný kontejner', do kterého umístíme checkboxy
$containter = $form->addContainer('selected');
// potřebujeme aspoň jeden checkbox, který bude ten kontrolní
if (count($items) > 0) {
$firstItem = array_shift($items);
$fluentRule = $container->addCheckbox((string) $firstItem->id, $firstItem->name);
foreach ($items as $item) {
// Checkboxy budou mít atribut name nastaven na selected[$id],
// s hodnotami tedy půjde pracovat jako s polem
$formItem = $container->addCheckbox((string) $item->id, $item->name);
// řetězení podmínek - je checkbox nezatrhnutý?
// TADY JE TEN ROZDÍL
$fluentRule = $fluentRule->addConditionOn($formItem, Form::EQUAL, FALSE);
}
// pokud jsou všechny podmínky definované v cyklu splněné, dojde to až sem,
// kde se zkontroluje, jestli je zatrhnutý ten první. Pokud ano, validace
// projde. Pokud ne, hodí to hlášku...
$fluentRule->addRule(Form::FILLED, 'Musíte něco zatrhnout...!');
}
?>