Vlastní kontrol pro správu uživatelů

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

Ahoj,
snažím se vytvořit formulářovou komponentu pro rychlou správu uživatelů a potřeboval bych trochu nakopnout. Vždycky se dostanu někam, kde narazim, že to moc jednoduše nejde.

Cílem je komponenta (nebo spíš form kontrol), která bude obsahovat multi selectbox, kde si člověk rychle nakliká uživatele. Tento selectbox bude dále přes javascript nahrazen za Select2 , aby výsledek vypadal elegantněji a ještě zlepšil použitelnost.

Kdykoli je hodnota v selectboxu změněna, tak se pod ním aktualizuje tabulka/seznam těchto lidí, kde k nim lze nastavovat různé atributy. Např. naklikám rychle uživatele a v seznamu si pak k nim můžu přiřadit role (pokud budu chtít) ← toto je příklad, cílem je, že komponenta bude obecná, takže konkrétní vlastnosti by se řešili přes callback jako např. u replicatoru/addDynamic. Po odeslání formuláře by pak $control->getValue() vracelo pole uživatelů a jejich vlastnosti.

Ve výsledku je to vlastně jenom kombinace addDynamic a MultiSelectBox. Teď ale nastává otázka, jak to co nejelegantněji sloučit do jedné komponenty? Dědit od BaseControl nebo od Container? Tady jsem našel docela dobré řešení podědit od \Nextras\Forms\ComponentControl, což se zdá jednoduché, ale opět se tam vyskytuje několik zásadních problémů – ale třeba na to jenom jdu špatně.

  • jak vygenerovat odkaz na handler této komponenty, který budu při změně selectboxu volat ajaxem?
  • jak následně invalidovat komponentu, aby se mi překreslila tabulka s novým obsahem?

Takhle to tak nějak cca funguje, ale přidávání položek do replikátoru pouze přes tlačítko, protože ani za boha nemůžu rozchodit odeslání přes ajax a následné refreshnutí

class UserSelect extends \Nextras\Forms\ComponentControl {

	public function __construct($data) {
		parent::__construct();

		$this['select'] = new \Nette\Forms\Controls\MultiSelectBox('Users', $data);
		$this['dynamic'] = new \Kdyby\Replicator\Container(function($container) {
			// test
			$container->addText('text');

		});

		$self = $this;
		$this['dynamic']->addSubmit('add')
				->setValidationScope(FALSE)
				->addCreateOnClick(function ($replicator, $container) use ($self) {
							$self->invalidateControl('users');
						});//->getControlPrototype()->class[] = "ajax";

	//	$this->template = new FileTemplate(__DIR__ . "/UserSelect.latte");
		$this->template->select = $this['select'];
		$this->template->dynamic = $this['dynamic'];
	}

	public function handleUsersChanged($data) {
		// ...
	}
}

šablona:

{!$select->getControl()}

{snippet users}
<table>
	<tr n:foreach="$dynamic->containers as $container">
		<td n:foreach="$container->getControls() as $control">{$control->getControl()}</td>
	</tr>
</table>
{/snippet}

<script>
$('#' +  {$select->getHtmlId()}).select2({
	width: 'element'
}).on("change", function(e) {
	{* nejde :(
	$.nette.ajax({
		url: {link usersChanged!},
		data: { object: 'a' },
		type: 'post'
	});*}
});
</script>