Yii Framework Forum: CTreeView nested add delete rename with db - Yii Framework Forum

Jump to content

Page 1 of 1
  • You cannot start a new topic
  • You cannot reply to this topic

CTreeView nested add delete rename with db an implementation of CTreeView with some ideas Rate Topic: -----

#1 User is offline   gdang 

  • Junior Member
  • Pip
  • Yii
  • Group: Members
  • Posts: 37
  • Joined: 20-August 11
  • Location:Venice

Posted 25 August 2011 - 07:13 AM

I'm new of YII and it's my first project with a PHP framework, means that if I can do the things better you can write me suggestions and I'll be so happy :D

Let's start...

On my site I want to use in different controllers a CTreeViev that displays different nested elements, and I want to add, delete and rename them, I want also write less code possible and that's my idea:

for now I want only root>Corporation>Division>Person and I want to add and rename only Corporation and Division, naturally I can nest mor things

View(index.php):

prova.js is the JQuery script and navTree.css is one easy css for creating two div in the same line, now isn't important

<?php
	$cs=Yii::app()->clientScript;
	$cs->registerCoreScript('jquery');
	$cs->registerScriptFile(Yii::app()->baseUrl.'/js/prova.js');
	$cs->registerCssFile(Yii::app()->baseUrl.'/css/navTree.css');
?>

<div id="left">
<?php
$this->widget('CTreeView',array(
		'id'=>'tree',
        'data'=>$dataTree,
        'animated'=>'fast',
        'collapsed'=>'false',
        'htmlOptions'=>array(
                'class'=>'filetree',//there are some classes that ready to use
        ),

));
?>
</div>

<script>
	//here I write classes array sended by actionIndex
	<?php echo $classes; ?>
	setParams("prova",classes);
</script>


Controller (ProvaController.php):

see the attribute $classes with the list of classes that I'll nest in order and how I want to manage the operations of add, rename, delete using the id sended by the elements (classname_id -> corporation_10)
there is also the creation the initial tree, the #adders can be avery kind of element, the important that the class is "adder" and the id is right.

<?php

class ProvaController extends Controller
{
	protected $classes = array('tree','corporation','division','person'); //list of classes in order, the first is the name of the tree

	
	public function actionIndex() {
		//$datatree is the array of the tree, $classes contains the string for the istance of the array in javascript
		$this->render('index', array('dataTree'=>$this->createTree($this->classes),'classes'=>'var classes = new Array("'. join($this->classes,'","'). '");'));
	}

	public function actionAddTreeNode() {
		$id=explode("_",$_GET['id']);
		$key = array_search($id[0],$this->classes)+1; //the addercontains the name of upper class, means that i must watch next object on classes
		switch($this->classes[$key])
		{
			case 'corporation';
				$corp=new Corporation;
				$corp->name ='new corporation';
				$corp->concurrency=true;
				$corp->save();
			break;
			case 'division';
				$div=new Division;
				$div->name ='new division';
				$div->corporation_id=$id[1];
				$div->save();
			break;
			default:
				return false;
			break;
		}
		echo Yii::app()->db->lastInsertID; //id to nsert on jtree
	}

	public function actionRenameTreeNode() {
		$id=explode("_",$_GET['id']);
		switch($id[0])
		{
			case 'corporation';
				$model=Corporation::model()->findByPk($id[1]);
			break;
			case 'division';
				$model=Division::model()->findByPk($id[1]);
			break;
			default:
				return false;
			break;
		}
		$model->name =$_GET['name'];
		$model->save();
	}

	public function actionRemoveTreeNode() {
		$id=explode("_",$_GET['id']);
		switch($id[0])
		{
			case 'corporation';
				Division::model()->deleteAll('corporation_id='.$id[1]);
				Corporation::model()->deleteByPk($id[1]);
			break;
			case 'division';
				Division::model()->deleteByPk($id[1]);
			break;
			default:
				return false;
			break;
		}
	}
 
 
	//creation of the tree with arrays, see .adder
	private function createTree()
	{
		$tree=array();
		$addCorporation=array('text'=>'<a class="adder" id="tree">Add</a>'); //adder can be everything, important: class and id
		array_push($tree,$addCorporation);
		$corporations = Corporation::model()->findAll();
		foreach($corporations as $corp)
		{
			$corporationNode=array('text'=>'<span class="node" id="corporation_'.$corp->id.'">'.$corp->name.'</span>'); //class=node, id=class_id
			
			$addDivision=array('text'=>'<a class="adder" id="corporation_'.$corp->id.'">Add</a>');
			$divisions = Division::model()->findAll('corporation_id='.$corp->id);
							
			$corporationNode['children']=array();
			array_push($corporationNode['children'],$addDivision);
			
			foreach($divisions as $div)
				array_push($corporationNode['children'],array('text'=>'<span class="node" id="division_'.$div->id.'">'.$div->name.'</span>'));

			array_push($tree,$corporationNode);
		}
		return $tree;
	}
}
?>


The Jquery script(prova.js):

the important classes are: adder, renamer, deleter, node. The first tree are selfexplained the node is an element that can be changed or deleted.

var controller; //controller name for calling
//actions name for calling
var actionAdd='addTreeNode'; 
var actionDelete='removeTreeNode';
var actionRename='renameTreeNode';
//the class names passed from the view
var nodes;

function setParams(cont,ns){ //give parameters
	controller=cont;
	nodes=ns;
}

function getRow(cl, id){ //obtain rows with id class_id
	return $("#"+cl+"_"+id);
}

function addNode(id, newId){ //add new rows
	var el="";
	var str="";
	id=id.split('_');

	if(id[0]==nodes[0])
		el=$("#"+nodes[0]); //root id=treeName
	else
		el=getRow(id[0],id[1]).parent().children("ul"); //other case example id="classNotRoot_#"
		
	str='<li><span class="node "id="'+nodes[nodes.indexOf(id[0])+1]+'_'+ newId +'">new '+ nodes[nodes.indexOf(id[0])+1] +'</span>';
	
	if(id[0]!=nodes[nodes.length-3]) //isn't one leaf <------------------you decide here where do you watnt stop
		str= str + '<ul><li><a class="adder" id="'+nodes[nodes.indexOf(id[0])+1]+'_'+ newId +'">Add</a></li></ul>';
	str= str + '</li>';
	branches = $(str).appendTo(el); //create new element
	$("#"+nodes[0]).treeview({add: branches}); //added to tree
	return true;
}

function pushRenameDelete(id) //write on the node add and remove the rename/delete options
{
	el = id.split("_");
	el = getRow(el[0],el[1]);
	if(!el.children("a").text())
		el.html(el.html()+' <a href="javascript:inputRename(\''+id+'\')">rename</a> <a class="deleter" id="'+ id +'" href="#">delete</a>');
	else if(el.children("a").text()!="change")
		el.children("a").remove();
}

function inputRename(id) //write the textfield on the node (called by rename, see function pushRenameDelete)
{
	el = id.split("_");
	el = getRow(el[0],el[1]);
	el.children("a").remove(); //remove rename delete
	el.html('<input type="text" value="'+el.text()+'"><a class="renamer" id="'+ id +'"href="#">change</a>');
}

function setName(id,name)
{
	el=id.split("_");
	getRow(el[0],el[1]).html(name);
}

function delNode(id)
{
	id=id.split("_");
	branches = getRow(id[0],id[1]).parent();
	$("#"+nodes[0]).treeview({remove: branches});
}

//here I watch events and I do the actions that interact with controller
$(document).ready(function() {
	$('.adder').live('click',function(e){
		var id=$(this).closest('.adder').attr('id');
		$.get("index.php?r="+controller+"/"+actionAdd,{'id':id},function(newId){
			addNode(id,newId);
		});
	});
	$('.renamer').live('click',function(e){
		var id=$(this).closest('.renamer').attr('id');
		var name=$("#"+id).children("input").val()
		$.get("index.php?r="+controller+"/"+actionRename,{'id':id, 'name':name},function(){
			setName(id,name);
		});
	});
	$('.deleter').live('click',function(e){
		var id=$(this).closest('.deleter').attr('id');
		$.get("index.php?r="+controller+"/"+actionDelete,{'id':id},function(){
			delNode(id);
		});
	});
	$('.node').live('click',function(e){
		pushRenameDelete($(this).closest('.node').attr('id'));
		//here i can add the code for call the pages in another div near this tree
	});
});	


That's all, I hope that the comments are OK and that's useful to someone
I'm beautiful and I dance well!
0

#2 User is offline   陈文杰 

  • Newbie
  • Yii
  • Group: Members
  • Posts: 1
  • Joined: 12-October 14

  Posted 12 October 2014 - 09:49 AM

Thank you for your example!I am Chinese and my English is not very good!

I have a few questions.
1.how to contact database and show in the Controller

This is my table in the database

DROP TABLE IF EXISTS `coverage`;
CREATE TABLE `coverage` (
`id` int(10) unsigned NOT NULL auto_increment,
`pid` int(10) unsigned default NULL,
`coverageName` varchar(100) default NULL,
PRIMARY KEY (`id`),
KEY `pid` (`pid`)
) ENGINE=InnoDB AUTO_INCREMENT=20 DEFAULT CHARSET=utf8;

INSERT INTO `coverage` VALUES ('16', null, 'total');
INSERT INTO `coverage` VALUES ('17', '16', 'class01');
INSERT INTO `coverage` VALUES ('18', null, 'class');
INSERT INTO `coverage` VALUES ('19', '17', 'class02');

how to show it in the view on your way use my table.
Can you help me?
0

Share this topic:


Page 1 of 1
  • You cannot start a new topic
  • You cannot reply to this topic

1 User(s) are reading this topic
0 members, 1 guests, 0 anonymous users