Kdyby/Replicator – dependency selectbox ajax

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

Ahojte,

Môj problém spočíva v tom že, mam formulár, v ktorom potrebujem použiť závislé selectoboxy(dependency). Všetko funguje až do momentu kým nepridám nový riadok. Akonáhle pridám nový riadok a zmením v ňom hodnotu tak mi to po prekreslení zresetuje hodnoty predchádzajúceho riadku. Pripadá mi to ako keby po prekreslení nevie aké hodnoty boli predtým. Ani dynamický snippet mi nepomohol lebo sa to prekreslilo aj keď som „nezmenil“ hodnoty.

Selectboxy sú podla postupnosti : Kategória → Výrobca → Produkt

Preseneter

<?php
	/**
     * DemandForm component.
     *
     * @return \Nette\Application\UI\Form
     */
    protected function createComponentDemandForm()
    {
        $removeEvent = callback($this, 'MyFormRemoveElementClicked');

    	$form = new Form;

        $items = $form->addDynamic('items', function (Container $item) use ($removeEvent) {
            $categories = $this->categoryRepository->findAll()->fetchPairs('id', 'name');
            $producers = $this->producerRepository->findAll()->fetchPairs('id', 'name');
            $products = $this->productRepository->findAll()->fetchPairs('id', 'name');

            $item->addSelect('category_id', 'Kategórie', $categories)
                ->setAttribute('class', 'form-control customSelect');
            $item->addSelect('producer_id', 'Výrobca', $producers)
                ->setAttribute('class', 'form-control customSelect');
            $item->addSelect('product_id', 'Produkt', $products)
                ->setAttribute('class', 'form-control customSelect');

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

        $items->addSubmit('add', 'Add next item')
            ->setValidationScope(FALSE)
			->setAttribute('class', 'ajax')
            ->onClick[] = callback($this, 'MyFormAddElementClicked');



        if ($this->id) {
            $form->addSubmit('send', 'Uložiť');
        } else {
            $form->addSubmit('send', 'Vytvoriť');
        }


    	$form->onSuccess[] = $this->demandFormSubmitted;

    	return $this->createBootstrapForm($form);
    }


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

        $this->redrawControl('items');
    }


    public function MyFormRemoveElementClicked(SubmitButton $button)
    {
        $id = $button->parent->name;
    }

    /***/
    public function handleUpdateProducers($value, $container)
    {
        $producers = $this->producerRepository->findBy(['category_id' => $value])->fetchPairs('id', 'name');
        $this['demandForm']['items'][$container]['producer_id']->setItems($producers);
        $this->redrawControl();
    }


    /***/
    public function handleUpdateProducts($value, $container)
    {
        $products = $this->productRepository->findBy(['producer_id' => $value])->fetchPairs('id', 'name');
        $this['demandForm']['items'][$container]['product_id']->setItems($products);
        $this->redrawControl('item-' . $container);
    }
?>

Latte

{block content}
	{form demandForm}
		<div class="form-group" n:snippet="items">
			{foreach $form['items']->containers as $id => $item}
				<div class="form" n:snippet="item-$id">
					{label items-$id-category_id /}
					{input items-$id-category_id}
					<br/>

					{label items-$id-producer_id /}
					{input items-$id-producer_id}
					<br/>

					{label items-$id-product_id /}
					{input items-$id-product_id}

					{include #jsCallback, id => $id, form => 'demandForm', input => $item['category_id']->name, link => updateProducers}
					{include #jsCallback, id => $id, form => 'demandForm', input => $item['producer_id']->name, link => updateProducts}
				</div>
			{/foreach}
		</div>
	{input items-add class => 'ajax'}
	{/form}
{/block}

Layout

<script>
{define #jsCallback}
	<script>
		$(function(){
			$('#'+{$control[$form]['items'][$id][$input]->htmlId}).on('change', function() {
				$.nette.ajax({
					type: 'GET',
					url: {link {$link}!},
					data: {
						'value': $(this).val(),
						'container': {$id}
					}
				});
			});
		});
	</script>
{/define}

Netvrdím že toto riešenie je asi najlepšie ako idem nato, no som začiatočník, ak existuje nato lepší spôsob rád ho uvítam, na fóre vačšinou som našiel tieto témy bez odpovede tak možno sa mne poštastí :D

Editoval johnnie (19. 2. 2016 14:22)