How is it possible to achieve block ui(http://malsup.com/jquery/block/#demos) kind of blocking user interaction in angular 2 ? Could someone please help.
spinner.ts
import {Component} from 'angular2/core';
@Component({
selector: 'spinner',
styleUrls: ['spinner.css'],
//I'm using in modal-backdrop classes from bootstrap
template:
`<div class="in modal-backdrop spinner-overlay"></div>
<div class="spinner-message-container" aria-live="assertive" aria-atomic="true">
<div class="spinner-message" [ngClass]="spinnerMessageClass">{{ state.message }}</div>
</div>`
})
export class SpinnerComponent {
state = {
message: 'Please wait...'
};
}
spinner.css
.spinner-overlay {
background-color: white;
cursor: wait;
}
.spinner-message-container {
position: absolute;
top: 35%;
left: 0;
right: 0;
height: 0;
text-align: center;
z-index: 10001;
cursor: wait;
}
.spinner-message {
display: inline-block;
text-align: left;
background-color: #333;
color: #f5f5f5;
padding: 20px;
border-radius: 4px;
font-size: 20px;
font-weight: bold;
filter: alpha(opacity=100);
}
spinner.service.ts
import {Injectable, DynamicComponentLoader, ApplicationRef, ElementRef, ComponentRef} from 'angular2/core';
import {SpinnerComponent} from './spinner.component';
@Injectable()
export class SpinnerService {
spinnerComp: ComponentRef;
constructor(private componentLoader: DynamicComponentLoader, private appRef: ApplicationRef) { }
public start() {
let elementRef: ElementRef = this.appRef['_rootComponents'][0].location;
return this.startInside(elementRef, null);
}
public startInside(elementRef: ElementRef, anchorName: string) {
let spinnerRef = (!anchorName) ?
this.componentLoader.loadNextToLocation(SpinnerComponent, elementRef) :
this.componentLoader.loadIntoLocation(SpinnerComponent, elementRef, anchorName);
spinnerRef.then((compRef:ComponentRef) => {
this.spinnerComp = compRef;
});
}
public stop() {
if (this.spinnerComp) {
this.spinnerComp.dispose();
}
}
}
Inject spinner service to your component. call start and stop to display and hide.
update: demo plnkr link: http://plnkr.co/edit/Y2ocRpbi2ORjbULrguDg
disclaimer: I have used one existing angular2 library as reference to create above code in my project. I'm searching for that library and will update the same here when I find it.
Angular 2 blockui with spinner (can be customized as per your needs)
Please find below code which works perfectly with angular 2
spinner.component.ts
import {Component, Input, OnDestroy} from '@angular/core';
@Component({
selector: 'my-spinner',
//templateUrl: 'app/components/spinner/spinner.html'
template: `
<div [hidden]="!isDelayedRunning" class="spinnercontainer">
<div class="spinner">
<div class="double-bounce1"></div>
<div class="double-bounce2"></div>
</div>
</div>
`,
styleUrls:['app/spinner.component.css']
})
export class SpinnerComponent implements OnDestroy {
private currentTimeout: any;
private isDelayedRunning: boolean = false;
@Input()
public delay: number = 300;
@Input()
public set isRunning(value: boolean) {
if (!value) {
this.cancelTimeout();
this.isDelayedRunning = false;
}
if (this.currentTimeout) {
return;
}
this.currentTimeout = setTimeout(() => {
this.isDelayedRunning = value;
this.cancelTimeout();
}, this.delay);
}
private cancelTimeout(): void {
clearTimeout(this.currentTimeout);
this.currentTimeout = undefined;
}
ngOnDestroy(): any {
this.cancelTimeout();
}
}
spinner.component.css
.spinnercontainer{
background-color: transparant;
height: 100vh;
width: 100%;
z-index: 20000;
position: fixed;
top: 0;
left: 0;
background-color: #000;
opacity: 0.5;
transition: all 0.5s ease;
display:block;
z-index: 20001;
}
.spinner {
width: 40px;
height: 40px;
position: relative;
margin: 100px auto;
}
.double-bounce1, .double-bounce2 {
width: 100%;
height: 100%;
border-radius: 50%;
background-color: #333;
opacity: 0.6;
position: absolute;
top: 0;
left: 0;
-webkit-animation: sk-bounce 2.0s infinite ease-in-out;
animation: sk-bounce 2.0s infinite ease-in-out;
}
.double-bounce2 {
-webkit-animation-delay: -1.0s;
animation-delay: -1.0s;
}
@-webkit-keyframes sk-bounce {
0%, 100% { -webkit-transform: scale(0.0) }
50% { -webkit-transform: scale(1.0) }
}
@keyframes sk-bounce {
0%, 100% {
transform: scale(0.0);
-webkit-transform: scale(0.0);
} 50% {
transform: scale(1.0);
-webkit-transform: scale(1.0);
}
}
How to use: Use above component in other component(which uses async task) as shown below
sample-view.component.ts
import {Component} from '@angular/core';
import {SpinnerComponent} from './spinner.component';
import {ApiService} from './apiService';
@Component({
selector: 'my-sample-view',
directives: [SpinnerComponent],
template: '<my-spinner [isRunning]="isRequesting"></my-spinner>',
})
export class SampleViewComponent {
public isRequesting: boolean;
public items: Array<any>;
constructor(private apiService: ApiService) {
this.refresh();
}
public refresh(): void {
this.isRequesting = true;
this.apiService.sampleHttpGetRequest()
.subscribe(
result => this.items = result,
() => this.stopRefreshing(),
() => this.stopRefreshing());
}
private stopRefreshing() {
this.isRequesting = false;
}
}
Thanks to https://manuel-rauber.com/2016/01/05/angular-2-spinner-component/
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With