TreeView+CheckBoxList = CBTree

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

pre potreby administracie intranetovej aplikacie som vytvoril tuto nadstavbu TreeView

poziadavka bola moznost urcovania viditelnosti poloziet v stromovej strukture

TreeView samotne ma dobre riesenu datovu strukturu a interne fungovanie, neda sa vsak jednoducho doplnit o checkbox ku kazdej polozke a nasledne to cele pouzit vo formulari

CheckBoxList zase ma funkcionalitu ktoru som potreboval (checkbox pole vo formulari) ale nema moznost stromoveho zobrazenia

Takze som hladal a nasiel som Collapsible Checkbox Tree jQuery Plugin ktory dizajnovo riesil spojenie stromovej struktury a checkboxov

takze 2 dni som sa snazil toto vsetko dat dokopy (novy renderer do TreeView, inclu TreeView DO CBListu a pod.) ale nakoniec vznikla CBTree nadstavba pre TreeView

TreeView sluzi ako datova struktura, ale kedze sa neda zaclenit do formulara, podla CheckBoxList som vytvoril nadstavbu, ktora toto umozni

pouzitie je dost jednoduche – treba zaregistrovat rozsirenie formu:

AppForm::extensionMethod('AppForm::addCBTree', array('CBTree', 'addCBTree'));

a v tovarnicke uz potom len

$tree=new TreeView;
$tree->addLink(null, 'name', 'id', true, $this->presenter);
$tree->dataSource=$this->model->findAllCTree($this->hierarchy, $this->stredisko);
$form->addCBTree('ctree', 'filter', $tree);

pripadne doplnit nazov stlpca podla ktoreho sa riadia checkboxy (defaultne visible):

$form['ctree']->checkColumn='visible';

v DB potom treba samozrejme v tabulke doplnit bool stlpec visible
vo formulari sa potom cela struktura objavi ako jednorozmerne pole, v ktorom hodnoty su id checknutych boxov

samotna nadstavba:

<?php
/**
 * @author Pavol Hluchy
 */
class CBTree
extends FormControl
{
	/** @var Nette\Web\Html  container element template */
	protected $container;
	/** @var TreeView data */
	protected $tree;
	/** @var string */
	public $checkColumn='visible';

	/**
	 * @param  string  label
	 * @param  TreeView   options from which to choose
	 */
	public function __construct($label, TreeView $tree)
	{
		parent::__construct($label);
		$this->control->type='checkbox';
		$this->container=Html::el();
		if ($tree!==NULL) $this->setItems($tree);
	}

	/**
	 * Returns selected checkbox value.
	 * @param  bool
	 * @return mixed
	 */
	public function getValue($raw=FALSE)
	{
		return is_array($this->value)? $this->value : NULL;
	}

	/**
	 * Form container extension method. Do not call directly.
	 * @param  Form
	 * @param  string  name
	 * @param  string  label
	 * @param  array   items
	 * @return CBTree
	 */
	public static function addCBTree(Form $form, $name, $label, $tree)
	{
		return $form[$name]=new self($label, $tree);
	}

	/**
	 * Sets options from which to choose.
	 * @param  TreeView
	 * @return CBTree  provides a fluent interface
	 */
	public function setItems(TreeView $tree)
	{
		$this->tree=$tree;
		return $this;
	}
	/**
	 * Returns container HTML element template.
	 * @return Nette\Web\Html
	 */
	final public function getContainerPrototype()
	{
		return $this->container;
	}

	/**
	 * Generates control's HTML element.
	 * @param  mixed
	 * @return Nette\Web\Html
	 */
	public function getControl($key=NULL)
	{
		if ($key===NULL)
			$container=clone $this->container;
		elseif (!isset($this->tree[$key]))
			return NULL;
		$control=parent::getControl();
		$control->name.='[]';
		$id=$control->id;
		$values=$this->value===NULL? NULL : (array)$this->getValue();
		$label=Html::el('label');
		$x=Html::el('ul', array('id'=>'example'));
		foreach ($this->tree->getNodes() as $node) {
			$x->add($this->renderNode($node, $control, $label));
			}
		$container->add($x);
		return $container;
	}

	/**
	 * Generates label's HTML element.
	 * @return void
	 */
	public function getLabel($caption=NULL)
	{
		$label=parent::getLabel($caption);
		$label->for=NULL;
		return $label;
	}

	public function renderNode(TreeViewNode $node, $control, $label)
	{
		$pcontrol=clone $control;
		$li=Html::el('li');
		$nid=$node->getDataRow()->id;
		$control->id=$label->for=$control->id.'-'.$nid;
		$ck=$this->checkColumn;
		if ($node->getDataRow()->$ck)
			$control->checked='checked';
		else $control->checked=null;
		$control->value=$nid;
		$label->setText($node->getDataRow()->name);
		$li->add((string)$control.(string)$label);
		$nodes=$node->getNodes();
		if (count($nodes)) {
			$u=Html::el('ul');
			$li->add($u);
			foreach ($nodes as $n)
				$u->add($this->renderNode($n, $pcontrol, $label));
			}
		return $li;
	}
}

niektore veci by sa dali mozno este lepsie vyriesit, aktualne vsak splna vsetko co potrebujem

Honza Kuchař
Člen | 1662
+
0
-

Do extras s tím ;)

Lopo
Člen | 277
+
0
-

ked bude cas aby som sa pozrel ako sa to vobec robi :)

najblizsie planujem dorobit:

  • moznost nastavenia id kontajneroveho UL – aby sa dalo nastavit kazdemu zvlast v pripade viacerych na jednej stranke
  • generovanie vazboveho javascriptu hned pri kontajnerovom ul aby to nebolo treba rucne pisat v sablone

akekolvek pripomienky/navrhy su vitane

rokerkony
Člen | 122
+
0
-

je to vec kterou bych zrovna uvital ale skoncim hned na radku
 $tree->addLink(null, 'name', 'id', true, $this->presenter);

hlasi mi to:
Call to undefined method TreeView::addLink().

kdyz ten radek zakomentuju tak mi v tve tride hodi chybu
Call to undefined method TreeView::getNodes(). na řádku 85…

nevis kde muze byt problem?

Lopo
Člen | 277
+
0
-

honzakuchar napsal(a):

Do extras s tím ;)

je to tam :)
Nette\Extras\CBTree

rokerkony napsal(a):

je to vec kterou bych zrovna uvital ale skoncim hned na radku
 $tree->addLink(null, 'name', 'id', true, $this->presenter);

hlasi mi to:
Call to undefined method TreeView::addLink().

kdyz ten radek zakomentuju tak mi v tve tride hodi chybu
Call to undefined method TreeView::getNodes(). na řádku 85…

nevis kde muze byt problem?

mas v projekte aj TreeView ?
kedze toto je len nadstavba tak potrebuje aj samotny TreeView

Honza Kuchař
Člen | 1662
+
0
-

jeste bych pouvazoval o prejmenovani na CheckBoxTree. Z cbtree neni jasne o co se jedna (treba po pul roce v nejakym velkym projektu).

rokerkony
Člen | 122
+
0
-

mas v projekte aj TreeView ? kedze toto je len nadstavba tak potrebuje aj samotny TreeView

jj mam :-/ ve verzi 0.5.2

Lopo
Člen | 277
+
0
-

honzakuchar napsal(a):

jeste bych pouvazoval o prejmenovani na CheckBoxTree. Z cbtree neni jasne o co se jedna (treba po pul roce v nejakym velkym projektu).

mno ja bezne taketo dlhsie nazvy skracujem, CB pouzivam prave pre checkbox

kazdy si to vsak pri vlozeni do projektu moze premenovat ako uzna za vhodne – je to len jedna trieda :)

ak by to vsak bol moc velky problem … tak to premenujem

rokerkony napsal(a):

mas v projekte aj TreeView ? kedze toto je len nadstavba tak potrebuje aj samotny TreeView

jj mam :-/ ve verzi 0.5.2

ja pouzivam 0.6.0a, tak skus tu

Jod
Člen | 701
+
0
-

Lopo: Šikovný chlapec, keď už si v tom tak doma, môžeš mi s tým heplnúť, nemám moc času nazvyš :)
Mám tu par celkom dôležitých issues, ktoré viem riešiť ale nestíham, medzitým aj ony checkboxy :)

v0.6.0 je na gite: https://github.com/romcok/treeview , addons som ešte neupdatoval sry :-/

Editoval Jod (25. 2. 2010 12:06)

Lopo
Člen | 277
+
0
-

nahodene 0.2.1 – zopar malych uprav, na funkcnosti sa nic nemeni

Jod napsal(a):

Lopo: Šikovný chlapec, keď už si v tom tak doma, môžeš mi s tým heplnúť, nemám moc času nazvyš :)
Mám tu par celkom dôležitých issues, ktoré viem riešiť ale nestíham, medzitým aj ony checkboxy :)

v0.6.0 je na gite: https://github.com/romcok/treeview , addons som ešte neupdatoval sry :-/

mno … nie ze by som bol v tom zase az tak moc doma …
ale posli co treba a ked bude cas tak sa na to pozriem a uvidi sa co zbucham

Jod
Člen | 701
+
0
-

Medzi najdôležitejšie asi patria:

  • pridať checkboxy :)
  • niečo sa pokazilo pri prekreslovaní stromu, invaliduje sa celý strom miesto jednej vetvy
  • vyriešit aby sa pri ajaxovom callbacku robila len jedna query
  • popridávať užitočné eventy

Väčšinu mám premyslených, alebo viem kde je problém, len nemám čas to opraviť a pokiaľ už niečo je, je strata času to robiť dva krát.
Ak s tým chceš niečo robiť, tak najlepšie si to je forknut na githube, len s tým som ešte nerobil :)

Editoval Jod (15. 3. 2010 16:31)

Lopo
Člen | 277
+
0
-

nova verzia 0.2.2:
doplnena moznost prenastavit defaultne hodnoty parametrov jQuery pluginu checkParents,checkChildren,uncheckChildren,initialState

Michalek
Člen | 209
+
0
-

Je možný, že jsem našel chybu? :-) Nemám sloupec pojmenovaný „name“ ale „nazev_cs“ a „parentId“ ale „rodic_id“ a nevypisovalo se mi to správně…

CBTree.php, line 140

<?php
$label->setText($node->getDataRow()->name);
?>

To samý TreeViewNode, line 90

<?php
|| (!empty($this->dataRow) && $this->dataRow->id===$dataRow->parentId)
?>

Jsou tam natvrdo zadrátovaný anglický názvy, i když se to tváří nastavitelně :-) Ale jinak je to moc moc super věcička.

Lopo
Člen | 277
+
0
-

mozne to je … a mas pravdu :)

v aktualnej verzii na github-e je to uz opravene