Показать сообщение отдельно
  #3 (permalink)  
Старый 21.06.2013, 01:43
Профессор
Отправить личное сообщение для Shitbox2 Посмотреть профиль Найти все сообщения от Shitbox2
 
Регистрация: 04.10.2010
Сообщений: 571

Кусок меню, которое сейчас делаю. Добавляются-удаляются пункты, сортируется и проч. Особо не отлаживал, так что буду раз замечаниям и правкам.

Было бы хорошо сделать добавление пунктов в закрытый пункт (В демке jQuery Sortable есть случай, когда элемент на таб перетаскивается, но пока не дошло как это здесь сделать)
<!doctype html>
<html>
  <head>
    <style>
        ul {
            list-style: none;
            padding: 0;
            margin: 0;
        }
        li {background: #888; border: solid 1px red;}
        li li {background: #aaa;}
        li li li {background: #eee;}
        li li li li {background: #fff;}
    </style>
    <script src="http://code.jquery.com/jquery-2.0.1.min.js"></script>
    <script src="//cdnjs.cloudflare.com/ajax/libs/jqueryui/1.9.2/jquery-ui.min.js"></script>
    <script src="http://code.angularjs.org/1.1.5/angular.min.js"></script>
    <script src="http://tamtakoe.ru/angular-ui-sortable.js"></script>
    <script language="javascript" type="text/javascript">
angular.module('treeMenu', ['ui.sortable'])
function TreeCtrl ($scope) {

    var tree = [{
            id: 1,
            name: "Пункт1",
            editor: false,
            res_type: 'page',
            vis: false,
            sub: [{
                id: 2,
                name: "Пункт1-1",
                editor: false,
                res_type: 'page',
                vis: false,
                sub: []
            },{
                id: 8,
                name: "Пункт1-2",
                editor: false,
                res_type: 'page',
                vis: false,
                sub: []
            }]
        },{
            id: 5,
            name: "Пункт2",
            editor: false,
            res_type: 'page',
            vis: false,
            sub: []
        }],
        blankItem = {
            id: null,
            name: '',
            editor: true,
            res_type: 'page',
            vis: false,
            sub: []
        };

    /*MainMenu.query(function(data) {
        tree = one2multi(data); //Преобразование линейного массива в многомерный
        addBlank();
        $scope.tree = tree;
        menuCollapse(Global.menuItemId) //Активация определенного пункта меню
    });*/
    addBlank();
    $scope.tree = tree;
    menuCollapse(0)
       
    //Открытие заданного пункта меню [и закрытие остальных]
    $scope.open = menuCollapse
    function menuCollapse (id, accordeon) {
        var acc = []
        function walk(children) {
            var i = children.length;
            while (i--) {                     
                if (children[i].id == id) {
                    for (var j = 0, n = acc.length; j < n; j++) {
                        acc[j].vis = true
                    }
                    children[i].vis = !children[i].vis
                } else {
                    if (typeof accordeon === 'undefined' || accordeon === true) children[i].vis = false
                    acc.push(children[i])
                    walk(children[i].sub)
                    acc.pop()
                }
            }
        }
        walk(tree);
    }

    //Редактирование и добавление элемента
    $scope.edit = function(item) {
        item.editor = !item.editor;
        if (!item.editor) {
            if (item.id !== null || typeof item.$save == 'function') {
                //Сохранение
                console.log(item)
                /*item.$save();*/
            } else {               
                //Добавление
                /*MainMenu.add(function (data) {*/
                    var data = { //Якобы полученный пустой новый элемент, созданный на сервере
                        id: 9,
                        name: '',
                        editor: false,
                        res_type: 'page',
                        vis: false,
                        sub: []
                    }
                    //Находим подмассив в который нужно добавить элемент
                    function walk(children) {
                        var i = children.length;
                        while (i--) {
                            if (children[i] === item) {
                                //Добавляем айдишник и введенный текст в новый элемент и сохраняем
                                var newitem = angular.extend(data, item, {id: data.id})
                                
                                children.push(angular.copy(blankItem));
                                children[i] = newitem;  
                                /*newitem.$save()*/                              
                                console.log(item)
                                sort();
                                return
                            } else {
                                walk(children[i].sub)
                            }
                        }
                    }
                    walk(tree);
                /*})*/
            }
        }
    }
    
    //Удаление элемента
    $scope.del = function (item) {
        //Находим подмассив из которого нужно удалить элемент
        function walk(children) {
            var i = children.length;
            while (i--) {
                if (children[i] === item) {
                    /*children[i].$remove(function (data) {
                        sort();
                    });*/
                    children.splice(i, 1);
                    sort();
                    return
                } else {
                    walk(children[i].sub)
                }
            }
        }
        walk(tree);

        /*typeRes[index].vis = false*/
        
    }

    //Добавление пустых элементов    
    function addBlank () {
        function walk(children) {
            var i = children.length;
            while (i--) {
                children[i].editor = false;
                
                walk(children[i].sub)
            }
            children.push(angular.copy(blankItem));
        }
        walk(tree);
    }
    
    //Сохранение порядка элементов
    $scope.sort = sort;
    function sort () {
        var sortArr = [],//айдишники в порядке расположения
            pidsArr = [] //id-элемента: id-родителя
        
        function walk(children, pid) {
            for (var i = 0, n = children.length; i < n; i++) { 
                if (children[i].id) {
                    sortArr.push(children[i].id)
                    pidsArr.push(pid)
                    walk(children[i].sub, children[i].id);
                }
            }
        }
        walk($scope.tree, null);
        
        /*MainMenu.save({sort: sortArr, pids: pidsArr}, function (data) {
        
        })*/

        $scope.$$phase || $scope.$apply(); //Если область видимости не находится в фазе digest, запускаем её с помощью $apply(). Делается для того, чтобы информация о сортировке сразу же поступила на сервер.

        console.log(sortArr)
        console.log(pidsArr)     
    }
}
    </script>
  </head>
   <body ng-app="treeMenu">
        <script type="text/ng-template"  id="tree_item.html">
            <div>
                <a href="" ng-hide="item.editor" ng-click="open(item.id)"><b>{{item.name}}</b></a>
                <span ng-show="item.editor">
                  <input type="text" ng-model="item.name" placeholder="Новый пункт"/>
                    <select ng-model="item.res_type">
                      <option value="page">страница</option>
                      <option value="catalog">раздел каталога</option>
                     </select>
                  <a href="" ng-click="del(item)">×</a>
                </span>
                <a href="" ng-model="item.editor" ng-click="edit(item)">ред./сохр.</a>
            </div>
            <ul ui-sortable="{items:'.sortable',
                              connectWith: '.menu',
                              revert: 0,
                              delay: 100,
                              distance: 20,
                              stop: sort}" 
                 ng-model="item.sub"
                 ng-show="item.vis"
                 class="menu">
                <li ng-repeat="item in item.sub" ng-include="'tree_item.html'" class="sortable"></li>
            </ul>
        </script>
        <div ng-controller="TreeCtrl">
            <ul ui-sortable="{items:'.sortable',
                              connectWith: '.menu',
                              revert: 0,
                              delay: 100,
                              distance: 20,
                              stop: sort}"
                 ng-model="tree"
                 class="menu">
                <li ng-repeat="item in tree" ng-include="'tree_item.html'" class="sortable"></li>
            </ul>
        </div> 
   </body>
</html>

Последний раз редактировалось Shitbox2, 02.07.2013 в 18:13. Причина: Исправил проблему с кэшированием данных о сортировки
Ответить с цитированием