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() {}
}
Related
I have 2 tabs,onclick a tab1 a div will be shown, again on click toggle button the div will expand(100% width) and collapse(25% width) by changing the class. Again when I click on tab2, and then click on tab1 my div should be remain collapse always,I mean its class should be 'old'.Here is the code below.
app.component.html
<span style="cursor:pointer" (click) = "tab1()">Tab1</span> <span (click) = "tab2()" style="cursor:pointer">Tab2</span>
<div [ngClass]="{'old': toggle, 'new': !toggle}" *ngIf="show" class="old">
Hello
</div>
<button (click)="change()">change</button>
app.component.ts
import { Component } from '#angular/core';
#Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
toggle:boolean = true;
show:any;
tab1(){
alert('tab1');
this.show = true;
}
tab2(){
alert('tab2');
this.show = true;
}
change(){
this.toggle = !this.toggle;
}
ngOnInit() {
this.show = false;
}
}
app.component.css
.old{
width:25%;
border:1px solid;
height:200px;
cursor:pointer;
background:yellow;
}
.new{
width:100%;
border:1px solid;
height:200px;
cursor:pointer;
background:green;
}
Try this:
HTML
<div [ngClass]="toggle ? 'old' : 'new'" *ngIf="show">
Hello
</div>
Removed the class="old". Please check now.
stackblitz demo
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'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;
}
import { Component, OnInit, ElementRef, Input, ViewChild, Output, EventEmitter } from '#angular/core';
declare var JQuery: any;
export class PresentationComponent implements OnInit {
constructor( public _eleRef : ElementRef,public CommonComponentService:CommonComponentService ) {
}
ngOnInit() {
jQuery(this._eleRef.nativeElement).find('#Fullscreen').on('click',function(){
jQuery('#exampleImage').width(jQuery(window).width());
jQuery('#exampleImage').height(jQuery(window).height());
});
}
}
.slide-control {
z-index: 5;
background-color: #323232;
overflow: hidden;
border: 0;
padding: 0;
width: 100%;
color: #fff;
font-size: 13px;
max-height: 56px;
min-height: 50px;
///text-align: center;
}
.control {
font-size: 20px;
padding: 10px;
cursor: pointer;
}
.slide-control #fullscreen {
float: right !important;
}
.imageArea {
background-color: #e5e5e5;
border: 1px inset #323232;
}
.resize {
width: 100%;
}
<div class="row imageArea">
<div class="mx-auto">
<img [src]="newUrl" id="exampleImage" class="img-fluid" alt="Responsive image">
</div>
<div class="slide-control form-inline">
<div *ngIf="!buttonShowFlag" class="mx-auto">
<span class="control" (click)="back()"><i class="fa fa-arrow-left" aria-hidden="true"></i></span>
<span>{{count+1}} / {{finalCount}}</span>
<span class="control" (click)="next()"><i class="fa fa-arrow-right" aria-hidden="true"></i></span>
</div>
<div class="mx-auto" *ngIf="buttonShowFlag">
<button (click)="cfuModal.show()" class="btn">{{'Stepper.Next' | translate}}</button>
</div>
<div class="fullscreen float-right">
<span class="control" id="download" *ngIf="download"></i></span>
<span class="control" id="Fullscreen"><i class="fa fa-arrows-alt text-right" aria-hidden="true"></i></span>
</div>
</div>
</div>
hello i am using angular 2. i am design my own image viewer with custom controls. there is one full-screen button available . i want to make my image to be full-screen on click of that button & when i again click on that button it should go to previous state means i want to make my it toggle. i am embedding jquery in angular 2. when i click on that it makes my image full-screen but how can i make it toggle.
This works for me, pls try
In your html,
<div class="row imageArea">
<button (click)="toggleMe()">Toggle Me</button>
<div class="mx-auto">
<img src="http://gkreading.com/wp-content/uploads/2017/03/awesome-kid-in-the-grass.jpg" id="exampleImage" [ngStyle]="{'width':myWidth,'height':myHeight}"class="img-fluid" alt="Responsive image">
</div>
</div>
In your component.ts file,
export class AppComponent {
private contact:Contacts;
private myWidth:any = 100+"px";
private myHeight:any = 100+"px";
private toggled:boolean = false;
private toggleMe(){
if(this.toggled == false ){
this.myWidth = (window.screen.width) + "px";
this.myHeight = (window.screen.height) + "px";
}else{
this.myWidth = 100 + "px";
this.myHeight = 100 + "px";
}
this.toggled = !this.toggled;
}
}
For getting the screen height and width, you dont want to use any jquery code. Hope this helps.
Instead of jQuery you could bind the height and width of the image with [style.height] and [style.width] as the example:
<img [src]="newUrl" [style.width]="imageWidth" [style.height]="imageHeight" id="exampleImage" class="img-fluid" alt="Responsive image">
and in the button event toggle the size of the image:
btnEventToggle(){
this.flagFullScreen = !this.flagFullScreen;
if(this.flagFullScreen)
{
this.imageHeight = (window.screen.height); //or $window.innerHeight
this.imageWidth = (window.screen.width);
}
else{
this.imageHeight = originalHeight;
this.imageWidth = originalWidth;
}
}
Another option is to bind the element to the angular and treat the element entirely:
<img [src]="newUrl" #imgToggled id="exampleImage" class="img-fluid" alt="Responsive image">
and send the element in the click event: (click)="btnEventToggle(imgToggled)", but it is not advised.
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;
}
}