Replicator – addCreateOnClick – Nefunguje s dynamickými snippetami

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

Zdravím,

mám problém s pluginem Kdyby/Replicator.

Mám formulář, kde jsou AJAXem přidávány nové řádky. Každý řádek má 3 selectboxy, jejichž obsah je na sobě v rámci řádku navzájem závislý. Jejich obsah je refreshován přes signály a invalidaci dynamických snippet.

V tomto však je problém, jelikož dynamické snippety zlobí s metodou addCreateOnClick (z balíku Kdyby/Replicator), která je navázaná na tlačítko, které přidává nové řádky do formuláře. Dynamické snippety ho zblbnou a zavoláním statické nad těmito dynamickými invaliduje pouze dynamické uvnitř, což je pro tuto akci nežádoucí (tyto dynamické jsou tam pouze pro refresh obsahu selectboxů).

Proto se ptám, nevíte někdo, jak zajistit to, aby se klikem na add button přidal nový řádek, a zároveň byly zachovány volby selectboxů z řádků výše?

Zde je kód:

<?php
	public function handleTableChange($name, $group){
		if(isset($name) && isset($group)){
			$columns = $this->getService('ruleModel')->provideColumnValues($name);
			reset($columns);
			$conditions = $this->getService('ruleModel')->provideAllowedActions($name, current($columns));

            $this['newRuleForm']['rules'][$group]['column']->setItems($columns);
			$this['newRuleForm']['rules'][$group]['condition']->setItems($conditions);
		}

		$this->invalidateControl('rulesForm');
	}

	public function handleColumnChange($name, $group, $parent){
		if(isset($name) && isset($group) && isset($parent)){
			$columns = $this->getService('ruleModel')->provideColumnValues($parent);
			$conditions = $this->getService('ruleModel')->provideAllowedActions($parent, $name);

			$this['newRuleForm']['rules'][$group]['column']
					->setItems($columns)
					->setDefaultValue($name);
			$this['newRuleForm']['rules'][$group]['condition']->setItems($conditions);
		}

		$this->invalidateControl('rulesForm');
	}

	public function createComponentNewRuleForm($name){
		$form = new Form;

		$presenter = $this;
		$invalidateCallback = function() use($presenter){
			/** @var \Nette\Application\UI\Presenter $presenter */
			$presenter->invalidateControl('rulesForm');
		};
		$tables = $this->getService('ruleModel')->provideTableNames();
		reset($tables);
		$columns = $this->getService('ruleModel')->provideColumnValues(current($tables));
		reset($columns);
		$conditions = $this->getService('ruleModel')->provideAllowedActions(current($tables), current($columns));

		$replicator = $form->addDynamic('rules', function(Container $container) use($invalidateCallback, $tables, $columns, $conditions, $presenter){
			$container->addSubmit('remove', 'X')
				->setAttribute('class', 'ajax')
				->addRemoveOnClick($invalidateCallback);
			$container->addSelect('table', 'Table', $tables);
			$container->addSelect('column', 'Column', $columns);
			$container->addSelect('condition', 'Condition', $conditions);
			$container->addText('value', 'Value');

		}, 1);

		$replicator->addSubmit('add', 'Add')
			//->setAttribute('class', 'ajax')
			->addCreateOnClick($invalidateCallback);
		$form->addSubmit('send', 'OK')
				->setAttribute('class', 'ajax')
				->onClick[] = callback($this, 'NewRuleFormSubmitted');

		$this[$name] = $form;
        //$form->action .= '#snippet--usersForm';
		return $form;
	}
?>
{block content}
    <h1 n:block=title>New Rule</h1>

	{snippet rulesForm}
		{form newRuleForm}
			{*{control newRuleForm}*}

			<table class="rules-form">
				<tr><td>Remove</td><td>Table</td><td>Column</td><td>Condition</td><td>Value</td></tr>
				{foreach $form['rules']->containers as $id => $rule}
					<tr>
						<td>{input rules-$id-remove}</td>
						<td>{input rules-$id-table}</td>
						<td>
							{snippet column-$id}
								{input rules-$id-column}
							{/snippet}
						</td>
						<td>
							{snippet condition-$id}
								{input rules-$id-condition}
							{/snippet}
						</td>
						<td>{input rules-$id-value}</td>
					</tr>
				{/foreach}
				<tr><td>{input rules-add}</td><td>{input send}</td></tr>
			</table>
			<script type="text/javascript">
				{foreach $form['rules']->containers as $i => $rule}
			</script>
				{snippet callback-$i}
					<script type='text/javascript'>
					{include #jsCallback, id => $i, input => $rule['table']->name, link => tableChange}
					{include #jsCallback, id => $i, input => $rule['column']->name, link => columnChange, parent => 1}
					</script>
				{/snippet}
			<script type='text/javascript'>
				{/foreach}
			</script>
		{/form}
	{/snippet}
{/block}

{define #jsCallback}
	$('#{$control["newRuleForm"]['rules'][$id][$input]->htmlId}').on('change', function(){
		link = '{link $link."!"}';
		link = link.replace("&amp;","&");
		$.nette.ajax({
			type: 'GET',
			url: link,
			data: {
				'name': $(this).val(),
				'group': {$id}
				{if isset($parent)}
					,'parent': $(this).parent().parent().prev().find("select").eq(0).val()
				{/if}
			}
		});
	});
{/define}

Pokud nikdo nevíte, vykašlu se na Replicator a vygeneruju si 15 řádků, který v CSSku skryju a budu je javascriptem odhalovat (pěkně po staru). Už se s tím konceptem drbu 14 dní a dochází síly :)

Editoval kastanekdavid (25. 12. 2013 21:28)