Angular, ng-templates with if condition - html

I want to call for two separate templates according to role id changes. I can get my role which role as
ngIf="rolet.role.id== adminRoleId
two templates are,
<ng-template #role ></ng-template>
and
<ng-template #admin ></ng-template>

I really don't know how many role in your project. But if you want to use two ng-template,check and test with the following code.
<div *ngIf="ngIf="rolet.role.id== adminRoleId; then #role else #admin"></div>
<ng-template #role>
...
</ng-template>
<ng-template #admin>
....
</ng-template>

You can always use a switch case.
It's faster and say cleaner (personal opinion)
<div [ngSwitch]="num">
<div *ngSwitchCase="'1'">One</div>
<div *ngSwitchCase="'2'">Two</div>
<div *ngSwitchCase="'3'">Three</div>
<div *ngSwitchCase="'4'">Four</div>
<div *ngSwitchCase="'5'">Five</div>
<div *ngSwitchDefault>This is Default</div>
</div>

I put them in separate div tags like this
<div *ngIf="rolet.role.id== adminRoleId">
<ng-template #adimn></ng-template>
</div>
<div *ngIf="rolet.role.id!= adminRoleId">
<ng-template #role></ng-template>
</div>

Related

How can I delete buttons from an ngprime component?

I'm using a picklist primeng component, ant it has buttons that I want to delete but I don't see them in my HTML and y tried searched them but I didn't find them.
This is my HTML.
I got this picklist component from http://primefaces.org/primeng/picklist
and I want to delete the first block of buttons and the last (I only need right and left arrows)
<p-pickList [source]="sourceProducts" [target]="targetProducts" sourceHeader="Listado de clases" targetHeader="Clases asignadas" dragdrop="true"
[sourceStyle]="{'height':'300px'}" [targetStyle]="{'height':'300px'}">
<ng-template let-product pTemplate="item">
<div class="product-item">
<div class="product-list-detail">
<h5 class="mb-2">{{product.name}}</h5>
<i class="pi pi-tag product-category-icon"></i>
<span class="product-category">{{product.category}}</span>
</div>
<div class="product-list-action">
<span [class]="'product-badge status-' + product.inventoryStatus.toLowerCase()">{{product.inventoryStatus}}</span>
</div>
</div>
</ng-template>
</p-pickList>
I reviewed the picklist.d.ts file but I didn't find anything
You need to add showSourceControls and showTargetControls properties.
like this :
<p-pickList [showSourceControls]="false" [showTargetControls]="false"></p-pickList>

Using ng-content with *ngtemplateOutlet not show in DOM

I have three Angular component, one base component and two child component (child1 and child2), with these structure:
child1.component.html
<ng-template #child1Template>
<div>
<h1>CHILD 1</h1>
</div>
</ng-template>
child2.component.html
<ng-template #child2Template>
<div>
<h1>CHILD 2</h1>
</div>
</ng-template>
base.component.html
<app-child1 #wrapper_child1 class="hidden"></app-child1>
<app-child2 #wrapper_child2 class="hidden"></app-child2>
<div class="baseContainer">
<ng-content *ngTemplateOutlet="wrapper_child1.child1Template"></ng-content>
<ng-content *ngTemplateOutlet="wrapper_child2.child1Template"></ng-content>
</div>
When I inspect the DOM, it shows child1 correctly but child2 not appears and there is that
<!--bindings={
"ng-reflect-ng-template-outlet": "[object Object]"
}-->
Anyone has some explenation?
Please note that my structure absolutely needs this structure because I need to insert the content of childs in the base component WITHOUT adding additional html tags.
Thanks!
Thanks to Vovan_Super I solved my issue adding this line of code in childs component
#ViewChild('child1Template') child1Template: TemplateRef<any>;

Angular: check if one of the ng-content slots provided

I have component template with multiple ng-content elements:
<div class="form__general">
<ng-content select="[general]"></ng-content>
</div>
<div class="form__footer">
<ng-content select="[footer]"></ng-content>
</div>
How can I check inside *ngIf condition is #footer is provided?
I tried something like this, but this does not work:
<div *ngIf="#footer" class="form__footer">
<ng-content select="[footer]"></ng-content>
</div>
Remove # from the condition check.
Sample Code Snippet:
app.component.html
<h1 #footer>Welcome</h1>
<child-comp>
<div *ngIf="footer.innerText === 'Welcome'" class="form__footer">
Hi There
</div>
</child-comp>
child.component.html
<ng-content select=".form__footer"></ng-content>

Can you extract part of HTML to template and call it from more than one place

I have duplicate code in my HTML. When I have it in Java i mark the code in IntelliJ and select "extract method" => "replace 2 occurrences".
I want to do the same for HTML and have the following solution, but I think its ugly:
<ng-template #banner1>
stuff...
</ng-template>
<ng-template #banner2>
other stuff...
</ng-template>
<div class="row tight">
<div class="col-sm-6 hidden-print">
<ng-container *ngIf="false; else banner1"></ng-container>
</div>
<div class="col-sm-6 hidden-print">
<div class="col-sm-7">
<ng-container *ngIf="false; else banner2"></ng-container>
</div>
<div class="col-sm-5">
stuff3...
</div>
</div>
<div class="col-sm-8 visible-print">
<ng-container *ngIf="false; else banner1"></ng-container>
</div>
<div class="col-sm-4 visible-print">
<ng-container *ngIf="false; else banner2"></ng-container>
</div>
</div>
The code above WORKS (if I have copy/paste it correctly) but it needs improvement...
The whole reason for the duplicated code is that I want different styling for the code when printing on paper and then viewing on screen.
I don't like this part:
<ng-container *ngIf="false; else banner1"></ng-container>
I want something like
<ng-inject template="banner1"></ng-inject>
or something even better.
There's ngTemplateOutlet directive that can help you with this. The syntax is very simple - <ng-container *ngTemplateOutlet="yourTemplate"></ng-container>
Example - https://stackblitz.com/edit/angular-xh9ebz
You can use property bindings concept something like
TS Side
htmlOfStuff = "<h1>HTML CODE</h1>";
HTML side
<div [innerHtml]="htmlOfStuff"></div>

Add class with [ngClass] depending on local html condition

I have used [ngClass] in the past, applying classes depending on the Boolean value of a variable held in the javascript/typescript before. However I am wondering if it is possible to apply it based on a local HTML boolean value or not?
ie.
<div class="card" *ngFor="let item of data" #panel ngClass="{expanded: isExpanded}">
<div class="header">
<div class="itemName">Text</div>
<div class="itemDir">Some more text</div>
<mat-icon *ngIf="!panel.isExpanded" (click)="panel.isExpanded=true">edit</mat-icon>
<mat-icon *ngIf="panel.isExpanded" (click)="panel.isExpanded=false">cancel</mat-icon>
</div>
</div>
Here, I am displaying one of two icons, depending on the local isExpanded variable defined within the HTML and not the backend.
I am wanting to apply a class based on this value... is it possible?
Here is what I am working on
use like [class.expanded]="isExpanded". binding to class.expanded trumps the class attribute
<div class="card" *ngFor="let item of data" #panel [class.expanded]="panel.isExpanded" [class.notExpanded]="!panel.isExpanded">
you can use *ngIf="true as isExpanded" to make variable on the template
<div class="card" *ngFor="let item of [1,2,3,4];" >
<div class="header" *ngIf="true as isExpanded" ngClass="{expanded: !isExpanded}">
<div class="itemName">Text</div>
<div class="itemDir">Some more text</div>
<div *ngIf="isExpanded" (click)="isExpanded=!isExpanded">edit</div>
<div *ngIf="!isExpanded" (click)="isExpanded=!isExpanded">cancel</div>
</div>
</div>
stackblitz demo 👍👍
<div class="card" *ngFor="let item of data" #panel ngClass="{expanded: isExpanded}">
<div class="header">
<div class="itemName">{{item.name}}</div>
<div class="itemDir">{{item.directory}}</div>
<mat-icon *ngIf="!isExpanded;else other_content" (click)="isExpanded=true">edit</mat-icon>
<ng-template #other_content>Other Icon goes here</ng-template>
</div>
You can refer the above code which use If and else by template referenced variable which properly toggle between both icon and non Icon