1

I managed to do that in my side with Angular Material, it worked with sub-menus that were deployed with dropdowns, but I'm looking for a way to make them not "Dropdowns", I'm looking for them to be like a kind of transition towards right, Something like this:

https://jmouriz.github.io/angular-material-multilevel-menu/demo/demo.html#!/demo/views/item-2

But this one is done in AngularJS 1.X. I am using Angular 5, does anyone come up with any way or where to start? Thank you!

Marshal
  • 10,499
  • 2
  • 34
  • 53
S. A
  • 493
  • 2
  • 6
  • 14
  • Hi S.A yes you can that please follow this https://material.angular.io/components/expansion/overview – harkesh kumar Dec 11 '18 at 10:09
  • @harkeshkumar thanks for the answer! Really appreciated. The documentation you send me is for dropdowns, which I have already managed to do; but what I'm looking for is a lateral transition. Like this: https://i.gyazo.com/483af37c10ebd1a0eb53441213fc9ae5.gif – S. A Dec 11 '18 at 10:20
  • its that help you ....that sit you want to know or how to implement also – harkesh kumar Dec 11 '18 at 10:20
  • No, I need its a transition like this: https://i.gyazo.com/483af37c10ebd1a0eb53441213fc9ae5.gif Not a drop down! – S. A Dec 11 '18 at 11:06
  • then you have to make your custom javascript code and logic with animation – harkesh kumar Dec 11 '18 at 11:25
  • @harkeshfumar Can you help me to do it? I dont have like much experience with Angular, and I really want to learn! – S. A Dec 11 '18 at 11:56
  • i'd recommend checking out the angular animations guide. You could always handle animations using css transitions, but angular animations are a much better way to handle state based transitions like what you've described. https://angular.io/guide/animations – Chris Newman Dec 11 '18 at 16:52

1 Answers1

1

After looking into this further I felt the original solution was overtly complicated, and there had to be a better way.

  • The original approach was to control the hierarchy mainly from the view...
  • This was the wrong approach.

The revised approach is based on the concept of driving the view based on array hierarchy... this makes for a much cleaner solution with better scale-ability.


Define array hierarchy... the key here is to assign options with sub menus to rootTab indexes that will hold the sub menu options when clicked..

rootTabs = [
    {
      id: 0,
      options: [
        { option: 'Home' },
        { option: 'Parámetros' },
        { option: 'Operativa' },
        { option: 'Productos' },
        { option: 'Invocación Servicios', rootTab: 1 }
      ]
    },
    {
      id: 1,
      options: [
        { option: 'Portal 1', rootTab: 2 },
        { option: 'Portal 2', rootTab: 4 },
        { option: 'Portal 3', rootTab: 5 }
      ]
    },
    {
      id: 2,
      options: [
        { option: 'Service 1 Item1', route: '/Submenu1' },
        { option: 'Service 1 Item2', route: '/Submenu2' },
        { option: 'Service 1 Item3', route: '/Submenu3' },
        { option: 'Service 1 Item4', route: '/Submenu4' },
        { option: 'Service 1 Item5', route: '/Submenu5' },
        { option: 'Invocación Servicios', rootTab: 3 }
      ]
    },
    {
      id: 3, options: [
        { option: 'put additional options here' }
      ]
    },
    {
      id: 4,
      options: [
        { option: 'Service 2 Item1', route: '/Submenu1' },
        { option: 'Service 2 Item2', route: '/Submenu2' },
        { option: 'Service 2 Item3', route: '/Submenu3' },
        { option: 'Service 2 Item4', route: '/Submenu4' },
        { option: 'Service 2 Item5', route: '/Submenu5' },
      ]
    },
    {
      id: 5,
      options: [
        { option: 'Service 3 Item1', route: '/Submenu1' },
        { option: 'Service 3 Item2', route: '/Submenu2' },
        { option: 'Service 3 Item3', route: '/Submenu3' },
        { option: 'Service 3 Item4', route: '/Submenu4' },
        { option: 'Service 3 Item5', route: '/Submenu5' },
      ]
    }
  ]

Create component methods to handle menu state via UI interaction.

rootSelected(optionIndex, optionRootIndex, rootOption) {
    this.numItemsSelected++;
    this.previousRootTab = this.currentSelectedRootTab;
    this.currentSelectedRootTab = optionRootIndex;
    this.indexClicked = optionIndex;
    if (!this.breadcrumb1) {
      this.breadcrumb1 = rootOption
    } else if (!this.breadcrumb2) {
      this.breadcrumb2 = rootOption
    } else {
      this.breadcrumb3 = rootOption
    }
  }

  back2Main() {
    this.currentSelectedRootTab = 0;
    this.previousRootTab = 0;
    this.indexClicked = 0;

    this.numItemsSelected = 0;
    this.breadcrumb1 = null;
    this.breadcrumb2 = null;
    this.breadcrumb3 = null;
  }

  toBreadcrum1() {
    if (this.numItemsSelected > 1) {
      this.currentSelectedRootTab = this.breadcrumb1.rootTab;
      this.breadcrumb2 = null;
      this.numItemsSelected--
    }
  }

  toBreadcrum2() {
    if (this.numItemsSelected > 2) {
      this.currentSelectedRootTab = this.breadcrumb2.rootTab;
      this.breadcrumb3 = null;
      this.numItemsSelected--
    }
  }

Wire it all up in the template

<div style="display: flex;flex-direction: row;margin:1% ;height:30px;">
    <div routerLink="/" routerLinkActive="active" (click)="back2Main()" style="cursor:pointer" class="vertical-align-text">Main</div>
    <div *ngIf="numItemsSelected >= 1">&nbsp;<mat-icon>chevron_right</mat-icon></div>
    <span *ngIf="numItemsSelected >= 1" routerLink="/" routerLinkActive="active" class="vertical-align-text" style="cursor:pointer;vertical-align: middle;" (click)="toBreadcrum1();">&nbsp;{{breadcrumb1.option}}</span>
    <div *ngIf="numItemsSelected >= 2">&nbsp;<mat-icon>chevron_right</mat-icon></div>
   <span *ngIf="numItemsSelected >= 2" routerLink="/" routerLinkActive="active" class="vertical-align-text" style="cursor:pointer" (click)="toBreadcrum2();">&nbsp;{{breadcrumb2.option}}</span>
    <div *ngIf="numItemsSelected >= 3">&nbsp;<mat-icon>chevron_right</mat-icon></div>
   <span *ngIf="numItemsSelected >= 3" routerLink="/" routerLinkActive="active" class="vertical-align-text" style="cursor:pointer" (click)="toBreadcrum3();">&nbsp;{{breadcrumb3.option}}</span>
   </div>


<div style="display: flex;flex-direction: row;background-color:white; height:100vh">
    <mat-tab-group class="navigation-tabs" [selectedIndex]="currentSelectedRootTab" dynamicHeight style="width:25vw; background-color:lightgray">
        <mat-tab *ngFor="let rootTab of rootTabs; let rootIndex = index" [label]="rootIndex">
            <mat-nav-list>
        <div *ngFor="let rootOption of rootTab.options; let optionIndex = index;">       
          <a mat-list-item *ngIf="!rootOption.rootTab" [routerLink]="rootOption.route" routerLinkActive="active">{{rootOption.option}}</a>
          <a mat-list-item style="width:100%" *ngIf="rootOption.rootTab" (click)="rootSelected(optionIndex, rootOption.rootTab, rootOption)">{{rootOption.option}}<div><mat-icon style="padding-left:20%;vertical-align: middle;">chevron_right</mat-icon></div></a>
        </div> 
            </mat-nav-list>
        </mat-tab>
    </mat-tab-group>
  <div style="margin:auto">
    <router-outlet></router-outlet> 
  </div>
</div>

Stackblitz

https://stackblitz.com/edit/angular-x5xefi-gmzy46?embed=1&file=app/tab-group-basic-example.html

Marshal
  • 10,499
  • 2
  • 34
  • 53
  • This is exactly what I was looking for, I finish refactoring other things in my app and I will try it. Thank you! Does this code have anything that is only version 7? Because in the project I'm working with they use Angular 5, therefore Angular Material 5 too. Thank you very much in the same way! So, to begin with, it will help me, you can always pivot, but this is excellent. – S. A Dec 12 '18 at 09:46
  • Hmm, I'm looking at the code and I see that it's 100% focused on tabs, can not I get them to point to a Router Link? so that instead of running a currentSelectedRootTab it is a routed component? – S. A Dec 12 '18 at 09:53
  • Exactly, excuse me, I did not know how to explain myself. – S. A Dec 12 '18 at 14:30
  • Thank you very much, yes, I know how the routing module works. Let me explain: https://i.gyazo.com/f4599c1aa08e84cf37e6f64d8cb903e7.gif I have a sidenav that has 4 routings that do not move, they are normal "mat-lists" that point directly to a route, but the route 5 (the one with the lightning icon) I want to do when it is activated, this is a tab and when clicked appear 3 submenu tabs, and if you click on any of these 3 submenu tabs that appeared; 5 tabs would come out (in each of these 3 tabs) – S. A Dec 12 '18 at 15:41
  • I think I've complicated a lot explaining, but it's what I'm looking to do and you've given me a good push to start! – S. A Dec 12 '18 at 15:41
  • Incredible, you just saved me two afternoons of attempts to find this solution. The only thing I do not know is how to create another 5 tabs when you click on "Service 1", "Service 2", "Service 3". https://i.gyazo.com/1e1ee1105402f5ef313317f0acdf140b.gif – S. A Dec 12 '18 at 16:31
  • Thanks! Really Appreciated. I understood the code, but as you say I can not find a way to put the 5 tabs also appear in the last 2 services :( So close but so far away hahaha – S. A Dec 13 '18 at 08:38
  • I was trying to do it from the stackblitz that you created and then try to insert it in my code, but trying to do it I only managed to multiply the last 5 tabs up to twice in it, I did not manage to get five in each tab ... :( truth is that I have tried for a long time but I can not find a viable solution – S. A Dec 13 '18 at 14:39
  • https://stackblitz.com/edit/angular-x5xefi-vdp13s If you click in "Portal 2" youre going to see it. I was quite out of hand, after many attempts I stayed like that and decided to stop before damaging it more. – S. A Dec 13 '18 at 14:57
  • Thanks!! It is impossible to change the routes, right? since they are named as {{'/ Submenu' + ​​(itemIndex + 2)}} It's perfect, the only detail is that of the route that would have to put the names that are generated there (SubmenuX) and that when you click "Service 1, 2 or 3" there is no transition effect as if it were tab, the rest is perfect, in fact the line that says "put your new 5 items here" is not necessary, since what is there is enough (Invocation Services> 3 Options> 5 options on each option – S. A Dec 13 '18 at 15:51
  • Perfect, thank you very much. One last thing: How can I do when I click on "Portal 1> Portal 2> Portal 3> "(Either of the three options) make a transition with the effect of the tabs instead of just moving to the next submenu without any kind of effect? – S. A Dec 13 '18 at 16:45
  • Please see revised answer – Marshal Dec 13 '18 at 23:47
  • Perfect, You gave a genius approach. Much more orderly and intuitive! It was just what I needed, thank you very much. P.D: Could I also put mat icons in the same arrays without damaging the code? Only for the root-tabs, not for the sub-tabs that come inside. – S. A Dec 14 '18 at 11:40
  • Do you know how to also do dropdowns? So that in the menu after choosing Portal 1 2 or 3, there are 2 possible dropdowns (Instead of the 5 services), with 5 links inside the first Dropdown and 3 links in the second Dropdown. Since if I do everything with Tabs, the breadcumbs are too much and it is somewhat confusing for the user experience so many tabs. – S. A Dec 17 '18 at 11:26