Angular - Active and desactive CSS with multiple selection - css

I need advice.
I need to be able to select two elements.
The second element can be selected by pressing "shift".
How do I take to change the background-colour when I click on an element and remodify when I click on another element?
With an image it might be more meaningful:

You can use a condition like this in your html
[style.background-color]="a.xx? 'purple': 'turquoise'"
or in your component like:
#Component({
selector: 'hello',
template: `
<a-item *ngFor="let a of catalogue"
[a]="a"
[style.background-color]="a.xx ? 'green': 'red'">
</a-item> ` })
You can define a class and change the class when somebody click on other box. It is to say, class ".previous_selected" and "now_selected" and onclick on a new element change the class the new element will have now_selected and the previous element the other class
Other option:
Example:
import { Component } from '#angular/core'
#Component({
selector: 'my-app',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css'],
})
export class AppComponent {
colorA = 'red'
colorB = 'blue'
}
In the HTML
<div [style.color]="isSelected ? colorA : colorB">Some example text</div>
isSelected can be a function that say true o false.
You can find more information here

Related

How to dynamically change styleUrls or style in Angular?

I want to allow users to customize colors and some styles in Angular application. For that I want to make something like this
Structure:
component-one
  folder-with-css-files
    style-for-component-1-for-client1.css
    style-for-component-1-for-client2.css
    style-for-component-1-for-client3.css
    style-for-component-1-for-client4.css
#Component({
selector: 'my-app',
templateUrl: './app.component.html',
styleUrls: ['./app.style-for-component-1-for-client{clientId}.css'],
})
export class AppComponent implements OnInit {
clientId: string;
ngOnInit(): void {
// pseudocode
clientId = service.fetchClientId() // for example
}
}
How I can achieve that? I want to have some css files for every component and depend on user id I want to assign them to styleUrls. Someone can tell me how to do it?
You can use scss and wrap every stylesheet in a different class then based on the user’s selection change the class of your body.
Something like:
DarkMode.scss
.darkMode{
your first css here…
}
LightMode.scss
.lightMode{
your second css here…
}
index.html:
<body class="lightMode"></body>
Doing the above will by default apply the lightMode styling and if you remove the classes of your body in any of your components and replace it with darkMode then the darkMode styling will apply.
Adding/Removing class to/from body:
constructor(private renderer: Renderer2) {}
addClass(){
this.renderer.addClass(document.body, 'className');
}
removeClass(){
this.renderer.removeClass(document.body, 'className');
}
Adding/Removing the class does not have to be only in the index.html file, all you need to do is have a tag with a certain class that wraps around your whole code. For example in one of your components:
component.html:
<div [class]="className">
the rest of your html here...
</div>
component.scss:
.greenDefault{
green default css here...
}
.redDefault{
red default css here...
}
.greyDefault{
grey default css here...
}
component.ts
className: string;
changeStyle(class: string){
this.className = class;
}

Change clr-dg-placeholder icon or background image

I'm using clr-dg-placeholder to set a placeholder in a Clarity Datagrid, but I want to change the background image or icon.
Is it possible without css?
You will have to turn off view encapsulation for the component that has a datagrid in it and also needs the override.
import { Component, ViewEncapsulation } from '#angular/core';
#Component({
selector: 'my-app',
templateUrl: './app.component.html',
styleUrls: [ './app.component.css' ],
encapsulation: ViewEncapsulation.None,
})
export class AppComponent {}
Then you can target the .datagrid-placeholder-image element directly and override the background-image property
.datagrid-host .datagrid .datagrid-table .datagrid-placeholder-container .datagrid-placeholder-image{
background-image: url('data:image/svg+xml;utf8,<svg height="100px" width="100px">YOUR SVG CODE HERE</svg>');
}
Here is a running stackblitz with an override.

Setting a class in a inner element of a component instead of on the selector itself

I would like to add a class into a component in a angular component (v6) using the HostBinding. So far I have the following piece of code:
#Component({
selector: 'app-boat',
templateUrl: './boat.component.html',
styleUrls: ['./boat.component.scss']
})
export class BoatComponent {
#HostBinding('class.dragging') dragging = false;
#HostListener('pointerdown', ['$event'])
onPointerdown(event: PointerEvent): void {
this.dragging = true;
}
}
boat.component.html
<div class="boat" >
<ng-container *ngTemplateOutlet="boatpieces"></ng-container>
</div>
With that example, it will add a class to the app-boat component itself the following way:
<app-boat class="dragging"></app-boat>
but my goal is to inject the "dragging" class to the <div class="boat dragging" >. Is this possible?
One way to do it is with input binding. You can define a boatClass input property in the child component:
export class BoatComponent {
#Input() boatClass: string;
...
}
and apply it to the div element in the template with [ngClass]:
<div class="boat" [ngClass]="boatClass">
<ng-container *ngTemplateOutlet="boatpieces"></ng-container>
</div>
In the parent component, you set the class to the appropriate value:
<app-boat boatClass="dragging"></app-boat>
<app-boat [boatClass]="'dragging'"></app-boat>
<app-boat [boatClass]="getBoatClass()"></app-boat>
See this stackblitz for a demo.
Why not use [ngClass] or [class.draggable] in your Boat Component Template:
<div class="boat" [class.dragging]="dragging">
<ng-container *ngTemplateOutlet="boatpieces"></ng-container>
</div>
Here's a Sample StackBlitz for your ref.

interpolation to a css class in an external file angular 2

I'm wondering if is possible to pass a variable to a css class into an external css file in angular 2, like from:
import { Component } from '#angular/core';
#Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
title = 'app works!';
bgc: string = 'orange'
}
then on the "app.component.css" I would like to pass like
.mydiv{ background: {{bgc}}; }
Is this possible?
I don't think this would be possible.
If you need a style to change programmatically, I would suggest looking into ngStyle at the link below:
https://angular.io/docs/ts/latest/api/common/index/NgStyle-directive.html

Angular 2: How to call the method on a nested component?

I'm trying to call functions on an element declared in my Angular 2 component.
The issue is that I don't know how to retrieve the element from my JS code.
If I can pass the element from the template to the JS code, it works, but
using document.querySelector does not return anything.
Example code (plunk):
#View({
template: `
<div>
<span id="p1">{{name}}</span>
<span #p2>{{name}}</span>
</div>
`,
encapsulation: ViewEncapsulation.Native
})
export class Person {
sayHello(e) {
p1 = document.querySelector('p1');
console.log('p1:', p1)
p2 = document.querySelector('p2');
console.log('p2:', p2)
alert('VanillaId: ' + (p1 ? p1.innerHTML : 'null') +
'\nAngularId: ' + (p2 ? p2.innerHTML : 'null'));
}
}
I suspect that it has something to do with shadow dom, but I don't know how to
get the shadow root and use it to do the query. this doesn't seem to expose
anything useful to access the dom.
Use ElementRef see it here http://plnkr.co/edit/LISYnq?p=preview
I did play around with your plunker:
I don't know how to retrieve the element from my JS code
It strikes me you might be able to just setup your component state in your js code and then mutate/display it usingg property binding, and communicate in/out with events.
If you provide a more specific use case maybe we can offer more advice. Anyway, heres the code:
person.ts
//a simple person component
import {Component, View, ViewEncapsulation, Input, ElementRef} from 'angular2/angular2'
#Component({
selector: 'my-person',
inputs: ['name'],
template: `
<pre>
<span> (Unsuspecting shadow dom node minding its own business)</span>
<span #p0el> Name : {{name}}</span>
<span #p1el> Passed in : {{p1}}</span>
</pre>
`,
encapsulation: ViewEncapsulation.Native
})
export class Person {
public p1:string = "...";
#Input('name') name:string;
constructor (elementRef: ElementRef) {
this.elementRef = elementRef;
}
sayHello(str) {
this.p1 = str;
this.elementRef.nativeElement.shadowRoot.querySelector('span').textContent = "BAM!"
}
}
app.ts
//our root app component
import {Component, View, CORE_DIRECTIVES, ViewEncapsulation} from 'angular2/angular2'
import {Person} from './person'
#Component({
selector: 'my-app',
template: `
<div>
<!-- Passing the element here works fine -->
<button (click)="person.sayHello('Clicked!') && person.name = 'Clicky name'">Test</button>
<my-person #person [name]="'World'"></my-person>
</div>`,
directives: [CORE_DIRECTIVES, Person],
encapsulation: ViewEncapsulation.Native
})
export class App {
test(personComponent: Person) {
}
}

Resources