Formulár – dynamický prvok obsahujúci dynamicky závyslí select
- ricco24
- Člen | 141
Ahojte, podreboval by som poradiť s riešením nasledovného problému.
Mám formulár s dynamicky pridávaným prvokom – osoba. Na tento prvok používam rozšírenie addDynamic no v tejto komponente potrebujem vytvoriť dynamicky závyslí select – misto kde pôsobím. A keďže týchto miest môže byť viacero potrbujem aby sa taktiež dynamicky pridával nový select po výbere mesta v už zobrazenom selecte. Samozrejme všetko musí fungovať ajaxovo.
Dá sa to riešiť všetko cez snippety ?
Keďže problém vydím v tom že ak chcem invalidovať všetky osoby potrebujem snippet okolo všetkých osôb no ak by som chcel invalidovať len selectboxy s miestom pôsobnosti tak si musím obaliť jednotlivé selecty do dynamických snippetov – no v tom potom nedokážem zinvalidovať všetky osoby v prípade nutnosti … Napadá vás návrh nejakého riešenia ?
- Tomáš Votruba
- Moderator | 1114
Ahoj, se snippety to určitě jde. Pro místo invaliduješ příslušný input a pro invalidaci osoby můžeš zahrnout oba inputy. Co tento návod?
- ricco24
- Člen | 141
Prešiel som si už predtým aj ten návod ktorý si postoval aj implementáciu rozšírenia addDynamic …
Tu posielam moje riešenie:
Presenter:
// časť funkcie formulára s vytváraním osoby:
$removeEvent = callback($this, 'MyFormRemoveElementClicked');
$persons= $form->addDynamic('persons', function (\Nette\Forms\Container $category) use ($removeEvent, $self) {
$persons->addText('name', 'Meno');
$persons->addSelect('region_id', 'Pôsobím v regióne', $self->regions)
->setPrompt('')
->setRequired()
->getControlPrototype()
->class('region-select');
$persons->addSelect('city_id', 'Pôsobím v meste', $self->city)
->setPrompt('')
->setRequired();
$persons->addSubmit('remove_person', 'Odstrániť')
->setValidationScope(false)
->onClick[] = $removeEvent;
}, $this->defaults_persons_count);
$persons->addSubmit('add_person', 'Pridať osobu')
->setValidationScope(false)
->onClick[] = callback($self, 'MyFormAddElementClicked');
// ostatok formulára ...
// spracovanie handle pri zmene regiónu
public function handleSelectLoad($region, $id)
{
$form = $this['dataForm'];
// tu získavam poradie v ktorom dynamickom elemente nastala zmena - osoba
$parseId = explode('-', $id);
$counter = $parseId[3];
$table = $this->context->database->table('cities')->where('region_id', $region);
$data = array();
foreach($table as $row) {
$data[$row->id] = $row->name;
}
$form['regions'][$counter]['city_id']->setItems($data);
$form['regions'][$counter]['city_id']->setPrompt('-- vyberte činnosť --');
$this->invalidateControl("persons");
}
Šablóna:
{snippet persons}
<fieldset>
{foreach $dataForm['persons']->containers as $person}
{if !$iterator->first}<br />{/if}
{if $iterator->first}<legend>Osoba</legend>{/if}
<table>
<tr>
<th>{$person['name']->label}</th>
<td>{$person['name']->control}</td>
</tr>
<tr>
<th>{$person['region_id']->label}</th>
<td>{$person['region_id']->control}</td>
</tr>
<tr>
<th>{$person['city_id']->label}</th>
<td>
{snippet city-$iterator->count}
{$person['city_id']->label}
{/snippet}
</td>
</tr>
</table>
<br />
<div class="right">
{$person['remove_category']->control}
{$dataForm['persons']['add_category']->control}
</div>
<div class="clear"></div>
{/foreach}
</fieldset>
{/snippet}
<script type="text/javascript">
$("form").delegate('.region-select', 'change', function() {
$.get("?do=selectLoad", {"region": $(this).val(), "id" : $(this).attr('id')});
});
</script>
Problém pri tomto riešení je ten že celá časť s osobami je obalená do statického snippetu a jednotlivé selecti mesta ktoré sú závyslé na výbere regiónu sú obalené do dynamických snippetov. Ak to mám takto tak pri zmene prvého regionu sa mestá načítajú dobre ale ak zmením región pri inej osobe tak sa mi síce mestá pre túto osobu načítajú dobre ale pre predchádzajúcu sa mi vrátia do východzích hodnôt. Taktiež pri tomto riešení nefunguje pridávanie/odoberanie osôb keďže pri invalidácii snippetu persons dostanem ako odpoveď len dynamické snippety …
Editoval ricco24 (11. 8. 2012 12:24)