The data is not rendering in the mat-menu - html

I been trying to create a navbar with a submenu. The nav bar data is rendered successfully but the submenu is not working, I am very new to this. Please let me know where is the problem.
<mat-nav-list class="navigation relative">
<div *ngFor="let link of navLinks; let i=index" style="padding-bottom: 14px;">
<div class="card">
<mat-list-item appAccordionlinks routerLinkActive="active-link" (click)="onClick(link.name)">
<a mat-button [matMenuTriggerFor]="submenu" *ngIf="link?.submenu?.length > 0" appAccordiontoggle
class="relative main-active">
<mat-icon *ngIf="link.icon">{{link.icon}}</mat-icon>
<img class="menu-img" *ngIf="link.img" [src]="link.img" alt="">
<app-menu-icon *ngIf="link.img" [name]="'employee'"></app-menu-icon>
<span>{{link.name}}</span><span fxFlex></span>
</a>
<a *ngIf="!(link?.submenu?.length > 0)" [routerLink]="link.path" appAccordiontoggle
class="relative main-active" mat-ripple fxLayout="row">
<mat-icon *ngIf="link.icon">{{link.icon}}</mat-icon>
<app-menu-icon *ngIf="link.img" [name]="link.name" [color]="link.color"></app-menu-icon>
<!-- <img class="menu-img" *ngIf="link.img" [src]="link.img" alt=""> this is need to mark as comment -->
<span>{{link.name}}</span>
</a>
</mat-list-item>
</div>
</div>
</mat-nav-list>
<mat-menu #submenu>
<ng-container *ngFor="let sublink of link?.submenu">
<ng-container *ngIf="link?.submenu?.length > 0">
<button mat-menu-item>
<img class="menu-img" *ngIf="sublink.img" [src]="sublink.img">
<span>{{sublink.name}}</span>
</button>
</ng-container>
</ng-container>
</mat-menu>

The mat-menu element is out of the scope of link variable. You need to include it (mat-menu) in the div you are dynamically rendering the links, i.e. within link's scope:
<div *ngFor="let link of navLinks; let i = index"...>
<--! card html -->
<mat-menu #submenu>
<--! submenu child elements... -->
</mat-menu>
</div>

Related

How to change button position in angular?

I want to change the button position in my html code but I got a problem in the j like in the photo below ! I want to put the button in the footer of the modal !
the Output (button in the bottom) :
here is it my code:
<div class="modal-header" >
<h6 class="modal-title" id="modal-basic-title">Notes</h6>
<button type="button" class="close" aria-label="Close" (click)="closemodal()">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body" style="width:500px ; height:600px; overflow-y: auto" >
<mat-accordion >
<mat-expansion-panel *ngFor="let i of listCategorie" class="parentPanel" >
<mat-expansion-panel-header class="parentPanel_header" (click)="getSouCategories(i.id)" >
<mat-panel-title > {{i.libelle}} {{i.id}}
<span class="badge badge-light " style="position:absolute; right:6em"> {{listCategorie.length}} </span>
</mat-panel-title>
</mat-expansion-panel-header>
<mat-accordion multi>
<mat-expansion-panel style="background-color: #EEDFF5;" class="childPanel childPanelCount" [expanded]="true" hideToggle disabled>
<div class="d-flex mt-2">
<div class="p-2"><p> Nombre des sous catégories </p></div>
<div class="ml-auto p-2">
<span class="badge badge-secondary "> {{listSousCategorie.length}} </span>
</div>
</div>
</mat-expansion-panel>
<ng-container>
<mat-expansion-panel class="childPanel" [expanded]="true" hideToggle disabled style=" background:#F2EDFF;"
*ngFor="let j of listSousCategorie; ">
<div class="childPanel_body2 mat-badge-large" fxLayout="row" fxFlex fxLayoutAlign="start center">
<div style="padding-left:1em" fxFlex="grow">{{j.libelle}} {{j.id}}</div>
<mat-form-field style="width:50px" appearance="standard">
<form>
<mat-label>Note</mat-label>
<input type="text" matInput name="Note" [(ngModel)]="j.Note_Condidat">
<button type="button" (click)="onSubmit(j)"> ok</button>
</form>
</mat-form-field>
</div>
</mat-expansion-panel>
</ng-container>
</mat-accordion>
</mat-expansion-panel>
</mat-accordion>
</div>
Ts File:
onSubmit(sous) {
this.LExamenSousCategorieService.updateSouCategorie(sous).then(res => {
})
}
i think you should give parent element of button "position: relative" and make your button positioning with "position: absolute; (and margin,padding vs...)"

Trouble with Angular Drag and Drop

I'm trying to make it so a User has a page where they view their company cards. I want to be able to create containers or just some sorting objects that they can use to organize them.
I created an ng-expansion panel that I want it to be based on. However, I'm having trouble making a proper Drag and Drop to work between them.
I've been using the cdkDragDrop tool and I only managed to make the company cards themselves be drag and dropped on screen but not on the container. I can't seem to be able to make the proper connection, the Angular website cdk page only seems to want to drag and drop sentences, I can't find a way to rework it to drag and drop my cards instead.
My expansion-panel is written like this:
<mat-expansion-panel cdkDropList (opened)="panelOpenState = true" (closed)="panelOpenState = false" (cdkDropListDropped)="drop($event)">
<mat-expansion-panel-header>
<mat-panel-title>
Group Name
</mat-panel-title>
<mat-panel-description>
Currently I am {{panelOpenState ? 'open' : 'closed'}}
</mat-panel-description>
</mat-expansion-panel-header>
</mat-expansion-panel>
and my cards are formatted to where I called the drag and drop here:
<div cdkDropList class="d-flex align-content-start flex-wrap mt-4" (cdkDropListDropped)="drop($event)" *ngIf="!isLoading">
<ng-container *ngFor="let perspective of watchlist">
<div class="watchlist-card" cdkDrag>
<div class="watchlist-card-content">
<div class="d-flex flex-column watchlist-card-body">
<!-- CARD HEADER AND REMOVE ICON -->
<div class="d-flex flex-row justify-content-between">
<p class="card-title">{{ perspective.company.title }}</p>
<button class="button-icon" (click)="removeCompanyFromWatchlist(perspective)">
<mat-icon class="btn-close">close</mat-icon>
</button>
</div>
<!-- 3P-SCORE -->
<ng-container *ngIf="scoreExists(perspective.company.scores) === true">
<div class="d-flex flex-column">
<!-- 3P SCORE HEADER -->
<div class="d-flex flex-row justify-content-between">
<p class="text-header">3P Score</p>
<!-- TOTAL 3P SCORE -->
<p class="text-header"> {{ calculateTotal3PScore(perspective.company.scores)}}/100</p>
</div>
<!-- SCORE BREAKDOWN: People, Product & Performance -->
<ng-container *ngFor="let criteria of scoreCriteria">
<div class="d-flex flex-column">
<!-- SCORE CRITERIA & SCORE OUT OF 100 -->
<div class="d-flex flex-row justify-content-between">
<div class="d-flex flex-row jutify-content-start align-self-center">
<img src={{criteria.icon}} class="score-icon">
<p class="score-label align-self-center">{{criteria.label | titlecase}}</p>
</div>
<p class="score-label">{{ perspective.company.scores[0][criteria.label] }}/100
</p>
</div>
<!-- PROGRESS BAR FOR CRITERIA -->
<div class="d-flex flex-row jutify-content-start slider-bottom">
<div class="slider-top"
[ngStyle]="{width: perspective.company.scores[0][criteria.label]+ '%'}">
</div>
</div>
</div>
</ng-container>
</div>
</ng-container>
<!-- NO 3P SCORE EXISTS -->
<ng-container *ngIf="scoreExists(perspective.company.scores) === false">
<div class="d-flex flex-column">
<p class="text-header">3P Score</p>
<p class="text-body">We don't have the 3P score of this input as of now. You can request the
score and we will get back to you if it’s a
company.</p>
<button class="btn port-btn small-label" *ngIf="!perspective.company.score_requested"
(click)="request3PScore(perspective)">Request 3P Score</button>
<p class="text-body port-orange" *ngIf="perspective.company.score_requested"><b>Your request
has been registered. We'll get back you to shortly.</b></p>
</div>
</ng-container>
<!-- FOOTER: KEWORDS AND ADD BUTTON -->
<div class="d-flex flex-column mt-auto">
<!-- KEYWORD CHIPS -->
<div class="d-flex flex-nowrap watchlist-keywords mt-2 mb-1">
<mat-chip *ngFor="let keyword of perspective.keywords" class="keyword-chip mr-2" [removable]="removable"
(removed)="removeKeywordFromWatchlist(perspective.keywords, keyword, perspective.id)">
{{ keyword }}
<mat-icon matChipRemove *ngIf="removable">close</mat-icon>
</mat-chip>
</div>
<!-- ADD KEYWORD BUTTON -->
<div class="d-flex flex-row flex-fill mr-auto mt-auto">
<!-- INPUT FIELD FOR ADDING KEYWORDS -->
<div class="d-flex flex-row flex-fill justify-content-between align-items-center" *ngIf="perspective.activeAddKeyword">
<div class="d-flex flex-row justify-content-between align-items-center search-bar p-3">
<input [(ngModel)]="keywordInput" type="text" placeholder="Add keyword here"
(keyup.enter)="addKeywordToWatchlist(perspective.keywords, perspective.id)">
<mat-icon matSuffix type="submit" (click)="addKeywordToWatchlist(perspective.keywords, perspective.id)">add</mat-icon>
</div>
<button class="button-curved ml-2 p-1" *ngIf="perspective.activeAddKeyword"
(click)="closeAddKeywordInput(perspective)">
Cancel
</button>
</div>
<button class="button-icon button-raised mt-auto" *ngIf="!perspective.activeAddKeyword" (click)="showAddKeywordInput(perspective)">
<mat-icon>add</mat-icon>
</button>
</div>
<div class="card-handle" cdkDragHandle>
<svg width="24px" fill="currentColor" viewBox="0 0 24 24">
<path
d="M10 9h4V6h3l-5-5-5 5h3v3zm-1 1H6V7l-5 5 5 5v-3h3v-4zm14 2l-5-5v3h-3v4h3v3l5-5zm-9 3h-4v3H7l5 5 5-5h-3v-3z">
</path>
<path d="M0 0h24v24H0z" fill="none"></path>
</svg>
</div>
</div>
</div>
</div>
</div>
</ng-container>
</div>
The rest of the card setups follows, this is just where I just the cdkDrag
*Edit, fixed up the cdkDropList as suggested by one of the answers.
*Edit2, Showed the whole card code.
The angular material Drag&Drop works with the concept of lists.
What you can do is connect lists (Drag and drop, or within the same list, or to another list).
So, let's assume, that the expansion panel is a list (It is a list because if you can drag things there, for Angular Material Drag & Drop it is a list)
To connect your expansion panel with cards that are not in there. You are going to have and keep two arrays. The first contain all your cards, and the second contain the cards that are inside the expansion panel
In your expansion panel:
<mat-expansion-panel
cdkDropList
#expansionPanelList="cdkDropList"
[cdkDropListData]="arrayCardsInsideExpansion"
[cdkDropListConnectedTo]="[listOfAllCards]"
(cdkDropListDropped)="drop($event)"
(opened)="panelOpenState = true"
(closed)="panelOpenState = false">
<mat-expansion-panel-header>
<mat-panel-title>
Group Name
</mat-panel-title>
<mat-panel-description>
Currently I am {{panelOpenState ? 'open' : 'closed'}}
</mat-panel-description>
</mat-expansion-panel-header>
<ng-container *ngFor="let perspective of arrayCardsInsideExpansion">
<div class="watchlist-card" cdkDrag>
.
.
.
</div>
</ng-container>
</mat-expansion-panel>
And your cards:
<div cdkDropList
#listOfAllCards="cdkDropList"
[cdkDropListData]="watchlist"
[cdkDropListConnectedTo]="[expansionPanelList]"
class="d-flex align-content-start flex-wrap mt-4"
(cdkDropListDropped)="drop($event)">
<ng-container *ngFor="let perspective of watchlist">
<div class="watchlist-card" cdkDrag>
.
.
.
Finally in your .ts Code, your drop Function:
import {CdkDragDrop, moveItemInArray, transferArrayItem} from '#angular/cdk/drag-drop';
.
.
.
.
drop(event: CdkDragDrop<string[]>) {
if (event.previousContainer === event.container) {
moveItemInArray(event.container.data, event.previousIndex, event.currentIndex);
} else {
transferArrayItem(event.previousContainer.data,
event.container.data,
event.previousIndex,
event.currentIndex);
}
}
}
If you have a lot of expansion panel, check CdkDropListGroup

Sidenav angular materials trying to be side to side with other component

The Problem: In an angular project I have a single component for the sidenav menu and I'm trying to put other component sided with the sidenav, but since the sidenav element has full height the other component just goes to the bottom of the page. I tried to use display flex, but still goes to the bottom of the page.
Sidenav - html
<mat-drawer-container class="container" autosize>
<mat-drawer #drawer class="p-5" mode="side">
<!-- Content for side menu -->
<!-- Title -->
<h2 class="mt-5">Menu</h2>
<!-- Menu options-->
<button mat-button class="m-2" [matMenuTriggerFor]="workexperience">Experiência
Profissional</button>
<button mat-button class="m-2" [matMenuTriggerFor]="studies">Educação</button>
<button mat-button class="m-2" [matMenuTriggerFor]="skills">Habilidades</button>
<...>
<!-- Option work experience-->
<mat-menu #workexperience="matMenu">
<button mat-menu-item>text</button>
<button mat-menu-item>text</button>
</mat-menu>
<...>
</mat-drawer>
</mat-drawer-container>
<nav class="navbar navbar-light cyan darken-3 text-white fixed-top">
<button type="button" mat-button (click)="drawer.toggle()">
<mat-icon class="mx-2">menu</mat-icon>
<p class="mr-4 d-inline">Menu</p>
</button>
<button type="button" routerLink="/home" routerLinkActive="active" mat-raised-button>
<mat-icon class="d-inline mx-2" aria-label="Example home icon">home</mat-icon>
<p class="mr-4 d-inline">Home</p>
</button>
<a class="navbar-brand d-inline mx-5" routerLink="/bio">
<img class="rounded-circle z-depth-2" alt="80x80" height="35" src="https://mdbootstrap.com/img/Photos/Avatars/img%20(31).jpg"
data-holder-rendered="true">
<p class="d-inline mx-3 text-white">text</p>
</a>
</nav>
Sidenav- css
.container {
display: inline-block;
height: 100%;
background-color: white;
}
The other component that I want to be on the rigth of the navside.
The other component html
<mat-grid-list cols="4" rowHeight="500" class="m-5 sidenav-content">
<mat-grid-tile
*ngFor="let tile of tiles"
[colspan]="tile.cols"
[rowspan]="tile.rows"
[style.background]="tile.color">
{{tile.text}}
</mat-grid-tile>
</mat-grid-list>
The other component css
.sidenav-content{
display: flex;
height: 100%;
}

how to make a RTL Menu in angular

Hi i am Learning Angular
I just Made an angular Panel But I want It To Be Rtl But I do not Know How To do That
This Is My Panel
this Is My Html Code
<mat-toolbar color="primary">
<mat-toolbar-row>
<button mat-icon-button >
<mat-icon>menu</mat-icon>
</button>
<span> Admin Panel </span>
<div fxFlex fxLayout="row" fxLayoutAlign="flex-end">
<ul fxLayout="row" fxLayoutGap="20px">
<li>
<button mat-icon-button>
<mat-icon>settings</mat-icon>
</button>
</li>
<li>
<button mat-icon-button>
<mat-icon>help_outline</mat-icon>
</button>
</li>
</ul>
</div>
</mat-toolbar-row>
</mat-toolbar>
This Is My css
ul li{
list-style: none;
}
Do you mean something like that?
Code:
<mat-toolbar color="primary">
<mat-toolbar-row fxLayout="row-reverse">
<button mat-icon-button (click)="sidenav.toggle()">
<mat-icon>menu</mat-icon>
</button>
<span> Admin Panel </span>
<span fxFlex="1 1"></span>
<button mat-icon-button>
<mat-icon>settings</mat-icon>
</button>
<button mat-icon-button>
<mat-icon>help_outline</mat-icon>
</button>
</mat-toolbar-row>
</mat-toolbar>
<mat-sidenav-container>
<mat-sidenav #sidenav position="end">
Sidenav content
</mat-sidenav>
<mat-sidenav-content>
Sidenav content
</mat-sidenav-content>
</mat-sidenav-container>
Using the fxLayout="row-reverse"-property in your <mat-toolbar-row>
Here is a stackblitz: https://stackblitz.com/angular/kgnvebakmpj
fyi if you only have one toolbar row, you can leave out the <mat-toolbar-row>.

nothing works well in mat-sidenav-container angular material 5

I'm using angular 5 and angular material. i have a mat-sidenav-container that consists of mat-sidenav and a mat-sidenav-content. and I have a mat-toolbar in the top of my page. I want to use routerLink in my sidenav-content but it's not working however it works in my mat-toolbar. even a button click function is not working. here are my codes below
<mat-toolbar>
<mat-toolbar-row>
<div>
<button mat-icon-button class="button" (click)="sidemenu.toggle()">
<mat-icon class="menu">menu</mat-icon>
</button>
</div>
<div mat-card-avatar class="example-header-image"></div>
</mat-toolbar-row>
</mat-toolbar>
<mat-sidenav-container class="example-container">
<mat-sidenav mode="side" opened #sidemenu>
<mat-nav-list>
<mat-list-item appAccordionLink>
<a appAccordionToggle>
<mat-icon class="list-icon">inbox</mat-icon>
<span class="link">IncomingMail</span>
<span fxFlex></span>
</a>
</mat-list-item>
</mat-nav-list>
</mat-sidenav>
<mat-sidenav-content>
<a routerLink="/">Home</a>
</mat-sidenav-content>
<router-outlet></router-outlet>
</mat-sidenav-container>