1 votes

Problem with sidenav scrollbar - Angular Material 6

I am relatively new to Angular. I am implementing in my project the sidenav example of kenji 1996 . link to your repository .

Many of the sidebar menu behaviors are what I need, however, I have a problem with the scrollbar when I try it for a mobile environment. When you hide the menu and show it again, the menu scrollbar does not hold the position it is in, but "resets" and goes back up. I know it may seem like a small detail, but I firmly believe that's what the user experience is all about, correcting those small details and providing convenience to the user.

The following images describe the problem better :)

abriendo menu y navegando hacia abajo

cerrando el menu

abriendo el menu otra vez

I have reviewed the documentation for Angular and Angular-Material but I haven't found a respective solution, or maybe I didn't understand it well. :(

Component.html:

<mat-toolbar color="primary" class="main-nav mat-elevation-z4">

    <button mat-icon-button (click)="start.toggle()" class="icon-padding">
        <mat-icon aria-hidden="true">menu</mat-icon>
    </button>
    <button mat-button routerLink="/"><strong>Prueba Menu Sidenav</strong></button>

    <!-- This fills the remaining space of the current row -->
    <span class="fill-remaining-space"></span>

    <button mat-icon-button class="icon-padding">
        <mat-icon aria-hidden="true">notifications</mat-icon>
    </button>

</mat-toolbar>

<mat-sidenav-container class="sidenav-container">

    <mat-sidenav class="mat-elevation-z10" #start [opened]="open" fixedTopGap="64" [mode]="mode" fixedInViewport="true" style="width:240px;">

        <mat-list dense>
            <ng-container *ngFor="let nav of navList">
                <mat-expansion-panel class="mat-elevation-z0" hideToggle="true" [expanded]="nav.dropDown">
                    <mat-expansion-panel-header>
                        <mat-panel-title>
                            <mat-icon mat-list-icon>{{nav.icon}}</mat-icon>
                            <span class="nav-list-item" style="margin-left: 10px;">{{nav.categoryName}}</span>
                        </mat-panel-title>
                    </mat-expansion-panel-header>
                    <mat-nav-list>
                        <div style="margin-top: -20px;">
                            <ng-container *ngFor="let subCategory of nav.subCategory">
                                <ng-container *ngIf="subCategory.visable"> <!--Sub category list-->
                                    <mat-list-item (click)="mode === 'over'? start.close() : null" routerLinkActive="mat-icon-active" style="margin-left: -70px;margin-right: -24px;">
                                        <a mat-list-item [routerLink]="subCategory.subCategoryLink"  mat-line style="margin-left: 30px;">
                                            <mat-icon class="sidenav-icon" style="margin-left: 18px;">{{subCategory.subCategoryQuery}}</mat-icon>
                                            <span style="margin-left: 3px;">{{subCategory.subCategoryName}}</span>
                                        </a>
                                    </mat-list-item>
                                </ng-container>
                            </ng-container>
                        </div>
                    </mat-nav-list>
                </mat-expansion-panel>
            </ng-container>
        </mat-list>

    </mat-sidenav>

    <mat-sidenav-content style="margin-top:64px;">
        <div style="margin: 10px;">
            <router-outlet></router-outlet>
        </div>
        <div style="height: 64px;"></div>
    </mat-sidenav-content>

</mat-sidenav-container>

Component.ts

import {Component, NgZone, OnInit} from '@angular/core';
import {Router} from '@angular/router';

@Component({
    selector: 'app-main',
    templateUrl: './main.component.html',
    styleUrls: ['./main.component.scss']
})
export class MainComponent implements OnInit {

    // Sidenav responsive
    width;
    height;
    mode = 'side';
    open = 'true';
    title = 'Responsive Sidenav Starter';
    navList: NavList[];

    constructor(public ngZone: NgZone,
                public route: Router, ) {
        this.navList = [
            { categoryName: 'Menu', icon: 'face', dropDown: true,
                subCategory:
                    [
                        { subCategoryName: 'Submenu', subCategoryLink: '/link', visable: true, },
                        { subCategoryName: 'Submenu', subCategoryLink: '/principal', visable: true, },
                        { subCategoryName: 'Submenu', subCategoryLink: '/link1', visable: true, },
                    ]
            },
            { categoryName: 'Menu', icon: 'face', dropDown: false,
                subCategory:
                    [
                        { subCategoryName: 'Submenu', subCategoryLink: '/link', visable: true, },
                        { subCategoryName: 'Submenu', subCategoryLink: '/principal', visable: true, },
                        { subCategoryName: 'Submenu', subCategoryLink: '/link1', visable: true, },
                    ]
            },
            { categoryName: 'Menu', icon: 'question_answer', dropDown: false,
                subCategory:
                    [
                        { subCategoryName: 'Submenu', subCategoryLink: '/link1', visable: true, },
                        { subCategoryName: 'Submenu', subCategoryLink: '/link1', visable: true, },
                        { subCategoryName: 'Submenu', subCategoryLink: '/link1', visable: true, },
                    ]
            },
            { categoryName: 'Menu', icon: 'work', dropDown: false,
                subCategory:
                    [
                        { subCategoryName: 'Submenu', subCategoryLink: '/link1', visable: true, },
                        { subCategoryName: 'Submenu', subCategoryLink: '/link1', visable: true, },
                        { subCategoryName: 'Submenu', subCategoryLink: '/link1', visable: true, },
                    ]
            },
        ];
        this.changeMode();
        window.onresize = (e) => {
            ngZone.run(() => {
                this.changeMode();
            });
        };
    }

    ngOnInit() {

    }

    changeMode() {
        this.width = window.innerWidth;
        this.height = window.innerHeight;
        if (this.width <= 800) {
            this.mode = 'over';
            this.open = 'false';
        }
        if (this.width > 800) {
            this.mode = 'side';
            this.open = 'true';
        }
    }

}

export class NavList {
    categoryName: string;
    icon: string;
    dropDown: boolean;
    subCategory: NavListItem[];
    constructor(_categoryName: string, _icon: string, _dropDown: boolean, _subCategory: NavListItem[]) {
        this.categoryName = _categoryName;
        this.icon = _icon;
        this.dropDown = _dropDown;
        this.subCategory = _subCategory;
    }
}

export class NavListItem {
    subCategoryName: string;
    subCategoryLink: string;
    subCategoryQuery?: any;
    visable: boolean;
}

Component.scss

// angular material colors
@import '../../../theme';

.sidenav-container {
    position: absolute;
    top: 0;
    bottom: 0;
    left: 0;
    right: 0;
}

.main-nav {
    position: fixed;
    top: 0px;
    left: 0;
    width: 100%  !important;
    z-index: 5;
}

.icon-padding {
    margin-left: 3px;
    margin-right: 3px;
}

.nav-list-exp {
    padding: 0 !important;
}

.nav-list-item {
    background-color: #FFF;
    transition: background 0.2s linear;
}
.mat-icon-active mat-icon {
    transition: color 0.2s linear;
    color: mat-color($primary) !important;
}
.nav-category-open {
    transition: color 0.2s linear;
    color: mat-color($primary) !important;
}
.nav-list-item:hover {
    cursor: pointer;
    background:#c5c5c5;
}

.nav-list-item-text {
    padding-left: 18px;
    font-size: 0.8em;
}

.nav-list-icon {
    margin-left: 5px;
}

mat-toolbar {
    height:  64px !important;
    min-height: 64px !important;

    mat-toolbar-row {
        height: 64px !important;
    }
}

Thank you in advance for your help :)

0 votes

You are in SO in Spanish, and the official language of the site is Spanish. Please translate your question.

0 votes

Can you try to set up an example in StackBlitz? Something is wrong when I try to use your code and I cannot reproduce the scenario

0 votes

Hi, @PabloLozano! Sorry for the delays. I don't know that tool, but I'll get up to speed as soon as possible :)

0voto

ChemaCortes Points 5050

Without going into whether or not it improves the user experience (the selected item is out of view), what you have to do is to stop the autofocus :

<mat-sidenav #start
  class="mat-elevation-z10"
  [opened]="open"
  [autofocus]="false"
  ...
>

0 votes

It did not work :'(

0 votes

You are using an old version. It does not work with angular-material@5.2 .

0 votes

:o I understand, to update the project and test the solution then :)

HolaDevs.com

HolaDevs is an online community of programmers and software lovers.
You can check other people responses or create a new question if you don't find a solution

Powered by:

X