How To : Parent Child Tree

Hi everybody,

I have another problem with my app:

Here my table

item

id

name

parentId

I want to have a CGRIDVIEW with search of every item I can attach to another item ($item), for that, the condition should be :

-not the same id (id <> $item->id)

-the parentId is null or is id of the issue (parentId IS NULL OR parentId = $item->id)

The problem : I miss another condition, to exclude the parent of the parent of the parent…

How to achieve this ?

CONTROLLER




<?php


public function actionAdmin() {

        $model = new Item('search');

        $model->unsetAttributes();  // clear any default values

        if (isset($_GET['Item']))

            $model->attributes = $_GET['Item'];


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

            'model' => $model,

        ));

    }



VIEW




<?php

       $this->widget('zii.widgets.grid.CGridView', array(

        'dataProvider'=>$search->search(),

           'id'=>'item-grid',

           'selectableRows'=>2,

           'filter'=>$search,

           'columns'=>array(

               array(

                   'class'=>'CCheckBoxColumn',

                   'id'=>'chk',

                   'checked'=>'$data->parentId',

               ),

               'name',

           )

    ));?>



The problem now : it show me all the items

Thanks

Hi,

[font="Arial"][size="2"]you can write a custom query on [/size][/font][size="2"]model search function [/size]

for e.g


if (isset($this->id) && !empty($this->id)) {

  $criteria = new CDbCriteria;

   $criteria->select = 't.*';

   $criteria->condition ='u.id <>' . $this->id'

  }

Thanks yeah I did a custom search like this :

MODEL




	public function search($param = array())

	{

		// @todo Please modify the following code to remove attributes that should not be searched.


		$criteria=new CDbCriteria($param);

		$criteria->compare('name',$this->name);


		return new CActiveDataProvider($this, array(

			'criteria'=>$criteria,

		));

	}




and the VIEW




<?php

       $this->widget('zii.widgets.grid.CGridView', array(

        'dataProvider'=>$search->search(array('condition'=>"id <> $model->id and (parentId = $model->id OR parentId IS NULL)")),

           'id'=>'item-grid',

           'selectableRows'=>2,

           'filter'=>$search,

           'columns'=>array(

               array(

                   'class'=>'CCheckBoxColumn',

                   'id'=>'chk',

                   'checked'=>'$data->parentId',

               ),

               'name',

           )

    ));?>



But my condition is incomplete, It show me the parent root and I need to exclude this root parent.

How can I modify my code to exclude the root parent ?

Because If I select the root parent it will be a mess, infinite loop

Thanks

Hi,

please remove query


'dataProvider'=>$search->search(array('condition'=>"id <> $model->id and (parentId = $model->id OR parentId IS NULL)")),

to and add this line on search function


   $criteria->condition ="id <> $model->id AND (parentId = $model->id OR parentId IS NULL)"

i think your condition was right but in your case you can write the condition on gridview so every time your query execute so it’s may be infinite loop.

My condition is correct I know, but it is incomplete because with this condition I can Attach the root parent to the last child of a tree and I don’t know how to avoid that.

Can you help me ?

-A

–B

—C

-D

–E

—F

-G

-H

Suppose we are looking the item C, the item C with my condition can attach "A" (wrong), D, G and H.

You understand what I mean ?

Thanks

If I understand your problem correctly, A is the parent of B and B is the parent of C. A has no parent so the parentId for A would be null.

Since you have no more than three levels, the logic for your condition needs to be along the lines of:


 

"id <> $model->id AND (parentId = $model->id OR (parentId IS NULL and id <> $model->parentId));




Not tested.

I resolved my problem with this code behind:

In my model




<?php

public function getNotIn(){

       if($this->parent){

           return $this->id.','.$this->getRootId($this->parent);

       }  else {

           return $this->id;

       }

    }

    

    public function getRootId($equipment){

        if($equipment->parent){

            getRootId($equipment->parent);

        }else{

            return $equipment->id;

        }

    }



In the view




<?php

$this->widget('zii.widgets.grid.CGridView', array(

        'dataProvider'=>$search->search(array('condition'=>"t.id NOT IN ($model->notIn) and (parentId = $model->id OR parentId IS NULL)")),

           'id'=>'item-grid',

           'selectableRows'=>2,

           'filter'=>$search,

           'columns'=>array(

               array(

                   'class'=>'CCheckBoxColumn',

                   'id'=>'chk',

                   'checked'=>'$data->parentId',

               ),

               'name',

           )

    ));?>



Thanks everyone :)