material angular select dropdown renders totally outside app-root - css

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.

Related

How to change button colour on click?

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

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

How to add horizontal scroll to mat autocomplete

I am running angular app , I have auto complete on this, I want to add horizontal scroll to the mat-option, I tried applying css style
.cdk-overlay-pane {
overflow-x: auto;
}
then applying syle as told in this docuemnt [enter link description here][1] showPanel: boolean
<mat-option class="CustomerDropDown" showPanel="true" ...
extended question
<mat-form-field >
<input matInput [matAutocomplete]="auto" [formControl]="customerFilterControl">
<mat-autocomplete panelWidth ="450px" #auto="matAutocomplete" [displayWith] = "displayFn" style="width:750px;">
<mat-option *ngFor="let customer of filteredOptions | async" [value] ="customer.AccountID + '('+ customer.AccountName + ')'" (click)="onCustomerChange(customer)">
{{customer.AccountID}} ({{customer.AccountName}})
</mat-option>
</mat-autocomplete>
</mat-form-field>
Both the attempts failed!!
Try the following CSS. It worked for me.
::ng-deep .custom-mat-option .mat-option-text {
overflow: auto;
text-overflow: unset;
// color: green;
}
custom-mat-option is a class I have added to the <mat-option> element to increase the css specifity.
Stackblitz
HTML
<cdk-virtual-scroll-viewport itemSize="50" class="example-viewport">
<div *cdkVirtualFor="let item of items" class="example-item">{{item}}</div>
</cdk-virtual-scroll-viewport>
TS File
import {ChangeDetectionStrategy, Component} from '#angular/core';
/** #title Basic virtual scroll */
#Component({
selector: 'cdk-virtual-scroll-overview-example',
styleUrls: ['cdk-virtual-scroll-overview-example.css'],
templateUrl: 'cdk-virtual-scroll-overview-example.html',
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class CdkVirtualScrollOverviewExample {
items = Array.from({length: 100000}).map((_, i) => `Item #${i}`);
}
CSS
.example-viewport {
height: 200px;
width: 200px;
border: 1px solid black;
}
.example-item {
height: 50px;
}
and also follow this link
scrolling

Dynamic styling not working in Angular2

Following is my working code, which is not giving any error in console and printing the array items and test heading as expected. BUT somehow dynamic background styling in not working, Let me know what I am doing wrong here.
import { Component } from '#angular/core';
#Component({
selector: 'my-app',
template: `
<h1>{{name}}</h1>
<div class="one" *ngFor="let item of colArr" style="background: {{item}};">{{item}}</div>
`,
styles: [`
.one {
width: 100%;
text-align: center;
padding: 10px;
margin: 5px;
}
`]
})
export class HomeComponent {
public name = 'test';
public colArr = ['#111111', '#222222', '#333333', '#444444', '#555555', '#666666', '#777777', '#888888', '#999999'];
}
Following is the output I am getting -
Direct binding to style is discouraged (doesn't work well on all browsers). Use instead
<div class="one" *ngFor="let item of colArr" [ngStyle]="{background: item}">{{item}}</div>
or
<div class="one" *ngFor="let item of colArr" [style.background]="item">{{item}}</div>

Resources