Put A Static Tree (Array) In A Dynamic One (Ajax) According Node's Type

Hi all,

I design a ctreeview from a table which is working very well through ajax request. Now, each of my node corresponds to a type defined by an integer. My wish would be to put a static tree, an array i think, in a node if his type is, for example, equal to 2.

He is my controller function :


  public function actionAjaxFillTree(){

    if (!Yii::app()->request->isAjaxRequest) {

      exit();

    }


    $parentId = "NULL";

    if (isset($_GET['root']) && $_GET['root'] !== 'source') {

      $parentId = (int) $_GET['root'];

    }

    else {

      $parentId = '0';

    }

    

    $sql = 'select distinct on (m1.id) '

           .'m1.id, m1.name, m2.id is not null as haschildren, m1.type '

           .'from treemenu as m1 '

           .'left join treemenu as m2 on m1.id=m2.parent_id '

           .'where m1.parent_id='.$parentId.';' ;  


    $req = Yii::app()->db->createCommand($sql);

    $children = $req->queryAll();

    $children = $this->createLinks($children,$parentId);

    echo str_replace(

      '"haschildren":"0"',

      '"haschildren":false',

      CTreeView::saveDataAsJson($children)

    );

    exit();

  }

  

  private function createLinks($children,$parentId){

          $return = array();

          

          if($parentId != '0')

            $model=$this->loadModel($parentId);


          else

            $model=$this->loadModel('1');

            

          if ($model->type == '1')

          {

            foreach($children AS $key=>$value){

              $child = array();

              $child['id']=$value['id'];

              $child['text']=$value['name'];

              if($value['type']=='1') 

              { 

                $child['hasChildren']=true;

              }

              else

              {

                $child['hasChildren']=$value['haschildren'];

              }

                

              /*if(strlen($value['url'])>0){

                      $child['text'] = $this->format($value['text'],$value['url'],Yii::app()->request->url);

              }*/

                    

              $return[] = $child;

            }

          }

          

          elseif ($model->type == '2')

          {

            $return[] = array(

              array('text'=>'First','children'=>array(

                array('text'=>'Some Point', ),

                array('text'=>'Another Point', 'children'=>array(

                  array('text'=>'Sub points are good',  'children'=>array(

                    array('text'=>'Like this'),

                    array('text'=>'Or even like this'),

                  )),

                  array('text'=>'Sub points are bad'),

                  array('text'=>'Sub points are sub points'),

                )),

                array('text'=>'More stuff'),

                array('text'=>'Also this'),

            )),

            array('text'=>'Second'),

            array('text'=>'Third', 'children'=>array(

                array('text'=>'It goes on', ),

                array('text'=>'and on...',)

                    )),

            );

          }

          

          //if ($model->type != '2') 

          { // Add new 'New entry' line

            $child = array();

            $child['id']=0;

            $img = '<img id="treeImg1" src="/myNewAppTest/images/add.gif" height="10px" width="10px">';

            $child['text'] = sprintf('<span>%s</span>',CHtml::link(($img." New entry"),"",array('onclick'=>"{updateElement('".$parentId."','".$this->createUrl('')."','treemenu-grid','#dialogTreemenu'); $('#dialogTreemenu').dialog('open');}")));

            $child['hasChildren']=false;

            $return[] = $child;

          }

          

          return $return;

  }

and here my div


<?php            $this->widget(

                    'CTreeView',

                    array(

                            'animated'=>'fast', //quick animation

                            'collapsed' => false,

                            'url' => array('/treemenu/ajaxFillTree'),

                            'persist' => 'cookie',

                            'cookieId' => 'group-tree',

                            'htmlOptions'=>array(

                                    'class'=>'treeview-grey',

                            )

                    )

            );

?>

My tree works very well except that I didn’t succeed to get my static tree shaped by the array. Indeed when I creat a node with a type 2, it’s not watched as a nod but as a simple children.

Do you have an Idea ? I don’t want to put all my array entries in my table.

thanks.

Try CMap::mergeArray($array1, $array2)

thanks for your quick reply, I tried what you suggested but didn’t work exactly like I would. To be more precise, I would like, when I click upon one of my specific nodes to show a tree hard coded in my function.

One of my main Idea would be to distinguish different type of node… I’ll call the first one “type 1” and the second one “type 2”. When I click on type’s 1 node I execute the sql request to display his children, and when I click on type’s 2 node, I don’t execute the sql request but instead I display a tree hard coded (well, an array in fact) in my function. until there, I succeeded to display a hard coded tree but only with one level… I don’t know how to do if I want to have in my hard coded tree many levels. So The problems come when I want to develop one of the node in the hard coded tree… from here I don’t know exactly how to do.

The easiest would be to display a tree fully collapsed that I wrote in my function but I didn’t succeed until there. So if you have any ideas.

Hope I got clearer here =)

Thanks by advance

here is my new code controller :


public function actionAjaxFillTree(){

    if (!Yii::app()->request->isAjaxRequest) {

      exit();

    }


    $parentId = "NULL";

    if (isset($_GET['root']) && $_GET['root'] !== 'source') {

      $parentId = (int) $_GET['root'];

      $model=$this->loadModel($parentId);

    }

    else {

      $parentId = '0';

      $model=$this->loadModel('20');

    }

    

    if($model->type == '1' or $parentId=='0')

    {

      $sql = 'select distinct on (m1.id) '

             .'m1.id, m1.name, m2.id is not null as haschildren, m1.type '

             .'from treemenu as m1 '

             .'left join treemenu as m2 on m1.id=m2.parent_id '

             .'where m1.parent_id='.$parentId.';' ;  


      $req = Yii::app()->db->createCommand($sql);

      $children = $req->queryAll();

      $children = $this->createLinks($children,$parentId);

      echo str_replace(

        '"haschildren":"0"',

        '"haschildren":false',

        CTreeView::saveDataAsJson($children)

      );

    }

    

    elseif($model->type =='2')

    {

      $children = array(array("id"=>'-2',"name"=>"node 1","haschildren"=>true,),

                        array("id"=>'-3',"name"=>"node 2","haschildren"=>true),

                        array("id"=>'-4',"name"=>"node 3","haschildren"=>true),

);

      $children = $this->createLinks($children,$parentId);

      echo str_replace(

        '"haschildren":"0"',

        '"haschildren":false',

        CTreeView::saveDataAsJson($children)

      );

    }

    exit();

  }

  

  private function createLinks($children,$parentId){

          $return = array();

          

            foreach($children AS $key=>$value){

              $child = array();

              $child['id']=$value['id'];

              $child['text']=$value['name'];

              //if($value['type']=='1') 

              { 

                $child['hasChildren']=true;

              }

              //else

              {

              //  $child['hasChildren']=$value['haschildren'];

              }

              

              /*if(strlen($value['url'])>0){

                      $child['text'] = $this->format($value['text'],$value['url'],Yii::app()->request->url);

              }*/

                    

              $return[] = $child;

            }

          //}

          

          { // Add new 'New entry' line

            $child = array();

            $child['id']=0;

            $img = '<img id="treeImg1" src="/myNewAppTest/images/add.gif" height="10px" width="10px">';

            $child['text'] = sprintf('<span>%s</span>',CHtml::link(($img." New entry"),"",array('onclick'=>"{updateElement('".$parentId."','".$this->createUrl('')."','treemenu-grid','#dialogTreemenu'); $('#dialogTreemenu').dialog('open');}")));

            $child['hasChildren']=false;

            $return[] = $child;

          }

          

          return $return;

  }

So the array you can see when type = 2 is well displayed… but as you saw, every nodes have children but I don’t know how to implement it. The easiest would be to write one only array with the children of “node 1”, “node 2”, and “node 3” then I display all the tree in one click… but I don’t succeed.

Hi all, I finally succeeded, watching precisely what was ‘SaveDataAsJson’ function at this link http://www.yiiframework.com/doc/api/1.1/CTreeView#data-detail I could have built my array like waited.

thanks