Categories > TinyButStrong general >

TBS and Treeview from Database

The forum is closed. Please use Stack Overflow for submitting new questions. Use tags: tinybutstrong , opentbs
By: Keith Silva
Date: 2006-09-02
Time: 01:20

TBS and Treeview from Database

Has anyone used TBS to produce a treeview using data from a database? If so, perhaps you could provide an example. Did you use client-side Javascript to expand and collapse the nodes? Any examples, code or assistance you can provide would be appreciated.

Thanks, Keith Silva
By: Skrol29
Date: 2006-09-03
Time: 20:20

Re: TBS and Treeview from Database

Hello,

Tree presentation is something that can be difficult to produce because Database system themselfs don't make it easy. You can find several threads on this forum about some ways of making it with TBS (use the search tool).
But there is a project to offer a nicer solution with a TBS plug-in. I'm still working on it.
By: Keith Silva
Date: 2006-09-04
Time: 07:15

Re: TBS and Treeview from Database

Thank you for the reply. Before I posted my message, I searched the forum using the keyword "treeview" which did not return any threads. In response to your reply I searched using the keyord "tree" and found a lot to read! Thanks for your help.

Regards, Keith Silva
By: Rudy
Date: 2011-04-06
Time: 17:19

Re: TBS and Treeview from Database

Hi Skrol,

But there is a project to offer a nicer solution with a TBS plug-in. I'm still working on it.

is there any update on this mysterious plugin? :) I'm REALLY interested in a finally easy way to merge tree menus without bloating code with brain-cracking lineage logic, using subqueries or faking a tree with indentation.

I always have classic MySQL tree structures with id and parentid and fast enough views displaying it nicely with id, parentid, depth and caption - would be great to be able to merge it with one mergeblock-statement like tables.

Thanks
Rudy
By: Skrol29
Date: 2011-04-06
Time: 22:02

Re: TBS and Treeview from Database

Wow.. you're digging up an old topic :)

The plug-in has been abandoned because the problem is solved by the tip & trics that you can found here:
http://tinybutstrong.com/forum.php?thr=1833
By: Rudy
Date: 2011-04-07
Time: 08:13

Re: TBS and Treeview from Database

Hi Skrol,

yes I like digging in the past :) It's that I'm using that method you linked to all the time, but it's not what I'm after. With that method, I have to save the subblock in a global variable (which is the ugliest part), delete that block, merge the items with depth=0 and then use subqueries for the tree. Again, without lineage, is it possible to achieve same thing using a reusable ondata-function and one single mergeblock to generate a tree? Let's forget about the parentid, it really shouldn't matter because I'm trying to avoid subqueries - if I have a plain array with a field "depth" which goes from 0 (main items) to x (subitems) defining how deep the item is in the tree, how can I merge it creating a hierarchical structure?

$menu = array(
  array('caption'=>'Menu 0.0.0', 'depth'=>0),
  array('caption'=>'Menu 0.1.0', 'depth'=>1),
  array('caption'=>'Menu 0.1.1', 'depth'=>2),
  array('caption'=>'Menu 1.0.0', 'depth'=>0),
  array('caption'=>'Menu 1.1.0', 'depth'=>1),
  array('caption'=>'Menu 2.0.0', 'depth'=>0)
);


<ol>
  <li>Menu 0.0.0
    <ol>
      <li>Menu 0.1.0
        <ol>
          <li>Menu 0.1.1</li>
        </ol>     
      </li>
    </ol>
  </li> 
  <li>Menu 1.0.0
    <ol>
      <li>Menu 1.1.0</li>
    </ol>
  </li>
  <li>Menu 2.0.0</li>
</ol>

Thanks for your help
Rudy
By: Rudy
Date: 2011-04-08
Time: 09:32

Re: TBS and Treeview from Database

Here's how I solve it now - I decided to go the classic way for this task, of course there is no nice editable template but alle the markup is mixed in the php. On the other hand it's pretty short, easy to understand, requires no recursion and the items (from a mysql resultset) have to be walked through only once, exactly what I wish TBS could do. I would try to write a plugin on my own and share a working example, if someone could push me in the right direction, I just don't know where to start.


$menu = array(
  array('caption'=>'Menu 0.0.0', 'depth'=>0, 'haschilds'=>1),
  array('caption'=>'Menu 0.1.0', 'depth'=>1, 'haschilds'=>0),
  array('caption'=>'Menu 0.2.0', 'depth'=>1, 'haschilds'=>1),
  array('caption'=>'Menu 0.2.1', 'depth'=>2, 'haschilds'=>0),
  array('caption'=>'Menu 0.2.2', 'depth'=>2, 'haschilds'=>0),
  array('caption'=>'Menu 1.0.0', 'depth'=>0, 'haschilds'=>1),
  array('caption'=>'Menu 1.1.0', 'depth'=>1, 'haschilds'=>0),
  array('caption'=>'Menu 1.2.0', 'depth'=>1, 'haschilds'=>0),
  array('caption'=>'Menu 2.0.0', 'depth'=>0, 'haschilds'=>1),
  array('caption'=>'Menu 2.1.0', 'depth'=>1, 'haschilds'=>1),
  array('caption'=>'Menu 2.1.1', 'depth'=>2, 'haschilds'=>0),
  array('caption'=>'Menu 2.1.2', 'depth'=>2, 'haschilds'=>0),
  array('caption'=>'Menu 2.1.3', 'depth'=>2, 'haschilds'=>0)
);

$depth = $haschildren = 0;
$markup = '<ol>';

foreach($menu as $item) {
  while ($depth-- > $item['depth']) {
    $markup .= '</li></ol>';
  }
  $depth = $item['depth'];
  $markup .= '<li>'.$item['caption'];
  if ($item['haschilds']) {
    $markup .= '<ol>';
  }
}
while ($depth-- >= 0) {
  $markup .= '</li></ol>';
}

echo $markup;


Thanks for any tips
Rudy
By: kle_py
Date: 2011-04-08
Time: 18:00

Re: TBS and Treeview from Database

here a solution i am using currently for a menu:

php like:
// one global array:
$app['menu'][0]=array('main'=>'home', 'srv'=>'main_caption1', 'inv'=>'main_caption2','rep'=>'main_caption3','rep2'=>'main_caption4');

$app['menu'][1]['main'] = array('eqtype' => 'sub_caption1', 'prv' => 'sub_caption2', 'loc' => 'sub_caption3', 'prm' => 'sub_caption4', '_2' => '<hr>', 'usr' => 'sub_caption5', 'bkup' => 'sub_caption5');
$app['menu'][1]['inv'] = array( 'hw'=>'sub_caption1', 'ports'=>'sub_caption2', 'sw'=>'sub_caption3', 'ips'=>'sub_caption4','_0' => '<hr>', 'st'=>'sub_caption5');
// and so on..

// show it:
$TBS->MergeBlock('menu0', $app['menu'][0]) ;
$TBS->MergeBlock('menu1','array', 'app[menu][1][%p1%]');
$TBS->MergeBlock('menu2','array', 'app[menu][2][%p1%]');

using a html template like:
<ul id="nav">
    <li class="top">
        <a class="top_link [var.route.0;noerr;if [val]=[menu0.$];then ' current';else '';]" href="?go=[menu0.$;block=li;]">
        <span [menu1.#;if [val]+-0;then ' class="down"';else '';]>[menu0.val]</span></a>
            <ul class="sub">
          <li><a href="?go=[menu0.$]/[menu1.$;block=li;]" [menu2.#;if [val]+-0;then ' class="fly"';else '';]>[menu1.val]</a>
            <ul [menu2.#;if [val]+-0;then ' class="fly"';else '';]>
              <li><a href="?go=[menu0.$]/[menu1.$;block=li;]">[menu2.val]</a></li>
            </ul>
          </li>
        </ul>
    </li>
</ul>

maybe this example helps in some way...

grat work skol - currently migrating to tbs3.7 ;)
By: Rudy
Date: 2011-04-10
Time: 01:21

Re: TBS and Treeview from Database

I was finally able to wrap it in a plugin which makes the merge process of trees easy. It's the first version and a little limited for the fact that the automatically added nesting containers (ol/ul) can't be changed (e.g. added attributes) during the merge process, but works for me to get quick results - I post it here maybe it's of some use.

The data structure in the example is an array, should be easy to reproduce a mysql query / view with the same data structure.

Save and include as tbs_plugin_tree.php:

<?php

/*********************************************************
  TinyButStrong plug-in: TREE
  Version 0.1a, on 2011-04-17, by Rudy
*********************************************************/

define('TBS_TREE', 'clsTbsPlugInTree');
$GLOBALS['_TBS_AutoInstallPlugIns'][] = TBS_TREE; // Auto-install

class clsTbsPlugInTree {

  private $depths = array();
  private $items = array();
  private $level = null;
  private $nested = false;
  private $endtag = null;

  public function OnInstall() {
    $this->Version = '0.1';
    return array('BeforeMergeBlock', 'OnMergeSection', 'AfterMergeBlock');
  }

  public function BeforeMergeBlock(&$TplSource, &$BlockBeg, &$BlockEnd, $PrmLst, &$DataSrc, &$LocR) {
    if (array_key_exists('nested', $PrmLst)) {
      $this->items = $this->depths = array();
      $this->endtag = trim($PrmLst['block'], '()');
      $this->nested = $PrmLst['nested'];
      $this->level = $PrmLst['level'];
      foreach ($DataSrc->RecSet as $r => & $rec) {
        $this->depths[] = $rec[$this->level];
      }
    } else {
      $this->items = $this->depths = array();
      $this->nested = false;
    }
  }

  public function OnMergeSection(&$Buffer, &$NewPart) {
    if ($this->nested) {
      $this->items[] = $NewPart;
    }
  }

  public function AfterMergeBlock(&$Buffer, &$DataSrc, &$LocR) {
    if ($this->nested) {
      $Buffer = '';
      $last = count($this->items) - 1;
      $depth = 0;
      foreach ($this->items as $i => & $item) {
        while ($depth-- > $this->depths[$i]) {
          $Buffer .= '</' . $this->nested . '></' . $this->endtag . '>';
        }
        $depth = $this->depths[$i];
        if ($i < $last && $this->depths[$i + 1] > $depth) {
          $Buffer .= substr($item, 0, strrpos($item, '</' . $this->endtag . '>')) . '<' . $this->nested . '>';
        } else {
          $Buffer .= $item;
        }
      }
      while ($depth-- > 0) {
        $Buffer .= '</' . $this->nested . '></' . $this->endtag . '>';
      }
    }
  }

}

?>


Example Use:

Template: (nested.html)
<!DOCTYPE html>
<html>
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
    <title>TBS Tree Plugin Example</title>
  </head>
  <body>
    <ol>
      <li>
        <a href="[menu.href]" class="lvl-[menu.depth]">
          [menu.caption;block=li;nested=ol;level=depth]
        </a>
      </li>
    </ol>
  </body>
</html>

The parameter "nested" has to be put in the block definition and is set to the tagname which should surround child elements (usually "ul" or "ol"). "level" tells the plugin which field in the resultset defines the depth of current element.

PHP:
<?php

error_reporting(E_ALL | E_STRICT);

require 'tbs_class.php';
require 'tbs_plugin_tree.php';

$tbs = new clsTinyButStrong;

$menu = array(
  array('caption'=>'Menu 0.0.0', 'depth'=>0, 'href'=>'#0.0.0'),
  array('caption'=>'Menu 0.1.0', 'depth'=>1, 'href'=>'#0.1.0'),
  array('caption'=>'Menu 0.2.0', 'depth'=>1, 'href'=>'#0.2.0'),
  array('caption'=>'Menu 0.2.1', 'depth'=>2, 'href'=>'#0.2.1'),
  array('caption'=>'Menu 0.2.2', 'depth'=>2, 'href'=>'#0.2.2'),
  array('caption'=>'Menu 1.0.0', 'depth'=>0, 'href'=>'#1.0.0'),
  array('caption'=>'Menu 1.1.0', 'depth'=>1, 'href'=>'#1.1.0'),
  array('caption'=>'Menu 1.2.0', 'depth'=>1, 'href'=>'#1.2.0'),
  array('caption'=>'Menu 2.0.0', 'depth'=>0, 'href'=>'#2.0.0'),
  array('caption'=>'Menu 2.1.0', 'depth'=>1, 'href'=>'#2.1.0'),
  array('caption'=>'Menu 2.1.1', 'depth'=>2, 'href'=>'#2.1.1'),
  array('caption'=>'Menu 2.1.2', 'depth'=>2, 'href'=>'#2.1.2'),
  array('caption'=>'Menu 2.1.3', 'depth'=>2, 'href'=>'#2.1.3'),
  array('caption'=>'Menu 2.2.0', 'depth'=>1, 'href'=>'#2.2.0')
);

$tbs->loadTemplate('nested.html');
$tbs->MergeBlock('menu', $menu);
$tbs->Show();

?>

Here's the (tidied) result:
<!DOCTYPE html>
<html>
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
    <title>TBS Tree Plugin Example</title>
  </head>
  <body>
  <ol>
    <li>
      <a href="#0.0.0" class="lvl-0">Menu 0.0.0</a>
      <ol>
        <li><a href="#0.1.0" class="lvl-1">Menu 0.1.0</a></li>
        <li>
          <a href="#0.2.0" class="lvl-1">Menu 0.2.0</a>
          <ol>
            <li><a href="#0.2.1" class="lvl-2">Menu 0.2.1</a></li>
            <li><a href="#0.2.2" class="lvl-2">Menu 0.2.2</a></li>
          </ol>
        </li>
      </ol>
    </li>
    <li>
      <a href="#1.0.0" class="lvl-0">Menu 1.0.0</a>
      <ol>
        <li><a href="#1.1.0" class="lvl-1">Menu 1.1.0</a></li>
        <li><a href="#1.2.0" class="lvl-1">Menu 1.2.0</a></li>
      </ol>
    </li>
    <li>
      <a href="#2.0.0" class="lvl-0">Menu 2.0.0</a>
      <ol>
        <li>
          <a href="#2.1.0" class="lvl-1">Menu 2.1.0</a>
          <ol>
            <li><a href="#2.1.1" class="lvl-2">Menu 2.1.1</a></li>
            <li><a href="#2.1.2" class="lvl-2">Menu 2.1.2</a></li>
            <li><a href="#2.1.3" class="lvl-2">Menu 2.1.3</a></li>
          </ol>
        </li>
        <li><a href="#2.2.0" class="lvl-1">Menu 2.2.0</a></li>
      </ol>
    </li>
  </ol>
</body>
</html>
By: Skrol29
Date: 2011-04-10
Time: 01:27

Re: TBS and Treeview from Database

May I publish it ?
Is it possible to have a short manual ?
By: Rudy
Date: 2011-04-10
Time: 14:53

Re: TBS and Treeview from Database

The previously posted plugin does not support database sources, it was the first try - you certainly shouldn't publish that :)
I now have a version that works with queries too, I'll mail it to you along with a mysql database example and manual in html format.