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.
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
If you have any questions, please ask in the forum instead.
Signup or Login in order to comment.