I'm using the latest version of Angular and Angular Material. I'm having issues with my components. The page Load like this:
Before de click
And the content just appear when I click on the menu.
After clicking
I already tried to uninstall and install all the meterial stuff. And this issue continues. I have a separate module to import and export all the material components. Here is the code of the component that is using the material tags:
profile.component.ts
import { Component, OnInit } from '#angular/core';
import {AuthService} from "../../services/auth.service";
import {User} from "../../model/model.user";
import {Router} from "#angular/router";
import { Expense } from '../../model/model.expense';
import { ReceiptService } from "../../services/receipt.service";
import { ExpenseService } from './../../services/expense.service';
import { Receipt } from './../../model/model.receipt';
#Component({
selector: 'app-profile',
templateUrl: './profile.component.html',
styleUrls: ['./profile.component.css']
})
export class ProfileComponent implements OnInit {
totalReceita = 0;
totalDespesa = 0;
receipts = []
expenses = []
currentUser: User;
constructor(public authService: AuthService, public router: Router, public receiptService: ReceiptService, public expenseService: ExpenseService) {
this.currentUser = JSON.parse(localStorage.getItem('currentUser'));
}
ngOnInit() {
this.receiptService.getReceipts(this.currentUser.id).subscribe(
data => {
console.log(data)
this.receipts = this.retiraArrayRec(data);
this.somaTudoRec();
}
);
this.expenseService.getExpenses(this.currentUser.id).subscribe(
data => {
this.expenses =this.retiraArrayDesp(data);
this.somaTudoDes();
}
);
console.log(this.receipts)
}
retiraArrayRec(data){
let lista = []
data.forEach(element => {
let receita : Receipt = new Receipt;
receita.name = element[0];
receita.value = element[1]
lista.push(receita);
});
return lista;
}
retiraArrayDesp(data){
let lista = []
data.forEach(element => {
let despesa : Expense = new Expense;
despesa.name = element[0];
despesa.value = element[1]
lista.push(despesa);
});
return lista;
}
somaTudoRec(){
this.receipts.forEach(element => {
this.totalReceita += element.value;
});
}
somaTudoDes(){
this.expenses.forEach(element => {
this.totalDespesa += element.value;
});
}
// login out from the app
logOut() {
this.authService.logOut()
.subscribe(
data => {
this.router.navigate(['/login']);
},
error => {
});
}
}
profile.component.html
<mat-sidenav-container fullscreen class="menu-container">
<mat-sidenav #sidenav>
<mat-nav-list>
<a mat-list-item routerLink="/home" routerLinkActive="active-list-item">
<h2 matLine>Home</h2>
<mat-icon matListIcon>home</mat-icon>
</a>
<a mat-list-item routerLink="/account" routerLinkActive="active-list-item">
<h2 matLine>Receitas</h2>
<mat-icon matListIcon>local_atm</mat-icon>
</a>
<a mat-list-item routerLink="/settings" routerLinkActive="active-list-item">
<h2 matLine>Despesas</h2>
<mat-icon matListIcon>show_chart</mat-icon>
</a>
<a mat-list-item routerLink="/settings" routerLinkActive="active-list-item">
<h2 matLine>Notificações</h2>
<mat-icon matListIcon>notification_important</mat-icon>
</a>
</mat-nav-list>
</mat-sidenav>
<mat-sidenav-content fxFlexFill>
<mat-toolbar>
<button class="hamburger mat-button" mat-icon-button (click)="sidenav.toggle()">
<mat-icon>menu</mat-icon>
<span>Menu</span>
</button>
<span>Bem vindo ao CPF, Pedro</span>
<button mat-icon-button [mat-menu-trigger-for]="menu">
<mat-icon>more_vert</mat-icon>
</button>
</mat-toolbar>
<mat-menu x-position="before" #menu="matMenu">
<button mat-menu-item>
<mat-icon>person</mat-icon>
<span>Perfil</span>
</button>
<button mat-menu-item>
<mat-icon>money_off</mat-icon>
<span>Sair</span>
</button>
</mat-menu>
</mat-sidenav-content>
</mat-sidenav-container>
profile.component.css
mat-toolbar {
background-image: linear-gradient(to bottom, #00b4db, #0083b0);
color: #fff;
justify-content: space-between;
box-shadow: 0 2px 5px 0 rgba(0,0,0,.3);
}
span {
font-size: 16px;
font-weight: 700;
}
.hamburger {
height: 100%;
font-size: 18px;
}
.mat-sidenav-container {
min-width: 400px;
max-width: 100%;
}
.mat-sidenav {
flex: 0 1 auto;
}
.menu-spacer {
flex: 1;
}
.mat-list-item-content {
padding: 0 25px;
}
.menu-container {
min-width: 200px;
max-width: 100%;
}
First, please consider that you need to insert style into the project:
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
If it did not solve the problem, I guess it's because you are using another font and also added !important for the font, please try to add the code below in your style.css (or style.scss) which is the general/public CSS file which effects on your whole project:
mat-icon{
font-family: 'Material Icons' !important;
}
Related
There is a product page where product list component and action buttons are there. This is the parent component. That product list component consists of list table and edit/add modal. Now, problem is Add action event is in parent component. But, add modal related data is available in child component.
So, how can i open that model based on click event from parent? Here i am doing like this approach.
Parent Component(Product Component snippets )
<template>
..... other code ....
<div class="action-buttons">
<vu-button class="add-action" #click="onAddAction">
<svg-icon
fill="#0071E3"
name="add"
height="20"
width="28"
/>
</vu-button>
</div>
<ChildComponent :open-add-modal="isAddModal" />
</template>
Methods in Parent component
onAddAction() {
this.editable = false;
this.isAddModal = true;
},
Now, in child component i passing boolean props openAddModal but i am checking condition into created hook to show Add modal.
Problem is in initial rendering or page load add modal is showing up not in click event. How can i solve this issue?
Child component(Created hook)
created() {
if(this.openAddModal) {
this.showModal = true;
this.formType = 'add';
this.editId = null;
}
},
I want to show add modal based on click event from parent not in initial page load.
You can try using a watcher instead of checking the value of open-add-modal in the created hook. This way, when the prop open-add-modal in the child component changes, you can check the new value there and emit the needed data to the parent to then open the modal.
Example:
Parent component code
<template>
<div>
<p>Parent component</p>
<button #click="changeOpenAddModal">Clic to get child data</button>
<button #click="resetParent">Reset data in parent</button>
<p>Data from child: {{ childData }}</p>
<br />
<br />
<Child
:openAddModal="this.openAddModal"
#child-component-data-emit="this.setChildData"
/>
</div>
</template>
<script>
import Child from "./Child";
export default {
name: "Parent",
components: { Child },
data() {
return {
childData: null,
openAddModal: false,
};
},
methods: {
changeOpenAddModal() {
this.openAddModal = !this.openAddModal;
console.log(
"changing openAddModal data. New value is ",
this.openAddModal
);
},
setChildData(data) {
console.log("setting child data", data);
this.childData = data;
},
resetParent() {
this.childData = null;
this.changeOpenAddModal();
},
},
};
</script>
Child component code
<template>
<div>
<p>Child component</p>
</div>
</template>
<script>
export default {
name: "Child",
props: {
openAddModal: {
type: Boolean,
default: false,
},
},
data() {
return {
childData: {
prop1: "lorem",
prop2: "ipsum",
prop3: "dolor",
},
};
},
watch: {
openAddModal: function (newValue, oldValue) {
console.log("child watcher with newValue", newValue);
if (newValue) {
this.$emit("child-component-data-emit", this.childData);
}
},
},
mounted: function () {
console.log("prop openAddModal value on mounted:", this.openAddModal);
},
};
</script>
I have built a few modals with Vue 2 and Vue CLI, and use an alternate approach for showing, hiding, and determined if add or edit mode. No watch or separate add/edit mode boolean is necessary.
The 'product' processing is somewhat contrived since no database or AJAX are used in this example, but you should get be able to evaluate the functionality.
Parent.vue
<template>
<div class="parent">
<h4>Parent of Form Modal</h4>
<div class="row">
<div class="col-md-6">
<button class="btn btn-secondary" #click="showAddModal">Show Add Modal</button>
<button class="btn btn-secondary btn-edit" #click="showEditModal">Show Edit Modal</button>
</div>
</div>
<form-modal v-if="displayModal"
:parentProduct="product"
#save-product-event="saveProduct"
#close-modal-event="hideModal"
/>
</div>
</template>
<script>
import FormModal from './FormModal.vue'
export default {
components: {
FormModal
},
data() {
return {
product: {
id: 0,
name: '',
description: ''
},
displayModal: false
}
},
methods: {
showAddModal() {
this.resetProduct();
this.displayModal = true;
},
showEditModal() {
this.product.id = 1;
this.product.name = 'productEdit';
this.product.description = 'productEditDescription';
this.displayModal = true;
},
hideModal() {
this.displayModal = false;
},
saveProduct(modalProduct) {
this.product = modalProduct;
this.hideModal();
console.log(this.product);
},
resetProduct() {
this.product.id = 0;
this.product.name = '';
this.product.description = '';
}
}
}
</script>
<style scoped>
.btn-edit {
margin-left: 0.5rem;
}
</style>
FormModal.vue
<template>
<!-- The Modal -->
<div id="form-modal" class="modal-dialog-container">
<div class="modal-dialog-content">
<div class="modal-dialog-header">
<h4>{{ modalTitle }}</h4>
</div>
<div class="modal-dialog-body">
<form #submit.prevent="saveProduct">
<div class="form-group">
<label for="product-name">Name</label>
<input type="text" class="form-control" id="product-name" v-model="product.name">
</div>
<div class="form-group">
<label for="product-description">Description</label>
<input type="text" class="form-control" id="product-description" v-model="product.description">
</div>
<button type="submit" class="btn btn-primary">Submit</button>
<button type="button" class="btn btn-secondary btn-close" #click="closeModal">Cancel</button>
</form>
</div>
</div>
</div>
</template>
<script>
export default {
props: {
parentProduct: {
type: Object,
required: true
}
},
data() {
return {
product: this.parentProduct
}
},
computed: {
modalTitle() {
return this.product.id === 0 ? 'Add Product' : 'Edit Product';
}
},
methods: {
closeModal() {
this.$emit('close-modal-event');
},
saveProduct() {
// Add product
if (this.product.id === 0) {
this.product.id = 2;
}
this.$emit('save-product-event', this.product);
}
}
}
</script>
<style scoped>
.modal-dialog-container {
/* display: none; Hidden by default */
position: fixed;
/* Stay in place */
z-index: 1;
/* Sit on top */
left: 0;
top: 0;
width: 100%;
/* Full width */
height: 100%;
/* Full height */
overflow: auto;
/* Enable scroll if needed */
background-color: rgb(0, 0, 0);
/* Fallback color */
background-color: rgba(0, 0, 0, 0.4);
/* Black w/ opacity */
}
.modal-dialog-content {
background-color: #fefefe;
margin: 10% auto;
padding: 20px;
border: 1px solid #888;
border-radius: 0.3rem;
width: 30%;
}
.btn-close {
margin-left: 0.5rem;
}
</style>
I have the following element:
import {LitElement, html} from '#polymer/lit-element';
import {SdkArticle} from '../elements/sdk-article/sdk-article.js'
class PraksisView extends LitElement {
static get properties() {
return {
articles: {type: Array},
};
}
constructor() {
super();
this.articles = [];
}
async firstUpdated() {
await fetch(`/testData.json`)
.then(r => r.json())
.then(async data => {
this.articles = data.articles;
});
}
render() {
return html `
<style>
.indent-1 {float: left;}
.indent-1 section {width: 50%; float: left;}
header {
display: block;
height: 50px;
background-color: #215959;
color: white;
}
.center {
margin: auto;
padding-top: 10px;
padding-bottom: 10px;
padding-left: 50px;
}
</style>
<header>
<h3 class="center">Almen praksis</h3>
</header>
<section class="indent-1">
<section>
<div>
<ul>
<li>Patientbehandling</li>
<li>Klinikdrift</li>
<li>Midtkraft</li>
</ul>
</div>
</section>
<section>
${this.articles.map(
article =>
html`
<div>
<sdk-article data=${article}></sdk-article>
</div>
`,
)}
</section>
</section>
`;
}
}
customElements.define('praksis-view', PraksisView);
As you can see here I load some test data in from testData.json.
Now the other sdk-article:
import {LitElement, html} from '#polymer/lit-element';
class SdkArticle extends LitElement {
static get properties() {
return {
data: {type: Object}
};
}
constructor() {
super();
this.data = {};
}
render() {
this.generateHtml();
return html`
`;
}
generateHtml(){
console.log(this.data);
}
}
customElements.define('sdk-article', SdkArticle);
Basically this just checks if the data is there.
When I run this the data is undefined and I get an error:
VM1588:1 Uncaught SyntaxError: Unexpected token o in JSON at position 1
at JSON.parse (<anonymous>)
at fromAttribute (updating-element.js:59)
at Function._propertyValueFromAttribute (updating-element.js:259)
at HTMLElement._attributeToProperty (updating-element.js:387)
at HTMLElement.attributeChangedCallback (updating-element.js:343)
at AttributeCommitter.commit (parts.js:79)
at AttributePart.commit (parts.js:111)
at TemplateInstance.update (template-instance.js:40)
at NodePart.__commitTemplateResult (parts.js:248)
at NodePart.commit (parts.js:189)
Can anyone see what the issue is here?
Solution
if you want to pass the actual property on then you need to use the "dot notation".
<sdk-article .data=${article}></sdk-article>
this is basically the same as doing
document.querySelector('sdk-article').data = article;
Explanation of issue
In your current code you are setting an attribute.
<sdk-article data=${article}></sdk-article>
which is basically this
document.querySelector('sdk-article').setAttribute('data', article);
Attributes however only accept strings.
I have a spinner , but I also want some text in the spinner independent of the component. So for example if you are doing a save action, then the spinner will showing: ...saving. But for example if you do a search action. The spinner will showing: ..processing and so on.
I have this as spinner component:
<div *ngIf="(isLoading | async)" class="overlay">
<div>
<mat-progress-spinner class="spinner" [color]="color" [mode]="mode" [value]="value"> </mat-progress-spinner>
<div style="position:relative; top: -60px; left: 30px;">{{message}}</div>
</div>
</div>
and ts script:
export class LoaderComponent {
color = 'primary';
mode = 'indeterminate';
value = 50;
message = 'Hello there';
isLoading: Subject<boolean> = this.loaderService.loaderState;
constructor(private loaderService: LoaderService) {}
}
and then for example I load the spinner in this component: listComponent
<app-loader ></app-loader>
So I see the spinner but not the message.
So what I have to improve so that the text will also been shown?
And how to make the text dynamically? So that you can put any text message in it?
Thank you
I have it now like this:
<div *ngIf="(isLoading | async)" class="overlay">
<div>
<mat-progress-spinner class="spinner" [color]="color" [mode]="mode" [value]="value"> </mat-progress-spinner>
<div style="position:absolute; top: -60px; left: 30px;">{{message}}</div>
</div>
</div>
export class LoaderComponent {
color = 'primary';
mode = 'indeterminate';
value = 50;
#Input()
message = 'Hello there';
isLoading: Subject<boolean> = this.loaderService.loaderState;
constructor(private loaderService: LoaderService) {}
}
and this is the css:
.overlay {
position:fixed;
display:block;
width:100%;
height:100%;
top:0;
left:0;
background-color:rgba(74,74,74,.8);
z-index:99999;
}
.spinner {
margin:auto;
position:absolute;
top:50%;
left:50%;
transform: translate(-50%,-50%);
}
You can find Working demo here in this StackBlitz Link
You have to use Behavior Subject and service...
Your app.component.html is..
<mat-toolbar color="primary">Spinner Demo</mat-toolbar>
<div style="margin:1em">
<button style="margin:1rem" mat-raised-button color="primary" (click)="spinner('search')">Search</button>
<button mat-raised-button color="primary" (click)="spinner('Send')">Send</button>
<button style="margin:1rem" mat-raised-button color="primary" (click)="spinner('Save')">Save</button>
</div>
<app-search-output ></app-search-output>
Your app.component.ts is...
export class AppComponent {
constructor( private serachService: SearchService){
}
spinner(term){
this.serachService.sendData(term);
}
ngOnInit(){
}
}
Your Service where you can use behaviorSubject as like this...
export class SearchService {
searchData$: BehaviorSubject<object[]> = new BehaviorSubject<object[]>([{}]);
constructor() { }
sendData(term){
this.searchData$.next(term)
}
getData(){
return this.searchData$.asObservable();
}
}
Your spinner component HTML is...
<div style="margin:2em auto; padding:1rem; box-shadow: 1px 2px 7px red; width:50vw">
<span style="margin:1em; padding:1rem">{{bookData$ |async |json}}</span>
<mat-spinner style="margin:1em" color="warn" ></mat-spinner>
</div>
Your spinner.component.ts is ...
export class SearchOutputComponent implements OnInit {
bookData$;
constructor(private searchService: SearchService) { }
ngOnInit() {
this.bookData$ = this.searchService.getData();
}
}
You can pass text values as #Input to your component and use the component as below
I believe you are not able to see it because of css issue. Try making the text position:absolute.
<div *ngIf="(isLoading | async)" class="overlay">
<div>
<mat-progress-spinner class="spinner" [color]="color" [mode]="mode" [value]="value"> </mat-progress-spinner>
<div style="position:absolute; top: -60px; left: 30px;">{{message}}</div>
</div>
</div>
To further debug please create a stackblitz.
<app-loader [message] = "Processing"></app-loader>
Spinner Component
import { Component, Input, OnInit } from '#angular/core';
export class LoaderComponent {
color = 'primary';
mode = 'indeterminate';
value = 50;
#Input()
message = 'Hello there'; // Default text will be Hello there but if you pass anything as stated above then it will be replaced.
isLoading: Subject<boolean> = this.loaderService.loaderState;
constructor(private loaderService: LoaderService) {}
}
Try to change style position to relative in your html file it should work:
HTML file
<div *ngIf="(isLoading | async)" class="overlay">
<div>
<mat-progress-spinner class="spinner" [color]="color" [mode]="mode" [value]="value"> </mat-progress-spinner>
<div style="position:relative; top: -60px; left: 30px;">{{message}}
</div>
</div>
</div>
TS file
export class ProgressSpinnerOverviewExample {
color = 'primary';
mode = 'indeterminate';
value = 50;
#Input()
message = 'Hello';
isLoading = true;
constructor() {}
}
I want to scroll to a particular div on clicking a button in Angular 7, below is the code I am using but it is working in stackblitz but showing error when i use in my project.
"Cannot read property 'scrollIntoView' of undefined".
https://stackblitz.com/edit/angular-scroll-local-variable?file=src%2Fapp%2Fscroll.component.ts
try this link: https://stackblitz.com/edit/angular-scroll-local-variable-ja96uz?file=src%2Fapp%2Fapp.component.html
<button (click)="scroll(target)"></button>
<div #target>Your target</div>
and in component:
scroll(el) {
el.scrollIntoView();
}
Try angular ViewportScroller Service Which provide scrollToAnchor method
scroll.html
<button (click)="scroll('target')">Click to scroll</button>
<div id="target">Your target</div>
scroll.ts
import { Component, Input } from '#angular/core';
import { ViewportScroller } from '#angular/common';
#Component({
selector: 'scroll',
template: `
<button (click)="scroll('target')">Click to scroll</button>
<div id="target">Your target</div>
`,
styles: [`h1 { font-family: Lato; }`, `div { margin-top: 5000px; }`]
})
export class ScrollComponent {
constructor(private vps: ViewportScroller) {
}
scroll(id) {
this.vps.scrollToAnchor(id);
}
}
Example:https://stackblitz.com/edit/angular-scroll-local-variable-99hwvo
Try using ViewChild:
//HTML
<button (click)="scroll()"></button><div #target>Your target</div>
//ts
//Import
import { ..., ViewChild, ElementRef } from '#angular/core';
//Declare
#ViewChild('target') targetEl: ElementRef;
scroll() {
this.targetEl.nativeElement.scrollIntoView();
}
Scroll.html
<button (click)="scroll()">Click to scroll</button>
<div id="target">Your target</div>
componet.ts
getOffset(el) {
el = el.getBoundingClientRect();
return {
left: el.left + window.scrollX,
top: el.top + window.scrollY,
bottom: el.top + window.scrollY
}
}
scroll() {
var scroll_to = document.getElementById('target');
var topHight = this.getOffset(scroll_to).top;
window.scrollTo(0, topHight);
}
The code is not working because of *ngIf condition, when you use show variable is default set to false, hence the div is not rendered on the component.
The code should be used in a related component where you want to scroll to be done, for example:
if you required in the scroll component then
HTML:
<button (click)="scroll(target)">clicking this button</button>
<div style="marging-top: 100px; height: 900px;"></div>
<div #target *ngIf="show" style="border: 1px solid #000; padding: 10px;margin-top: 10px;">
show get screen scrolled to this div
</div>
TS:
scroll(el: HTMLElement) {
if(el){ // If the div is rendered on the HTML then it should be HTML element
el.scrollIntoView();
}
}
StackBlitz
I have a div on my ionic 2 page and I want to display and hide it when click , the first part is done (display) I use ngClass to do it but the second part can't do it I think is a logic problem , see the image bellow :
, here is the html code :
<ion-content>
<ion-fab right [ngClass]="isCalendar ? 'show-calendar':'hide-calendar' " (click)="showCalendar();">
<div class="close" (click)="hideCalendar()" [ngClass]="isNotCalendar ? 'hide-Calendar' :'show-calendar'">
<ion-icon class="icon-close" name="ios-close"></ion-icon>
</div>
<p class="day" [ngClass]="isClicked ? 'day-no-click':'day' ">DAY</p>
<p class="month" [ngClass]="isClicked ? 'monthclicked':'month' " (click)="selectMonth()">MONTH</p>
<p class="year">YEAR</p>
<div class="button-date" ion-button round>
<p>. . .</p>
</div>
<div class="Progress" style="transform: rotate(90deg);">
<progress max="100" value="0" class="Progress-main">
<div class="Progress-bar" role="presentation">
<span class="Progress-value" style="width: 80%;"></span>
</div>
</progress>
</div>
</ion-fab>
<ion-fab top left>
<ion-searchbar> </ion-searchbar>
</ion-fab>
<ion-img class="map" [src]="mapsource" (click)="changeView(mapsource)"></ion-img>
<ion-icon class="icon-bonfire" name="ios-bonfire"></ion-icon>
<ion-icon class="icon-heart" name="md-heart"></ion-icon>
<ion-icon class="icon-nuclear" name="md-nuclear"></ion-icon>
<ion-fab top right (click)="showCalendar()">
<button ion-fab color="whitecolor"><ion-icon class="calandaricon" name="md-calendar"></ion-icon></button>
</ion-fab>
<div class="calendar">
</div>
<ion-fab bottom right class="fablocate">
<button ion-fab color="whitecolor"><ion-icon class="locateicon" name="md-locate"></ion-icon></button>
</ion-fab>
<ion-fab (click)="ListParrots();" bottom left class="linklist">
<ion-img class="parrot-list-link" src="img/citydirty.jpg"></ion-img>
</ion-fab>
</ion-content>
and here is the ts file code :
import { Component } from '#angular/core';
import { IonicPage, NavController, NavParams } from 'ionic-angular';
import {ParrotListPage } from '../parrot-list/parrot-list';
/**
* Generated class for the MapPage page.
*
* See https://ionicframework.com/docs/components/#navigation for more info on
* Ionic pages and navigation.
*/
#IonicPage()
#Component({
selector: 'page-map',
templateUrl: 'map.html',
})
export class MapPage {
mapsource :any;
isClicked : Boolean= false;
isCalendar : Boolean=false;
isNotCalendar : Boolean=false;
constructor(public navCtrl: NavController, public navParams: NavParams) {
this.mapsource = '../../img/map.jpg';
}
changeView(mapsource){
this.mapsource ='../../img/mapzoom.jpg';
if (mapsource == this.mapsource) {
this.mapsource = '../../img/map.jpg';
}else{
this.mapsource= '../../img/mapzoom.jpg';
}
}
ionViewDidLoad() {
console.log('ionViewDidLoad MapPage');
}
ListParrots(){
this.navCtrl.push(ParrotListPage);
}
showCalendar(){
this.isCalendar = true;
}
hideCalendar(){
this.isNotCalendar = false;
}
selectMonth() {
this.isClicked = true;
}
}
and here is the css
.show-calendar {
height: 100%;
width: 25%;
background-color: color($colors, notification-blue);
margin-right: -10px;
z-index: 1000;
text-align: center;
}
.hide-calendar {
display: none;
}
.close {
width: 50px;
height: 50px;
text-align: center;
background-color: white;
border-radius: 50%;
line-height: 50px;
margin-top: 20px;
margin-left: auto;
margin-right: auto;
}
can some check with the logic and tell how to define exactly the ngClass functionalities?
Try like this :
<button class="btn btn-primary" (click)="showCalendar()">showCalendar</button>
<div [ngClass]="isCalendar ? 'show-calendar':'hide-calendar'">
<h1>Calendar Content</h1>
</div>
and method :
export class Component {
private isCalendar: boolean = false;
showCalendar() {
this.isCalendar = this.isCalendar ? false : true;
}
}