Nested Sets + CTreeView, CDropdownList, CListBox

Выкладываем свои наработки
Аватара пользователя
timlar
Сообщения: 1382
Зарегистрирован: 2009.09.19, 17:49
Откуда: Украина, Днепропетровск
Контактная информация:

Re: Nested Sets + CTreeView, CDropdownList, CListBox

Сообщение timlar »

zvnman писал(а):Как сделать управление ветками дерева CTreeView с использованием Ajax, типа:

root
-категория_1 add|edit|del|down
--категория_1.1 add|edit|del|down|up
--категория_1.2 add|edit|del|down|up
-категория_2 add|edit|del|down|up
--категория_2.1 add|edit|del|down|up
---категория_2.1.1 add|edit|del|down|up
---категория_2.1.2 add|edit|del|down|up
Нужно писать js который будет все это обрабатывать. Я для себя писал, можно было удалять, добавлять, редактировать и перемещать узлы drug'n'drop-ом. Сейчас скрипта не осталось, поделиться не смогу. :( Но там ничего сложного.
Twitter: @timlar_ua
zvnman
Сообщения: 7
Зарегистрирован: 2010.08.30, 20:30

Re: Nested Sets + CTreeView, CDropdownList, CListBox

Сообщение zvnman »

Timlar писал(а): Нужно писать js который будет все это обрабатывать. Я для себя писал, можно было удалять, добавлять, редактировать и перемещать узлы drug'n'drop-ом. Сейчас скрипта не осталось, поделиться не смогу. :( Но там ничего сложного.
Спасибо за ответ!
Жаль что пока нет примера для реализации, я думаю что многим такой вариант управления деревом понравится.
Я не так давно начал юзать Yii и пока не могу освоить гибкость фреймворка с использованием JS.
Если сделаю доработку обязательно выложу код!
Аватара пользователя
MOTORIST
Сообщения: 245
Зарегистрирован: 2010.06.24, 10:04

Re: Nested Sets + CTreeView, CDropdownList, CListBox

Сообщение MOTORIST »

CTreeView
НЕ показывает активный пункт меню, ни класса ни id.
В сознании новичка много возможностей, в сознании эксперта — лишь несколько.
Аватара пользователя
metal
Сообщения: 12
Зарегистрирован: 2010.11.08, 05:48

Re: Nested Sets + CTreeView, CDropdownList, CListBox

Сообщение metal »

Код: Выделить всё

public function behaviors(){
    return array(
        'TreeBehavior' => array(
            'class' => 'application.extensions.nestedset.TreeBehavior',
            '_idCol' => 'id',
            '_lftCol' => 'lft',
            '_rgtCol' => 'rgt',
            '_lvlCol' => 'level',
        ),
        'TreeViewTreebehavior' => array(
            'class' => 'application.extensions.nestedset.TreeViewTreebehavior',
        )
    );
} 
Когда прописываешь поля (id, lft, rgt, level) работает нормально, но если у этих полей другие имена (category_id, category_lft и т.д.) и прописываешь их соответственно с эту функцию, запросы к БД все равно идут по полям id, lft и т.д. Возможно ли это обойти настройками, или необходимо переписывать расширение?
Аватара пользователя
timlar
Сообщения: 1382
Зарегистрирован: 2009.09.19, 17:49
Откуда: Украина, Днепропетровск
Контактная информация:

Re: Nested Sets + CTreeView, CDropdownList, CListBox

Сообщение timlar »

Я бы рекомендовал использовать вот это расширение: http://code.google.com/p/yiiext/source/ ... del/trees/. Сам с ним работаю, намного удобнее чем то, о котором говорится в данной теме.
Twitter: @timlar_ua
SpiLLeR
Сообщения: 350
Зарегистрирован: 2009.09.17, 16:47
Откуда: Санкт-Петербург
Контактная информация:

Re: Nested Sets + CTreeView, CDropdownList, CListBox

Сообщение SpiLLeR »

Не нашел по данному расширению темы, поэтому пишу сюда.
При moveAsLast и видимо других подобных действиях не вызывается afterSave(); Это сделано специально, если да, то почему?
Предупрежден - значит вооружен.
devKP.ru
Аватара пользователя
creocoder
Сообщения: 138
Зарегистрирован: 2010.01.24, 05:29
Откуда: Тамбов

Re: Nested Sets + CTreeView, CDropdownList, CListBox

Сообщение creocoder »

Да, это сделано специально. Операция переноса не вызывает событие afterSave(). В будующем планируется, что библиотека будет расширять стандартные AR события своими. Для этого метода это будет afterMove().
webgold
Сообщения: 8
Зарегистрирован: 2011.04.28, 15:32

Re: Nested Sets + CTreeView, CDropdownList, CListBox

Сообщение webgold »

Сделал все как в посте, в самом начале темы, выскакивает ошибка include(CNestedSetBehavior.php): failed to open stream: No such file or directory. В чем может быть причина?

Код: Выделить всё

/home/artem/mysite/motor.l/public/framework/YiiBase.php(396)

384      * @return boolean whether the class has been loaded successfully
385      */
386     public static function autoload($className)
387     {
388         // use include so that the error PHP file may appear
389         if(isset(self::$_coreClasses[$className]))
390             include(YII_PATH.self::$_coreClasses[$className]);
391         else if(isset(self::$classMap[$className]))
392             include(self::$classMap[$className]);
393         else
394         {
395             if(strpos($className,'\\')===false)
396                 include($className.'.php');
397             else  // class name with namespace in PHP 5.3
398             {
399                 $namespace=str_replace('\\','.',ltrim($className,'\\'));
400                 if(($path=self::getPathOfAlias($namespace))!==false)
401                     include($path.'.php');
402                 else
403                     return false;
404             }
405             return class_exists($className,false) || interface_exists($className,false);
406         }
407         return true;
408     } 
Аватара пользователя
timlar
Сообщения: 1382
Зарегистрирован: 2009.09.19, 17:49
Откуда: Украина, Днепропетровск
Контактная информация:

Re: Nested Sets + CTreeView, CDropdownList, CListBox

Сообщение timlar »

Twitter: @timlar_ua
zvnman
Сообщения: 7
Зарегистрирован: 2010.08.30, 20:30

Re: Nested Sets + CTreeView, CDropdownList, CListBox

Сообщение zvnman »

Timlar писал(а):Я бы рекомендовал использовать вот это расширение: http://code.google.com/p/yiiext/source/ ... del/trees/. Сам с ним работаю, намного удобнее чем то, о котором говорится в данной теме.
А как используя данный класс вывести дерево в CtreeView?
Аватара пользователя
Darth_Ixis
Сообщения: 105
Зарегистрирован: 2010.08.23, 10:03
Откуда: KZ, Almaty

Re: Nested Sets + CTreeView, CDropdownList, CListBox

Сообщение Darth_Ixis »

Планируется ли введение возможности отключения транзакций внутри поведения?
Из-за отсутствия данной возможности нельзя самому инициализировать транзакции, как требуется.
Например, нельзя написать так:

Код: Выделить всё

    public function actionDelete($category_id)
    {
        if (Y::app()->request->isPostRequest) {
            try {
                $category = $this->loadModel($category_id);;
                $transaction = $category->dbConnection->beginTransaction();
                    if ($category->delete())
                        $transaction->commit();
                    else
                        throw new Exception($category->getErrors());
            }
            catch (Exception $e) {
               $transaction->rollBack();
               throw new CHttpException(400, $e->getMessage());
            }
        }
        else
            throw new CHttpException(400,'Invalid request. Please do not repeat this request again.');
    } 
Аватара пользователя
aleXoid
Сообщения: 6
Зарегистрирован: 2011.01.03, 17:48

Re: Nested Sets + CTreeView, CDropdownList, CListBox

Сообщение aleXoid »

zvnman писал(а):
Timlar писал(а):Я бы рекомендовал использовать вот это расширение: http://code.google.com/p/yiiext/source/ ... del/trees/. Сам с ним работаю, намного удобнее чем то, о котором говорится в данной теме.
А как используя данный класс вывести дерево в CtreeView?

Я просто доработал, используя обсуждаемое поведение, добавив к NestedSetBehavior:

Код: Выделить всё

...
public function getTreeViewData($rootNodeId = null, $isReturnRootNode = true){
        $keyField = 'id';

        if ($rootNodeId == null)
            $rawTree = $this->getTreeWithoutManyRoots();
        else
            $rawTree = $this->getTreeWithManyRoots($rootNodeId);

        // Init variables needed for the array conversion
        $tree = array();
        $node =& $tree;
        $position = array();
        $lastitem = '';
        $depth = 1;

        foreach($rawTree as $rawItem){
            // If its a deeper item, then make it subitems of the current item
            if ($rawItem->getLevelValue() > $depth)
            {
                $position[] =& $node; //$lastitem;
                $depth = $rawItem->getLevelValue();
                $node =& $node[$lastitem]['children'];
            }
            // If its less deep item, then return to a level up
            else
            {
                while ($rawItem->getLevelValue() < $depth)
                {
                    end($position);
                    $node =& $position[key($position)];
                    array_pop($position);
                    $depth = $node[key($node)]['node']->getLevelValue();
                }
            }

            if(!$rawItem->hasChildNodes())
                $rawItem->owner->name = '<a href="/category/'.$rawItem->owner->id.'">'.$rawItem->owner->name.'</a>';
            else
                $rawItem->owner->name = '<span>'.$rawItem->owner->name.'</span>';

            // Add the item to the final array
            $node[$rawItem->$keyField]['node'] = $rawItem;
            $node[$rawItem->$keyField]['id'] = (int) 'node'.$rawItem->owner->id;
            $node[$rawItem->$keyField]['text'] = (string) $rawItem->owner->name;
            // save the last items' name
            $lastitem = $rawItem->$keyField;
        }
        // we don't care about the root node
        if (!$isReturnRootNode){
            reset($tree);
            $tree = $tree[key($tree)]['children'];
            //array_shift($tree);
        }

        return $tree;
    }


    protected function getTreeWithoutManyRoots(){
        $owner=$this->getOwner();
        return $owner->findAll(array('order'=>$this->leftAttribute));
    }


    protected function getTreeWithManyRoots($rootId){
        $owner=$this->getOwner();
        return $owner->findAll(
            array(
                 'condition' => $this->rootAttribute.'=:rootId',
                 'order'=>$this->leftAttribute,
                 'params' => array(':rootId'=>$rootId)
            ));
    }


    protected function hasChildNodes(){
        return $this->getLeftValue() != ($this->getRightValue() - 1);
    }

    protected function getLeftValue(){
        $fieldName = $this->leftAttribute;
        $owner=$this->getOwner();

        return $owner->$fieldName;
    }

    protected function getRightValue(){
        $fieldName = $this->rightAttribute;
        $owner=$this->getOwner();

        return $owner->$fieldName;
    }


    protected function getLevelValue(){
        $fieldName = $this->levelAttribute;
        $owner=$this->getOwner();

        return $owner->$fieldName;
    }


    protected function getRootValue(){
        $fieldName = $this->rootAttribute;
        $owner=$this->getOwner();

        return $owner->$fieldName;
    }

 
E.l.l.a.r
Сообщения: 12
Зарегистрирован: 2011.08.14, 16:51

Re: Nested Sets + CTreeView, CDropdownList, CListBox

Сообщение E.l.l.a.r »

Подскаите, пожалуйста, как можно построить дерево, данные для которого получены в результате выполнения хранимой процедуры? ведь в этом случае модель с ActiveRecord не создать...
rak
Сообщения: 2181
Зарегистрирован: 2010.11.02, 23:40
Контактная информация:

Re: Nested Sets + CTreeView, CDropdownList, CListBox

Сообщение rak »

почему же не создать
вот тут можно почитать об этом
http://rmcreative.ru/blog/post/yii-obek ... at-vyborki
E.l.l.a.r
Сообщения: 12
Зарегистрирован: 2011.08.14, 16:51

Re: Nested Sets + CTreeView, CDropdownList, CListBox

Сообщение E.l.l.a.r »

А каким образом тогда определить класс AR, ведь получается, что

Код: Выделить всё

public function tableName()
    {
        return 'tbl_name';
    } 
не прокатит, так как таблицы то нету, соответственно и метаданные для создания класса получить неоткуда
E.l.l.a.r
Сообщения: 12
Зарегистрирован: 2011.08.14, 16:51

Re: Nested Sets + CTreeView, CDropdownList, CListBox

Сообщение E.l.l.a.r »

Далее в этой же директории создаем (если не существует) папку /views в которой создаем файл tree.php. Открываем его и пишем:

КОД: ВЫДЕЛИТЬ ВСЁ

<?php
$this->widget('CTreeView', array(
'data'=>$tree, // передаем массив
'animated'=>'medium', // скорость анимации свертывания/развертывания
'collapsed'=>true, // если тру, то при генерации дерева, все его узлы будут свернуты
'persist'=>'location', // метод запоминания открытого узла
'unique'=>true, // если тру, то при открытии одного узла, будут закрываться остальные
'cssFile'=>'/css/treeview/jquery.treeview.css', // меняем расположение css файла (он немного подправлен мной)
));
?>
что за метод запоминания открытого узла и где он прописан? а то у меня при переходе со страницы на страницу дерево снова все сворачивается
nigredo
Сообщения: 9
Зарегистрирован: 2011.12.07, 00:33
Откуда: Донецк,Украина

Re: Nested Sets + CTreeView, CDropdownList, CListBox

Сообщение nigredo »

Здравствуйте! Начал недавно учить yii.
И вот дошло дело до древовидных категорий, скачал отсюда http://code.google.com/p/yiiext/source/ ... del/trees/, behavior и подключил. Но при сохранении пишет ошибку:
You should not use CActiveRecord::save() method when NestedSetBehavior attached.
Подскажите пожалуйста, как решить эту проблему.
Аватара пользователя
timlar
Сообщения: 1382
Зарегистрирован: 2009.09.19, 17:49
Откуда: Украина, Днепропетровск
Контактная информация:

Re: Nested Sets + CTreeView, CDropdownList, CListBox

Сообщение timlar »

nigredo писал(а):Здравствуйте! Начал недавно учить yii.
И вот дошло дело до древовидных категорий, скачал отсюда http://code.google.com/p/yiiext/source/ ... del/trees/, behavior и подключил. Но при сохранении пишет ошибку:
You should not use CActiveRecord::save() method when NestedSetBehavior attached.
Подскажите пожалуйста, как решить эту проблему.
Данное расширение теперь находится здесь: https://github.com/yiiext/nested-set-behavior
Twitter: @timlar_ua
nigredo
Сообщения: 9
Зарегистрирован: 2011.12.07, 00:33
Откуда: Донецк,Украина

Re: Nested Sets + CTreeView, CDropdownList, CListBox

Сообщение nigredo »

Спасибо! скачал с новой ссылки, все равно та же ошибка. Ошибка возникает в behavior-функции beforeSave($event), если посмотреть код функции, то получается, что переменная $this->_ignoreEvent = false, но по логике функции должна быть true.
Аватара пользователя
timlar
Сообщения: 1382
Зарегистрирован: 2009.09.19, 17:49
Откуда: Украина, Днепропетровск
Контактная информация:

Re: Nested Sets + CTreeView, CDropdownList, CListBox

Сообщение timlar »

А код сохранения можно увидеть?
Twitter: @timlar_ua
Ответить