How change component html template in angular 2? - html

For example I have this component with a simple template:
<div>
<h2>Hello!!!</h2>
</div>
and I want to add this new template tag:
<div>
<h2>Hello!!!</h2>
<div class = "new-tag">
</div>
</div>
How can I do this?
Thanks.

Use a structural directive like *ngIf
<div>
<h2>Hello!!!</h2>
<div *ngIf="showNew" class = "new-tag"></div>
<button (click)="showNew = true">click me</button>
</div>

Related

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>

Calling the CSS style from typescript append it to html file

On button click function CSS style to be called with in the TS file
html code:
<div class="overlay-loader">
<div *ngIf="isLoading" class="loader"></div>
<p *ngIf="results">{{ results | json }}</p>
<p *ngIf="error">Error: {{ error | json }}</p>
</div>
<p>
<button (click)="getResult()">Get result</button>
</p>
Link which i have tried:https://stackblitz.com/edit/angular-loader-kspfhg?ctl=1&embed=1&file=app/app.component.html&view=editor
After clicking the button overlay-loader css class to be loaded and once data get fetched css overlay-loader to be dissaper
Use ngClass to add a class conditionally:
<div [ngClass]="{'overlay-loader': isLoading}">

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

Setting the div in angular to different color on click

So though my question might sound familiar the case is a bit different. I have a screen with multiple tasks. To show the tasks I am iterating via the data and my code looks something like
<div *ngFor="let task of tasks" class="scheduleContainer inline-block shadow">
<div id="myHeader" #myHeader class="activeHeader">
{{task.title}}
</div>
<div class="detailsBox">
<div class="row">
<div class="offset-md-1 col-md-auto">
Last Date:
</div>
<div class="col-md-auto">
{{task.lastDate}}
</div>
</div>
<div class="row">
<div class="offset-md-1 col-md-auto">
Duration:
</div>
<div class="col-md-auto">
{{task.duration}}
</div>
</div>
<div class="row">
<div class="offset-md-1 col-md-auto">
Total Runs:
</div>
<div class="col-md-auto">
{{task.totalRun}}
</div>
</div>
</div>
<div class="footer">
<a [routerLink]="['edit-scheduled-tasks']">edit schedule</a>
<a [routerLink]="['view-history-scheduled-tasks']">view history</a>
<a (click)="onClick()">enable task</a>
run now
</div>
</div>
<router-outlet></router-outlet>
Now when I click on the enabled task, I would like the color of that particular div to be changed. In my component, I tried something like
onClick() {
this.myHeader.nativeElement.style.background = 'red';
}
So this did change the color but it did not change the current task but rather some other task. Suggestions?
you can access myHeader from template so you can change the color something like this
<div id="myHeader" #myHeader class="activeHeader">
Change the color by myHeader variable
</div>
<button (click)="myHeader.style.background='red'">click</button>
or you can use a property with ngStyle like this
<div [ngStyle]="{'background-color':color}" >
Another way by ngStyle
</div>
<button (click)="color='red'">click</button>
or you can use a property to toggle class with ngClass
<div [ngClass]="{'red':isClicked}" >
Set class
</div>
<button (click)="isClicked=!isClicked">Toggle class</button>
Example toggle color of taskList by useing ngClass
template
<div *ngFor="let task of taskList"
[ngClass]="{'red':selectedTasks[task.id]}"
(click)="selectedTasks[task.id]= !selectedTasks[task.id]" class="task">
{{task.name}}
</div>
or you can use button to toggle the state
<div *ngFor="let task of taskList"
[ngClass]="{'red':selectedTasks[task.id]}"
class="task">
{{task.name}}
<button (click)="selectedTasks[task.id]= !selectedTasks[task.id]">toggle {{task.name}}</button>
</div>
if you want to set the state without toggle on click event just set
the state to true like this selectedTasks[task.id] =true
component
taskList =[
{id:1 , name:'Task 01'},
{id:2 , name:'Task 02'},
{id:3 , name:'Task 03'},
{id:4 , name:'Task 04'},
{id:5 , name:'Task 05'},
];
selectedTasks = {};
stackblitz demo
Not a clean way to do, but it still works. Send an index of selected element to onClick(i) and add the color to selected div. So that you don't mess with template reference.
html
<div *ngFor="let task of tasks; let i=index;" class="scheduleContainer inline-block shadow">
<div id="myHeader" #myHeader class="activeHeader">
{{task}}
</div>
<div class="footer">
<a (click)="onClick(i)">enable task</a>
</div>
</div>
component.ts
onClick(index: number) {
document.querySelectorAll('#myHeader')[index]
.style.background = 'red';
}
DEMO
It's not a good practice to manipulate DOM directly.
Angular: Stop manipulating DOM with ElementRef!
As an alternate, It's easy to bind inline style in your Angular templates using style binding.
Since you would like the color of that particular div to be changed. Use A boolean array:
component:
export class AppComponent {
name = 'Angular';
public styleArray=new Array<boolean>(10);
onClick(i)
{
this.styleArray[i]=true;
}
}
While Iterating pass index to onClick(i) to set particular index of array true and apply style dynamically
[style.color]="styleArray[i] ? 'green':'black'"
<div *ngFor="let task of tasks; let i=index" class="scheduleContainer inline-block shadow">
<div id="myHeader" [style.color]="styleArray[i] ? 'green':'black'" class="activeHeader">
{{task.title}}
</div>
........rest of the code
<a (click)="onClick(i)">enable task</a>
Live Demo

How to pass a html template through props to a react component?

I have a popup up window react component. I want to pass in templates to the component via props.
Here is an example of my popup
popup = (
<div>
<Popup text='This is a popup'
popupEl={ popupEl }
/>
</div>
);
The popup component works if the popupElements value is a button on its own, or a list of checkboxes. But I want to pass in an entire template. Unfortunately the popupElements prop is seen as undefined when I try to do so.
Here is a very basic example of a template I want to pass in. Is there something I'm missing here?
popupEl = (
<div>
<div>
<h1> hi </h1>
</div>
<div>
<button>CLOSE</button>
</div>
</div>
);
The popupEl should be a function which returns JSX,
popupEl = () =>
<div>
<div>
<h1> hi </h1>
</div>
<div>
<button>CLOSE</button>
</div>
</div>
);