can not add class name from app.component.css - javascript

I'm learning Angular and can not resolve how to add class names from CSS component
I'm writing a code demo that displays the weather condition of the city. If a city has cold temp, it will have blue color
I want to add class "express" to tags but I have tried ngClass and className from Angular but it is not working
This is my Angular code
app.component.ts
import { Component } from '#angular/core';
#Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
title = 'traning';
public cities =[{
name: 'montreal ',temp: -30
},{
name: 'toronto ', temp: 19
},{
name:'vancouver ',temp: -4
}];
;
}
app.component.css
.express {
color: rgb(13, 142, 255);
}
app.component.html
<head>
<link href="./app.component.css" rel="stylesheet" >
</head>
<table>
<tr>
<th>City</th>
<th>temp</th>
</tr>
<tr *ngFor="let city of cities">
<td >{{city.name}}</td>
<td class="express" *ngIf="city.temp <0; then cold; else cool" >{{city.temp}}</td>
<ng-template #cold> cold</ng-template>
<ng-template #cool> cool</ng-template>
</tr>
</table>
Here is my Angular demo run
Demo of AngularJS
I want to add class "express" to <>td> tags but do not know how

Since you're using an *ngIf directive with an explicit then clause, the <td class="express"> element is ignored altogether in favor of the <ng-template #cold> element that is referenced from the then cold clause.
Take a look at this "Using an external then template" section of the NgIf Angular documentation. You'll notice, in the example it gives, the following line:
<div *ngIf="show; then thenBlock; else elseBlock">this is ignored</div>
As is suggested, the entire element to which the *ngIf directive is applied, is ignored when using an external then template (this is what you're doing).
It seems that you'd like to render the <td class="express"> with dynamic content inside of it. That might look like the following:
<td class="express">
{{city.temp}}
<ng-container *ngIf="city.temp < 0; then cold; else cool"></ng-container>
<ng-template #cold> cold</ng-template>
<ng-template #cool> cool</ng-template>
</td>
Or using an implicit then template:
<td class="express">
{{city.temp}}
<div *ngIf="city.temp < 0; else cool"> cold</div>
<ng-template #cool> cool</ng-template>
</td>`
Alternatively, if all you need is dynamic text, I might suggest the following:
<td class="express">
{{city.temp}} {{city.temp < 0 ? "cold" : "cool"}}
</td>

Related

Preserve the whitespaces of an element while using *ngFor

I am using Angular.js, *ngFor for looping over the array and display the values. I want to preserve the spaces of an elements like array is,
string arr1 = [" Welcome Angular ", "Line1", "Line2", "
Done "]
I have used :
<div *ngFor="let arrValue of arr1">
{{arrValue}}
</div>
current output:
Welcome Angular
Line1
Line2
Done
Expected output:
Welcome Angular
Line1
Line2
Done
How to preserve the spaces of an elements like array without any modification.
Here, link for stackblitz where displaying by looping over. You can perform practical and Please let me know if you figure out way to preserve element with white spaces.
Thank you in advance.
https://stackblitz.com/edit/ngfor-examples?file=app%2Fapp.component.ts,app%2Fapp.component.css
Use the css style white-space: pre;
css
.preserve-whitespace {
white-space: pre;
}
ts
import { Component } from '#angular/core';
#Component({
selector: 'my-app',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css'],
})
export class AppComponent {
arr1 = [' Welcome Angular ', 'Line1', 'Line2', ' Done '];
name = 'Angular';
}
html
<div *ngFor="let arrValue of arr1" class="preserve-whitespace">
{{ arrValue }}
</div>
forked stackblitz
You could try this
<div *ngFor="let arrValue of arr1">
<pre>{{arrValue}}</pre>
</div>
Similar to all the answers above you can use CSS's white-space: pre-wrap; to accomplish this goal. You can either do it inline which would look like this:
yourComponent.html
<div style="white-space: pre-wrap;">
Or you could add a CSS attribute to the div you want like so:
styles.scss
.white-space {
white-space: pre-wrap;
}
yourComponent.html
<div class="white-space">
Try the following:
<div *ngFor="let arrValue of arr1">
<pre>
{{arrValue}}
</pre>
</div>

How to show specific data on mouse hover of specific column into table in angular 8

I have a simple json. I need to show specific related span/vehicle_name on mouse hover of specific 'status' . Now when I hover on status(red or yellow) on my table column both vehicle_name is showing.Here I want to show only specific vehicle_name on mouse hover of specific status. Here is the code below
Demo : https://stackblitz.com/edit/angular-d8cwtw?file=src%2Fapp%2Fapp.component.ts
home.component.html
<div>
<table>
<tr *ngFor="let x of statusdata1;">
<td style="border:1px solid"><span>{{x.vehicle_number}}</span></td>
<td style="border:1px solid"><span (mouseover)="show()" (mouseout)="hide()">{{x.status}}</span><span *ngIf="showit">{{x.vehicle_name}}</span></td>
</tr>
</table>
</div>
home.component.ts
import { Component, OnInit } from '#angular/core';
#Component({
selector: 'app-home',
templateUrl: './home.component.html',
styleUrls: ['./home.component.css']
})
export class HomeComponent implements OnInit {
imageSource :any;
statusdata1: any;
showit:boolean = false;
constructor() {}
ngOnInit() {
/* First data */
this.statusdata1 = [{"vehicle_number":1,"vehicle_name":"car","status":"yellow"},{"vehicle_number":2,"vehicle_name":"bus","status":"red"}];
console.log(this.statusdata1);
}
show(){
this.showit= true;
}
hide(){
this.showit= false;
}
}
Good day!
To be honest, I can suggest to you is just move this logic to separate dummy component, with such template:
<span (mouseover)="show()" (mouseout)="hide()">{{x.status}}</span>
<span *ngIf="showIt">{{x.vehicle_name}}</span>
So, in this case you showIt boolean will be bonded to particular component and you needn't do some extra logic.
If you don't wont to do it, I think you should have additional variable (index of table row on which mouseover event triggers) and inner your template you should have such condition:
<tr *ngFor="let x of statusdata1; index as idx">
<td style="border:1px solid"><span>{{x.vehicle_number}}</span></td>
<td style="border:1px solid">
<span (mouseover)="show(idx)" (mouseout)="hide(idx)">{{x.status}}</span>
<span *ngIf="showit && idx === currentIdx">{{x.vehicle_name}}</span>
</td>
</tr>
Also I can suggest to you the clearest and performant solution from my option - use data-content attribute, check it out: https://davidwalsh.name/css-content-attr
.html
<table>
<tr *ngFor="let x of statusdata1">
<td>
<span>{{ x.vehicle_number }}</span>
</td>
<td>
<span class="status" [attr.data-line]="x.vehicle_name">
{{ x.status }}
</span>
</td>
</tr>
</table>
.css
td {
border: 1px solid;
}
span[data-line]:hover:after {
content: attr(data-line);
}
Demo: https://stackblitz.com/edit/angular-qowzj3

Add border and background color when I click the yes button

I am developing a kind of text boxes for comments.
When I click on the YES button I would like the box where the click came from, to have some kind of borders and a background color in order to signal that the click came from that box.
Can someone help me?
BLITZ
code
<div class="Submitcomments" *ngFor="let c of data; let i = index;">
<div>
<div class="row rowComments" style="margin-top: 11px;">
</div>
<div class="form-group">
<textarea #myinput type="text" class="form-control AreaText" rows="2"></textarea>
</div>
<div class="row" style="margin-top: -20px; margin-left: 5px;">
<button *ngIf="c.currentState=='pause'" class="btn reply" (click)="adjustState(i)">Yes</button>
<button *ngIf="c.currentState=='start'" class="btn reply1" (click)="adjustState(i)">No</button>
</div>
</div>
</div>
Try to use the [ngStyle] binding in your html.
Something like this:
<textarea #myinput type="text" class="form-control AreaText" rows="2"
[ngStyle]="{
'background-color': c.currentState=='start' ? '#daf4d5' : 'initial',
'border': c.currentState=='start' ? '1px solid green' : ''
}">
</textarea>
There are shorter ways to write the ngStyle but this one allows you to choose a style for box elements that aren't clicked too.
Also, you might want to move the ngStyle value in your component as a string, and use that instead (to make the html more readable).
You can use use AfterViewInit to wait until the component has loaded. Then just update each textarea styles everytime the child btn is clicked inside of each element .Submitcomments.
import { Component, ViewChild, ElementRef, AfterViewInit } from '#angular/core';
#Component({
selector: 'my-app',
templateUrl: './app.component.html',
styleUrls: [ './app.component.css' ]
})
export class AppComponent implements AfterViewInit {
ngAfterViewInit() {
let submitComments = document.querySelectorAll('.Submitcomments');
[].slice.call(submitComments).forEach((submitComment, index) => {
submitComment.querySelector('.btn').addEventListener('click', (event) => {
submitComment.querySelector('textarea').style.border = '1px solid red';
});
});
}
https://stackblitz.com/edit/angular-qe9hac?file=src/app/app.component.ts
NOTE: I'm not an angular 2 developer, so I'm sure there is a more "angular" type of way to do this. But this works for now.
try this also don't forget to upvote me if this is what you need becuse this takes time for me to do and i dont have time wasting to do this alot but if this isnt working at all you dont have to upvote me im just saying if it works remember to upvote me
window.onload = function() {
//onclick event
document.getElementById("yes").onclick = function fun() {
var element = document.getElementById("yes");
element.classList.add("yeep");
element.classList.remove("unk");
}
}
.yeep{
background-color:green ;
border-color:limegreen ;
border-width:5px;
color:white;
}
.unk{
background-color:darkgray;
border-color:gray;
border-width:5px;
color:white;
}
<button class='unk' id = 'yes'>yes!</button>

How to hide and show table tree row using Angular 5 directives

Just need the table tree by clicking on the row which needs to hide and show using angular 5. The following code will highlight the row. I have tried a lot of solutions. Please help me to hide the table tree and show child rows. The table tree structure is as follows :parent rows:1 ,2 ,3 ,4-this needs to display initially. Then by clicking on the parent 1 row it should display the child of 1.1,1.2.
import {
Directive,
Renderer2,
OnInit,
ElementRef,
HostListener,
HostBinding,
Input
} from '#angular/core';
#Directive({
selector: '[appBetterHighlight]'
})
export class BetterHighlightDirective implements OnInit {
#HostBinding('style.backgroundColor') backgroundColor: string;
constructor(private elRef: ElementRef, private renderer: Renderer2) { }
ngOnInit() {
this.backgroundColor = this.defaultColor;
// this.renderer.setStyle(this.elRef.nativeElement, 'background-color', 'blue');
}
#HostListener('mouseenter') mouseover(eventData: Event) {
// this.renderer.setStyle(this.elRef.nativeElement, 'background-color', 'blue');
this.backgroundColor = 'blue';
}
#HostListener('mouseleave') mouseleave(eventData: Event) {
// this.renderer.setStyle(this.elRef.nativeElement, 'background-color', 'transparent');
this.backgroundColor = 'blue';
}
}
<div class="table-responsive">
<table class="table table-striped">
<thead>
<tr>
<th>one</th>
<th>two</th>
<th>three</th>
</tr>
</thead>
<tbody >
<tr *ngFor="let demo of demoData" appBetterHighlight>
<td>{{demo.one}}</td>
<td>{{demo.two}}</td>
<td>{{demo.three}}</td>
</tr>
<tr *ngFor="let demo of demoData" [style.display]="'none'" appBetterHighlight>
<td>{{demo.one}}</td>
<td>{{demo.two}}</td>
<td>{{demo.three}}</td>
</tr>
</tbody>
</table>
</div>

Displaying link conditionally in Angular.js

Basically, I have this code in my template:
<tr ng-repeat="entry in tableEntries">
<td ng-switch="entry.url == ''">
<span ng-switch-when="false">{{entry.school}}</span>
<span ng-switch-when="true">{{entry.school}}</span>
</td>
...
</tr>
As you can see I'm trying to display a clickable URL when entry.url is not empty and a plain text otherwise. It works fine, but it looks quite ugly. Is there a more elegant solution?
Another way I can think of doing it is using ng-if:
<td>
<span ng-if="entry.url != ''">{{entry.school}}</span>
<span ng-if="entry.url == ''">{{entry.school}}</span>
</td>
But then I would be repeating almost the same comparison twice, which looks even worse. How would you guys approach this?
You can try.
<div ng-show="!link">hello</div>
<div ng-show="!!link">hello</div>
But the ngSwitch which you are using should be fine.
Use double negation, it cast into boolean thus !!entry.url will return true if string is not empty.
<td ng-switch="!!entry.url">
<span ng-switch-when="true">{{entry.school}}</span>
<span ng-switch-when="false">{{entry.school}}</span>
</td>
A good read What is the !! (not not) operator in JavaScript? and Double negation (!!) in javascript - what is the purpose?
You can create a custom directive that hides the complexity:
HTML
<tr ng-repeat="entry in tableEntries">
<td>
<link model="entry"></link>
</td>
...
</tr>
JS
app.directive('link', function() {
return {
restrict: 'E',
scope: {
model: '='
},
template: '<a ng-if="model.url != ''" href="{{model.url}}">{{model.school}}</a><span ng-if="model.url == ''"> {{ model.school }}</span>'
}
});
I would recommend having an ng-class="{'className': whenEntryURLisWhatever}" in your td, and make it change the css styles accessed, e.g:
td span{ /*#normal styles#*/ }
.className span{ /*#styles in the case of added classname (when it is a link)#*/
text-decoration: underline;
cursor: pointer;
}
Then just change what happens on ng-click within a function defined in your javascript code.
$scope.yourFunction = function(url){
if(!!url){
window.location = YourURL;
}
}
This would cut down on code repetition, as your html could now be:
<tr ng-repeat="entry in tableEntries">
<td ng-class="{'className': !!entry.url}">
<span ng-click="yourFunction(entry.url)">{{entry.school}}</span>
</td>
...
</tr>

Categories

Resources