How to change button colour on click? - css

I want to change my button colour on click using angular and css as I am very new to it.
.ts
import { Component } from '#angular/core';
#Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.scss']
})
export class AppComponent {
title = 'title';
}
.html
<mat-sidenav color="primary" #sidenav fxLayout="column" mode="over" opened="false" fxHide.gt-sm="true">
<div fxLayout="column">
<button mat-button style="text-align:left" routerLink="butn1" >Attend</button>
<button mat-button style="text-align:left" routerLink="butn2" >Host</button>
<button mat-button style="text-align:left" routerLink="contact" >Contact</button>
<button mat-button style="text-align:left" routerLink="login" >Login</button>
</div>
</mat-sidenav>

You can add this in the html button tag
‘<button [class.mycolorclass]=’hasClicked’ (click)=’hasClicked=true’
The logic in the click directive can be moved into a method in the typescript class if you prefer that

I'm not familiar with angular, but CSS :active should manage to do this:
button {
line-height: 30px;
height: 30px;
font-size: 15px;
color: red;
border: 1px solid black;
background-color: #eee;
color: black;
}
button:active {
color: red;
border-color: red;
}
<button>Click me!</button>

on button click set variable true/false as per your requirement
buttonClicked=false;
onButtonClick(){
this.buttonClicked=true;
}
and give condition in HTML like this
<button mat-button
[ngClass]="buttonClicked? 'myClassHighlighted' : 'none'"
style="text-align:left" routerLink="attend" >Attend</button>
and in css add classes like
.myClassHighlighted{
//your styles here
}
.none{
//your styles here
}

Use ngClass in your buttons to give 'em conditional classes based on a flag which is set true only when you click on that button so I guess you will need ngClick as well, well I don't know about the version of Angular that you are using right now cuz you didn't mention that but now you know you will need ngClass and ngClick for sure and your code might look like sth like this:
<button mat-button style="text-align:left" [ngClass]="{'button--clicked': clicked}" routerLink="attend" (click)="clicked=!clicked" >Attend</button>

.ts
import { Component } from '#angular/core';
#Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.scss']
})
export class AppComponent {
title = 'title';
buttons = [
{ title: 'Attend', link: 'butn1', active: false },
{ title: 'Host', link: 'butn2', active: false },
{ title: 'Contact', link: 'contact', active: false },
{ title: 'Login', link: 'login', active: false },
]
toggleColor(button) {
button.active = !button.active;
}
}
.html
<mat-sidenav color="primary" #sidenav fxLayout="column" mode="over" opened="false" fxHide.gt-sm="true">
<div fxLayout="column">
<button
mat-button
*ngFor="let button of buttons"
[color]="button.active ? 'accent' : 'primary'"
style="text-align:left"
[routerLink]="button.link"
(click)="toggleColor(button)">
{{ button.title }}
</button>
</div>

Need to add css class for button based on click css value change

Related

How do we use the input:focus selector in angular 2+ component?

I have a form that contains something like the following:
<div class="form-field">
<input-component [tabIndex]="tabData.tabEnable"></input-component>
</div>
<div class="form-field">
<input [tabIndex]="tabData.tabEnable" matInput cgiPrecision type="number"/>
</div>
In the css I have this:
input:focus {
border: $border-width solid $darkblue
}
but the border only shows on the input element and not the input-component component which has an input wrapped inside of it. How can I get the input:focus to work for the custom angular component as well?
Your custom component should listen for the focus event, then focus the input.
#Component({
selector: 'custom-input',
template: `<input #myInput type="text" [(ngModel)]="innerValue">`,
styles: [`
input {border: 5px solid green; }
input:focus { border: 5px solid blue; }
`]
})
export class CustomInputComponent implements ControlValueAccessor {
#ViewChild('myInput', {static: false}) inputCtrl;
//...functions to implement ControlValueAccessor
#HostListener('focus')
focusHandler() {
this.inputCtrl.nativeElement.focus();
}
}
Here's a stackblitz demonstrating.
scss files are limited to their angular component. If you want to use css globally, use the style.scss.
Another option is, integrate the scss into your child component with the style-urls array:
#Component({
selector: 'input-component',
templateUrl: '/input-component.html',
styleUrls: [
'./input-component.scss', // own scss file
'./../path-to-other-compontent.scss' // <--- here
]
})
export class InputComponent {
[...]
}

ngbTooltipConfig tooltipClass not loading custom style tooltip

I am trying to add custom class to ngbTooltip which is working fine on ng-bootstrap official documentation
ngBootstrap Link
I am trying to replicate the same in my code:
tooltip-test.component.html
<div class="row mt-5 ml-5">
<div class="col">
<button type="button" class="btn btn-primary" ngbTooltip="Tool tip on top" placement="top"
tooltipClass="my-custom-class">Tooltip</button>
</div>
</div>
tooltip-test.component.ts
import { Component, OnInit, ViewEncapsulation } from '#angular/core';
import { NgbTooltipConfig } from '#ng-bootstrap/ng-bootstrap';
#Component({
selector: 'app-tooltip-test',
templateUrl: './tooltip-test.component.html',
styleUrls: ['./tooltip-test.component.css'],
providers: [NgbTooltipConfig],
// encapsulation: ViewEncapsulation.None
})
export class TooltipTestComponent implements OnInit {
constructor(tooltipConfig: NgbTooltipConfig) {
tooltipConfig.openDelay = 500;
tooltipConfig.tooltipClass = 'my-custom-class'
}
ngOnInit() {
}
}
tooltip-test.component.css
.my-custom-class .tooltip-inner {
background-color: darkgreen;
font-size: 125%;
}
.my-custom-class .arrow::before {
border-top-color: darkgreen;
}
But I want to achieve same without using encapsulation: ViewEncapsulation.None or ::ng-deep or :host in my code.
tooltipConfig.openDelay = 500; is working fine but
tooltipConfig.tooltipClass = 'my-custom-class' is not loading class.
I even tried tooltipClass="my-custom-class" in HTML.
Can anyone tell me where I am going wrong?
Stackblitz Link where code is not working
All you need is to understand what is view encapsulation in Angular. Here is a good article: https://blog.thoughtram.io/angular/2015/06/29/shadow-dom-strategies-in-angular2.html

PrimeNG confirmation dialog (OverLay) has no build-in style (css)

I added a PrimeNG confirmation dialog (followed the example from the official doc):
component.html
<p-confirmDialog appendTo="body" #cd>
<p-footer>
<button type="button" pButton class="btn btn-primary btn-normal mr-4" label="Print or save" (click)="cd.accept()"></button>
<button type="button" pButton class="btn btn-default btn-normal ml-2" label="Skip" (click)="cd.reject()"></button>
</p-footer>
</p-confirmDialog>
component.ts:
import { ConfirmationService } from 'primeng/api';
#Component({
selector: 'xxx',
templateUrl: './xxx.component.html',
styleUrls: ['./xxx.component.scss'],
providers: [ConfirmationService]
})
constructor(private _confirmationService: ConfirmationService) { }
// I am trying to simplify the code
// this method is called successfully
this._confirmationService.confirm({
message: 'Please print or save the confirmation details before continuing.',
header: 'Confirmation details',
accept: () => {
this.navigatetoPaymentApp();
}
});
angular.json:
"styles": [
"node_modules/primeng/resources/primeng.min.css",
"src/styles/main.scss"
],
app.module.ts:
import {BrowserModule} from '#angular/platform-browser';
import {BrowserAnimationsModule} from '#angular/platform-browser/animations';
#NgModule({
imports: [
BrowserModule,
BrowserAnimationsModule,
//...
],
//...
})
export class AppModule { }
And I got this:
The expected result is like this:
Issues:
1. missing out-of-box styling from primeng (e.g. darken background)
2. missing close window cross icon
Is there anything missing?
Ideas?
Thanks in advance!
Eventually I found the issue. It's because the CSS styles are coming from the prime theme. e.g. add "node_modules/primeng/resources/themes/nova-light/theme.css" to angular.json for the styles list.
So I implemented the following classes with specific properties:
.ui-confirmdialog.ui-dialog {
width: 34em;
background-color: white;
& .ui-dialog-titlebar {
padding: .5em 0.667em;
font-family: xxx;
font-size: 1.3125rem;
font-weight: bold;
color: orange;
}
& .ui-dialog-content {
padding: 1em;
}
}
Additionally, I need to add this to darken the background (I drew some wisdom from the theme.css files from primeNG:
body .ui-widget-overlay {
background-color: #424242;
opacity: 0.7;
filter: alpha(opacity=70);
}
Note: the class ui-widget-overlay is pretty much empty if theme is not applied.

Angular 1.5 component css scoping with nested components

I'm trying to use angular 1.5 components to create a button group.
<button-group size="default">
<my-button>Button 1</my-button>
<my-button>Button 2</my-button>
</button-group>
But, it compiles to something like:
<div class="btn-group" ng-transclude>
<my-button class="ng-scope ng-isolate-scope>
<button class="btn>Button 1</button>
</my-button>
<my-button class="ng-scope ng-isolate-scope>
<button class="btn>Button 1</button>
</my-button>
</div>
So now my CSS scoping is all messed up:
.btn-group > .btn:not(:first-child) {
background: red; //<- doesnt work
}
Basic example:
const buttonGroup = {
bindings: {},
transclude: true,
template: myButtonGroupTemplate
};
You can add classes to your component
Something like that:
html
<button-group size="default">
<my-button class="awesome-class-btn">Button 1</my-button>
<my-button class="awesome-class-btn">Button 2</my-button>
</button-group>
css
.btn-group .awesome-class-btn > .btn:not(:first-child) {
background: red;
}

material angular select dropdown renders totally outside app-root

https://material.angular.io/components/select/overview
the select dropdown renders totally outside app-root.
Basically it creats a div with class="cdk-overlay-container" which is appended as sibling of the app. I want the drop down to open at exactly where I embed <mat-select> tag. What am I missing.
Here is my code
import { Component, Input, Output, OnInit, OnChanges, SimpleChanges, ChangeDetectionStrategy, EventEmitter } from '#angular/core';
import {FormControl} from '#angular/forms';
#Component({
selector: 'my-app',
template: `
<nav class="row navbar navbar-default navbar-fixed-top">
<div class="navbar-container">
<div class="navbar__content">
<mat-form-field>
<mat-select [formControl]="pc" panelClass="example-panel-{{pc.value}}">
<mat-option *ngFor="let panelColor of panelColors" [value]="panelColor.value">
{{ panelColor.viewValue }}
</mat-option>
</mat-select>
</mat-form-field>
</div>
</div>
</nav>
<div class="main-page">
NAVBAR ENDED MAIN PAGE STARTS
</div>
`,
styleUrls: [ './app.component.scss' ],
changeDetection: ChangeDetectionStrategy.Default
})
export class AppComponent {
private pc = new FormControl('red');
private panelColors = [
{value: 'red', viewValue: 'red'},
{value: 'blue', viewValue: 'blue'},
{value: 'green', viewValue: 'green'}
];
}
I created a stackblitz here
That's because you're missing a theme.
Add the following line to the top of your styles.scss or declare a theme (read the guide for more info):
#import '~#angular/material/prebuilt-themes/indigo-pink.css';
This can help you find the right path :
In the app.component.html, add a class to select <mat-form-field> tag :
<mat-form-field class="myForm">
At the bottom of app.component.scss
/*.navbar-default{
height: 120px;
}*/
.myForm {
height: 100px;
}
#cdk-overlay-2 > div {
margin-top: 80px;
}
.page-content {
margin-top: 100px;
}
.main-page{
height: 130px;
}
You have to import #import "~#angular/cdk/overlay-prebuilt.css"; in styles.scss.

Resources