Hello wartur, I'm back to say thanks for your awesome job!
It's just the very extension suit my requirement.
classRealTreeSelectRelationWidgetextendsCInputWidget{
/**
* @var boolean if true, then this node and all children will remove from select input
*/public $deleteHimself = true;
/**
* @var int if larger, then more space on each tree level
*/public $spaceMultiplier = 2;
/**
* @var mixed text layout if option not select. Default is "(Select parent)".
* You can change text this or use Yii:t
*/public $emptyText = null;
/**
* @var boolean using ram cache mechanism in RealActiveRecordTreeBehavior
*/public $useCacheInternal = true;
public $relationModel = null;
publicfunctioninit(){
parent::init();
}
publicfunctionrun(){
list($name, $id) = $this->resolveNameID();
echo CHtml::activeDropDownList($this->model, $this->attribute, $this->recursiveGenerateSelect(), array_merge(array(
'encode' => false,
'empty' => $this->emptyText,
'name' => $name,
'id' => $id), $this->htmlOptions));
}
/**
* Generate tree data input point
* @return array key => name pair
*/publicfunctionrecursiveGenerateSelect(){
$exeptid = $this->deleteHimself ? $this->relationModel->getPrimaryKey() : 0;
// need walk around all tree, cache itif($this->useCacheInternal) {
$this->relationModel->loadAllTreeCache();
}
return$this->recursiveGenerateOpgrouptedSelect($this->relationModel->getRootline(), $exeptid, 0);
}
/**
* Recursive generate tree data
* @param CActiveRecord[] $items part of tree nodes
* @param int $exeptid node pk which will remove from options with subnodes
* @param int $level tree level
* @return array part of data
*/protectedfunctionrecursiveGenerateOpgrouptedSelect($items, $exeptid, $level){
$result = array();
$bspResult = str_repeat(' ', $level * $this->spaceMultiplier);
foreach ($items as $entry) {
if ($exeptid == $entry->getPrimaryKey()) { // let exeptid and all brunchcontinue;
}
$result[$entry->getPrimaryKey()] = $bspResult . $entry->getNodeName();
if ($entry->getChildExists($this->useCacheInternal)) {
$result += $this->recursiveGenerateOpgrouptedSelect($entry->getChildren(), $exeptid, $level + 1);
}
}
return $result;
}
}
And I made a minor change base on RealTreeSelectWidget to make it support relation model. Haven't been fully tested yet, it just work fine in my other case.
User Contributed Notes 2
Supporting relation model
Hello wartur, I'm back to say thanks for your awesome job!
It's just the very extension suit my requirement.
class RealTreeSelectRelationWidget extends CInputWidget { /** * @var boolean if true, then this node and all children will remove from select input */ public $deleteHimself = true; /** * @var int if larger, then more space on each tree level */ public $spaceMultiplier = 2; /** * @var mixed text layout if option not select. Default is "(Select parent)". * You can change text this or use Yii:t */ public $emptyText = null; /** * @var boolean using ram cache mechanism in RealActiveRecordTreeBehavior */ public $useCacheInternal = true; public $relationModel = null; public function init() { parent::init(); } public function run() { list($name, $id) = $this->resolveNameID(); echo CHtml::activeDropDownList($this->model, $this->attribute, $this->recursiveGenerateSelect(), array_merge(array( 'encode' => false, 'empty' => $this->emptyText, 'name' => $name, 'id' => $id), $this->htmlOptions)); } /** * Generate tree data input point * @return array key => name pair */ public function recursiveGenerateSelect() { $exeptid = $this->deleteHimself ? $this->relationModel->getPrimaryKey() : 0; // need walk around all tree, cache it if($this->useCacheInternal) { $this->relationModel->loadAllTreeCache(); } return $this->recursiveGenerateOpgrouptedSelect($this->relationModel->getRootline(), $exeptid, 0); } /** * Recursive generate tree data * @param CActiveRecord[] $items part of tree nodes * @param int $exeptid node pk which will remove from options with subnodes * @param int $level tree level * @return array part of data */ protected function recursiveGenerateOpgrouptedSelect($items, $exeptid, $level) { $result = array(); $bspResult = str_repeat(' ', $level * $this->spaceMultiplier); foreach ($items as $entry) { if ($exeptid == $entry->getPrimaryKey()) { // let exeptid and all brunch continue; } $result[$entry->getPrimaryKey()] = $bspResult . $entry->getNodeName(); if ($entry->getChildExists($this->useCacheInternal)) { $result += $this->recursiveGenerateOpgrouptedSelect($entry->getChildren(), $exeptid, $level + 1); } } return $result; } }And I made a minor change base on RealTreeSelectWidget to make it support relation model. Haven't been fully tested yet, it just work fine in my other case.
$this->widget('RealTreeSelectRelationWidget', array( 'model' => $model, 'relationModel'=> Group::model(), //or $model->group in update scenario 'attribute' => 'group_id', 'deleteHimself' => true, 'spaceMultiplier' => 2, 'emptyText' => Yii::t('app', 'All'), ));Re: yanhui
Thanks for report
I have decided this issue in version 2.0.0. In addition, I added the possibility of multiple attach. You can take last version from git
Leave a comment
If you have any questions, please ask in the forum instead.
Join the conversation to share a note.