Search code examples
javascriptangularjsmetronic

Multi-menu level Angular js


I want to loop over an array of menus and submenus(maybe sub of submenus) .

I use metronic template (look the second-last item of this link Metronic Template ("Multi Level Menu")

I have this structure :

$scope.dashitems = [{
    title: 'Company',
    icon: 'icon-layers',
    href: '#/dashboard1',
    isActive: path === '/dashboard1'
}, {
    title: 'Buildings',
    icon: 'icon-layers',
    href: '#/Buildings',
    isActive: path === '/Buildings'
}, {
    title: 'Floors',
    icon: 'icon-layers',
    href: '#/Floors',
    isActive: path === '/Floors'
}, {
    title: 'Spaces',
    icon: 'icon-layers',
    href: 'javascript:;',
    isActive: path === '/Spaces',
    subitems: [{
        title: 'OpenSpaces',
        icon: 'icon-layers',
        href: '#/OpenSpaces',
        isActive: path === '/OpenSpaces',
        subitems: [{
            title: 'OpenSpaces2',
            icon: 'icon-layers',
            href: '#/OpenSpaces2',
            isActive: path === '/OpenSpaces2',
        }]
    }, ]
}, {
    title: 'Meeting',
    icon: 'icon-layers',
    href: '#/meeting',
    isActive: path === '/meeting'
}];

this not work :

function printList(dashitems){
            $scope.menu = '<ul>';
            angular.forEach(dashitems, function(value, key) {
                $scope.menu+="<li>";
                if(value.hasOwnProperty('subitems')){


                  $scope.menu=' <a ng-href="{{ value.href }}" class="nav-link nav-toggle">'+
                              '<i ng-class="value.icon"></i>'+
                              '<span class="title">{{ value.title }}</span>'+
                              '<span class="arrow open"></span>'+
                          '</a>';


                  printList(value.subitems);
                }else{

                   $scope.menu+="<a href='javascript:;' class='nav-link nav-toggle'>"+
                      "<i class='value.icon'></i>"+
                      "<span class='title'>{{value.title}}</span>"+
                  "</a></li>";
                }
            });
            $scope.menu += "<ul>";
            return $scope.menu;
        }

How to loop over this structure and produce the same html of the "Multi Level Menu" ?

EDIT:

angular
  .module('app').directive('menuBar', function() {
    return {
      restrict: 'E',
      controller: ['$scope', '$location', function($scope, $location) {
        //function & dashitems
            $scope.printList($scope.dashitems);
      }]
    }   
});

Solution

  • You can create a directive that make lists recursively.

    <menu ng-model="dashItems"></menu>
    

    The directive should do somethink like:

    1. create a funcion printList(dashItems)
    2. open a ul element
    3. Iterate dashItems, for each item generates a li element
    4. If an item hasOwnProperty('subItem'), you call printList(dashItems.subitem) recursively.
    5. Finally close the ul element and return list.

    Now you only have to do: element.append(printList(dashItems))

    That's a high level approach but I think it could be usefull.

    Edited: I'm going to help you to create the function:

    function printList(dashitems){
                $scope.menu = '<ul>';
                angular.forEach(dashitems, function(value, key) {
                    $scope.menu+="<li>";
                    if(value.hasOwnProperty('subitems')){
    
                      $scope.menu=' <a ng-href="{{ value.href }}" class="nav-link nav-toggle">'+
                                  '<i ng-class="value.icon"></i>'+
                                  '<span class="title">{{ value.title }}</span>'+
                                  '<span class="arrow open"></span>'+
                              '</a>';
    
    
                      printList(value.subitems);
                    }else{
    
                       $scope.menu+="<a href='javascript:;' class='nav-link nav-toggle'>"+
                          "<i class='value.icon'></i>"+
                          "<span class='title'>{{value.title}}</span>"+
                      "</a>";
                    }
                    $scope.menu+="</li>";
                });
                $scope.menu += "<ul>";
                return $scope.menu;
            }
    

    I think that could work

    angular
      .module('app').directive('menuBar', function() {
        return {
          restrict: 'E',
          scope: {
              list: '=dashitems'
          }
          controller: ['$scope', '$location', function($scope, $location) {
            //function & dashitems
                $scope.printList($scope.dashitems);
          }]
        }   
    });