Ctreeview - Nodes From Model1, Leafs From Model2 [Solved]

Hi

I wat to implement CTreeView which will represent 2 models. It should be plain tree, where every node can have many leafs - these leafs don’t have leafs.

Model ‘Sectors’ has nodes, model ‘SubSectors’ are leafs.

For example Sector BANKING:

CTreeView :

This tree should function in the way, that if I click on any leaf, its value should propagate to corresponding textarea. Textarea also will have rows/lines functionality to enable deleting selected rows. Textarea values will be used for search.

In controller which renders the search site as far as I know I have to load models which are used on the search site:




$this->render('search',array(

   'model1'=>$model1,

   'model2'=>$model2

));



Then in search.php view I can access model1 and model2.

Now let’s assume model1 is my Sectors (nodes) model. Model2 is SubSectors (leafs). How to implement tree with such structure? Not many info found on forums. Should I have relations defined in models to do this?

I found similar topic here the code works, but it uses static defined tree.

Data for tree and leafs is being fetched from function:





protected function getData()

{

$data=array(

array("id"=>1,"name"=>"John","parents"=>

array(

	array("id"=>10,"name"=>"Mary","parents"=>

		array(

			array("id"=>100,"name"=>"Jane","parents"=>

				array(

					array("id"=>1000,"name"=>"Helene",),

					array("id"=>1001,"name"=>"Peter",),

				      )

			     )

		     )

	      )

	  )

..

..

..

return $data;



This above is nested tree, where node has leafs, leafs can have own leafs:

In my case I need just nodes, and leafs. Leafs don’t have leafs.

So static code for my needs would look like:




<?php

function getData{

        $data=array(

		array("id"=>1,"name"=>"John","parents"=>

                        array(

                               array("id"=>10,"name"=>"Mary")

				array("id"=>11,"name"=>"Lary")

			     )

		      )


		array("id"=>2,"name"=>"Jane","parents"=>

                        array(

                                array("id"=>20,"name"=>"Hary")

				array("id"=>21,"name"=>"Wary")

			     )

		      )

	        )

...........

.........

.....

return $data;

?>

}

How to get data from 2 models instead of writing static function?

Thank you in advance

Try below function to replace your current getData. Because you did not provide the relationship between Sectors and SubSectors, so I assume SubSector’s parent = Sectors ID.




function getNewData{

$data=array();

$sectors = $model1->findAll();


foreach($sectors AS $sector)

{

    

    $subSectors = $model2->findAllByAttributes(array('parent'=>$id));

    $subSectorArray=array();

    foreach($subSectors as $subSector)

    {

        $subSectorArray += array('id'=>$subSector->id,'name'=>$subSector->name);

    }

    

    $data += array('id'=>$sector->id,'name'=>$sector->name, 'paraents'=>$subSectorArray);


}


return $data;

}



Thank you for your input. I was trying to get your code working, but somehow:


$data += array('id'=>$sector->id,'name'=>$sector->name, 'parents'=>$subSectorArray);

was returning only first row in array, although the foreach loop was OK.

I modified the function getNewData() like this:




	function getNewData() {

	

	$data = array();

	$sectors_temp = array();

	$subsectors_temp = array();

	$dictsectors = DictSectors::model()->findAll();

	$indx = -1;

	foreach($dictsectors as $sector)

	{

		$indx++;

		$dictsubsectors = DictSubsectors::model()->findAllByAttributes(array('id_sector'=>$id));

		$subSectorArray = array();

		foreach($dictsubsectors as $subSector)

		{

			$subsectors_temp['id_sector']=$subSector->id;

			$subsectors_temp['name_en']=$subSector->name_en;

			$subSectorArray[] = $subsectors_temp;

		}


		$sectors_temp['id'] = $sector->id;

		$sectors_temp['name_en'] = $sector->name_en;

		$sectors_temp['parents'] = $subSectorArray;

		$data[] = $sectors_temp;

	}


        return $data;


	}



I use different technique to add elements to multidimensional array:




		$sectors_temp['id'] = $sector->id;

		$sectors_temp['name_en'] = $sector->name_en;

		$data[] = $sectors_temp;



adding element to first column [‘id’] of temp array, adding element to second column of temp array [‘name_en’] and then assiging temp array to result array.

I was also trying to use index in which is not accessible in foreach loop. So I declared $indx=-1; before the foreach loop. Then inside the loop I add 1, so first $indx in the loop has value of 0 (zero).

The only problem I have is with $dictsubsectors model. In line:




$dictsubsectors = DictSubsectors::model()->findAllByAttributes(array('id_sector'=>$id)); //// what is $id here <img src='http://www.yiiframework.com/forum/public/style_emoticons/default/huh.gif' class='bbc_emoticon' alt='???' />?



to the array $dictsubsectors there is assigned model DictSubsectors with criteria ‘id_sector’=>$id. And it is not working. I don’t get it. To remind id_sector of model DictSubsectors equals id of DictSectors.

When searching in DictSubsectors this way:




$dictsubsectors = DictSubsectors::model()->findAllByAttributes(array('id_sector'=>$id));



I print_r this array:

When searching in DictSubsectors this way:




$dictsubsectors = DictSubsectors::model()->findAll();



Which obviously is wrong (I need related data from DictSubsectors not all). I get this array:

DictSectors model:

DictSubsectors model:

Any idea how to retrieve related data?




$dictsubsectors = DictSubsectors::model()->findAllByAttributes(array('id_sector'=>$id));



What is $id?

====

UPDATE Got it!




	function getNewData() {

	

	$data = array();

	$sectors_temp = array();

	$subsectors_temp = array();

	$dictsectors = DictSectors::model()->findAll();

	$indx = -1;

	foreach($dictsectors as $sector)

	{

		$indx++;

		$dictsubsectors = DictSubsectors::model()->findAllByAttributes(array('id_sector'=>$id));

		$subSectorArray = array();

		foreach($dictsubsectors as $subSector)

		{

			$subsectors_temp['id_sector']=$subSector->id;

			$subsectors_temp['name_en']=$subSector->name_en;

			$subSectorArray[] = $subsectors_temp;

		}


		$sectors_temp['id'] = $sector->id;

		$sectors_temp['name_en'] = $sector->name_en;

		$sectors_temp['parents'] = $subSectorArray;

		$data[] = $sectors_temp;

	}


        return $data;


	}



$dictsubsectors = DictSubsectors::model()->findAllByAttributes(array(‘id_sector’=>$sector[‘id’]));

Now there is a CTreeView:

:rolleyes:

Now I have to implement leafs as a links, to move leafs values onclick to textarea and more… but this will be bread and butter :rolleyes: This tree was tough.

Thank you again.

Very good to know you solve the problem, I also can learn form your code. Very nice! :rolleyes:

I was fighting hard half of the night :rolleyes: I used code provided by you, but I changed the way the arrays are filled. Hope anyone finds this code useful.