How to style encapsulated child components in angular?
Following are the child and parent components with view encapsulation enabled.
** child
//template
<div class="child-container"> </div>
// class
#Component({
selector: "app-child",
templateUrl: "./child.component.html",
styleUrls: ["./child.component.css"],
encapsulation: ViewEncapsulation.ShadowDom
})
** parent
//template
<div class="parent-container"> </div>
// class
#Component({
selector: "app-parent",
templateUrl: "./parent.component.html",
styleUrls: ["./parent.component.css"],
encapsulation: ViewEncapsulation.ShadowDom
})
How can I select a particular class inside the Child component from the parent component's stylesheet and change it's style?
** parent
//template
<div class="parent-container">
<app-child></app-child>
</div>
// class
#Component({
selector: "app-parent",
templateUrl: "./parent.component.html",
styleUrls: ["./parent.component.css"],
encapsulation: ViewEncapsulation.ShadowDom
})
//styles
app-child {
.child-container {
background colour: red;
}
}
Currently when I try to select a class from the child component, I'm not being able to override it's styles. Please help!
Remember that ViewEncapsulation.ShadowDom is required for my used cased. So we have to keep that in mind.
css variables are accessible through the shadow dom..
so in your app-parent component scss, you should be able to do something like
--child-comp-background: red;
and in your app child component scss,
background-color: var(--child-comp-background, white) //white is a default incase the variable isnt defined or passed down from the parent
you can use :host-context() to do that
:host-context(.parent-container) .child-container{
...style here
}
Here the demo: Demo
Related
The below clicked() function is triggering when a click is performed on the below label. It does not trigger when click is performed on glyphicon icon.
<div>
<span class="glyphicon glyphicon-heart" [class.highlight]="isActive" (click)="clicked()"></span>
</div>
<div><label >{{count}}</label></div>
This is the css File
.glyphicon{
color:#ccc;
cursor:pointer;
}
.highlight{
color:deeppink;
}
This is the ts file
import { Component, OnInit, Input,Output,EventEmitter } from '#angular/core';
#Component({
selector: 'likecounter',
templateUrl: './likecounter.component.html',
styleUrls: ['./likecounter.component.css']
})
export class LikecounterComponent implements OnInit {
#Input() count = 0
#Input() isActive = false
#Output() click = new EventEmitter()
constructor() { }
ngOnInit(): void {
}
clicked(){
this.click.emit()
}
}
You need to insert some content in span, so it may be visible in DOM.
<span class="glyphicon glyphicon-heart" [class.highlight]="isActive"
(click)="clicked()">Click Me</span>
This will solve your issue.
changing output event name form click to someothername worked.
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>
Here's the code:
list.component.html
<nz-radio-group formControlName="radiostatus" [(ngModel)]="radioValue" (ngModelChange)="onChangeStatus($event)">
<label nz-radio nzValue="passed">Passed</label>
<label nz-radio nzValue="failed">Failed</label>
</nz-radio-group>
<div>
<textarea nz-input class="remarks-textarea" type="text" name="otherRemark" formControlName="remark" [(ngModel)]="otherRemark"
[nzAutosize]="{ minRows: 3, maxRows: 3 }"></textarea>
</div>
how to show the div which it has a textarea, it will show when in radio button select the failed and it will hide when it clicked the passed.
thanks in advance
Please find below image which has all formcontrol and (ngModelChange).
I think there is some issue with initialization. If you can elaborate more about your code that can help you to check further.
Thanks.
You may be try to add *ngIf condition on div
<div *ngIf="radioValue === 'failed'">
Use like bellow example:
HTML:
<form [formGroup]="radioForm">
<nz-radio-group formControlName="radiostatus" [(ngModel)]="radioValue" (ngModelChange)="onChangeStatus($event)">
<label nz-radio nzValue="passed">Passed</label>
<label nz-radio nzValue="failed">Failed</label>
</nz-radio-group>
<div *ngIf="radioValue === 'failed'">
<textarea nz-input class="remarks-textarea" type="text" name="otherRemark" formControlName="remark" [(ngModel)]="otherRemark"
[nzAutosize]="{ minRows: 3, maxRows: 3 }"></textarea>
</div>
</form>
Component ts:
import { Component } from '#angular/core';
import { FormGroup, FormControl } from '#angular/forms';
#Component({
selector: 'my-app',
templateUrl: './app.component.html',
styleUrls: [ './app.component.css' ]
})
export class AppComponent {
radioForm = new FormGroup({
radiostatus: new FormControl(''),
remark: new FormControl('')
});
onChangeStatus($event){
console.log($event);
}
}
Also you could use like [hidden]="radioValue !== 'failed'" instead of *ngIf="radioValue === 'failed'"
WORKING DEMO
I'm new to Angular 7, was trying to implment a feature but got stucked.
There are three divisions namely left, right and middle. middle div contains 2 more divisions inside it and those 2 divisions contains button inside them. I have applied col-md-6 class to middle division and whenever I click on left button inside middle div, I want the left division to be hidden and change the class of middle div from col-md-6 to col-md-9 and If both left and right div's are hidden I want the class of middle div to change from col-md-9 to col-md-12. I have tried using Renderer2, using addClass() and removeClass(). It's working with hostlistener, whenever I click on host element. But I want this functionality to work whenever I click on button. If there is any other method achieving this, then please suggest whether using Elementref or renderer2.
home-page.component.html
**left division**
<div class="col-md-3 sidebar" #leftBar style="background-color: #F8F4F4;">
</div>
** middle div**
<div class="md-center col-md-6" id="content" #content>
**left button**
<div class="btn toggle-sidebar-left" #t1 appSideBar>
<mat-icon> {{!leftBarHidden ? 'chevron_left' : 'chevron_right' }}
</maticon>
</div>
** right button **
<div class="btn toggle-sidebar-left" (click)="hide()" #t1>
<mat-icon>
{{!leftBarHidden ? 'chevron_left' : 'chevron_right' }}
</mat-icon>
</div>
</div>
**right div**
<div class="col-md-3 sidebar scrollbar" *ngIf="!rightBarHidden" id="sidebar-
right" style="background-color: #F8F4F4;">
</div>
home-page.component.ts
import { AfterViewInit, Component, OnInit, Input, Renderer2, ElementRef,
ViewChild, HostListener, ViewChildren } from '#angular/core';
import { Router } from '#angular/router';
import { SideBarDirective } from './appSideBar';
#Component({
selector: 'app-home-page',
templateUrl: './home-page.component.html',
styleUrls: ['./home-page.component.css']
})
export class HomePageComponent implements OnInit, AfterViewInit {
rightBarHidden = false;
leftBarHidden = false;
constructor(private router: Router, private render: Renderer2,
private el: Elemen Ref) { }
#ViewChild('leftBar') LeftBar:ElementRef; // leftbar is variable for
accessing left div.
#ViewChild('content') content:ElementRef; // content is variable for middle
div
#ViewChild('t1') t1:ElementRef; //t1 is variable for left button inside
middle div
#HostListener('click')
onclick() {
this.leftBarHidden = !this.leftBarHidden;
if (this.leftBarHidden)
{
const b = this.LeftBar.nativeElement;
this.render.removeStyle(b, 'display');
this.render.setStyle(b, 'display', 'none');
const b = this.LeftBar.nativeElement;
const c=this.render.parentNode(this.t1.nativeElement);
this.render.removeClass(c,'col-md-6');
this.render.addClass(c,'col-md-9');
this.render.removeClass(this.content.nativeElement, 'col-md-6');
this.render.addClass(this.content.nativeElement, 'col-md-9');
}
else {
this.render.removeStyle(b, 'display');
this.render.setStyle(b, 'display', 'block');
console.log(b);
}
}
I wish to add a class name to NG2 directive in order to apply CSS rules on it. Given the following component:
#Component({
moduleId: module.id,
selector: 'search-form',
templateUrl: 'search-form.component.html',
styleUrls: [ 'search-form.component.css']
})
I tried this:
search-form {
width:100%;
display:block;
}
But it did not work.
How can I add a class to search-form ?
#Component({ // or #Directive({
// use `host:` or `#HostBinding()` (not both)
// host: {'[class.someclass]': 'true'}
})
class SearchFormComponent {
#HostBinding('class.someclass')
someClass = true;
}
Perhaps you mean adding styles to "self" by adding this CSS to search-form.component.css
:host {
width:100%;
display:block;
}
You declare CSS classes in your stylesheet .. search-form.component.css
If you want to target the component in your stylesheet then you could do ...
search-form {
width:100%;
display:block;
}
This will target elements with the tag search-form.
Because Angular2 is component based, it only targets elements inside the component. I am not sure if it will target the actual element itself but I think it will.
I can show an example of this.
Firstly create a stylesheet. like
<style>
.red
{
color:red;
}
.blue
{
color:blue;
}
</style>
Then in your HTML include your style sheet along with angular.min.js and create a dropdown as below.
<select ng-model="a">
<option value="red">red</option>
<option value="blue">blue</option>
</select>
Then create a H1 tag like below.
<h1 ng-class="a">Header color</h1>
Note. HTML has to be within the div of ng-app you create.
Hope this helps. All the best.