I'm developing a web site using Angular 2. Is there any way to disable or trigger Browser back button using Angular 2?
Thanks
I'm developing a web site using Angular 2. Is there any way to disable or trigger Browser back button using Angular 2?
Thanks
Not sure if this is already sorted, but posting the answer nonetheless, for future references. To tackle this, you basically need to add a listener in your app-component and setup a canDeactivate guard on your angular-router.
// in app.component.ts
import { LocationStrategy } from '@angular/common';
@Component({
selector: 'app-root'
})
export class AppComponent {
constructor(
private location: LocationStrategy
) {
// check if back or forward button is pressed.
this.location.onPopState(() => {
// set isBackButtonClicked to true.
this.someNavigationService.setBackClicked(true);
return false;
});
}
}
// in navigation guard
@Injectable()
export class NavigationGuard implements CanDeactivate<any> {
constructor(private someNavigationService: SomeNavigationService) {}
canDeactivate(component: any) {
// will prevent user from going back
if (this.someNavigationService.getBackClicked()) {
this.someNavigationService.setBackClicked(false);
// push current state again to prevent further attempts.
history.pushState(null, null, location.href);
return false;
}
return true;
}
}
This isn't Angular2 related problem. You can send the user back in history. See Manipulating the browser history, history.go()
method particular:
window.history.go(-1);
However, I don't think there's a way to cancel or disable default browser action on pressing back button in the browser window because that could be very easily abused.
As an alternative you can show a dialog window when user tries to leave the page: javascript before leaving the page
Try this
<script type = "text/javascript" >
history.pushState(null, null, 'pagename');
window.addEventListener('popstate', function(event) {
history.pushState(null, null, 'pagename');
});
</script>
where change 'pagename' to your page name and put this into head section of page.
If you want to prevent a route to be reached you can add the @CanActivate() decorator to your routing component
@Component({selector: 'control-panel-cmp', template: `<div>Settings: ...</div>`})
@CanActivate(checkIfWeHavePermission)
class ControlPanelCmp {
}
See also
- Angular 2: Inject a dependency into @CanActivate? for access to global services.
- Angular2 Router - Anyone know how to use canActivate in app.ts so that I can redirect to home page if not logged in
A bit late perhaps but maybe somebody can use it. This is a solution I use for a page with tabs (Bootstrap 4 style) where each tab is a component.
@Injectable()
export class CanNavigateService {
private static _isPermissionGranted = true
public navigationAttempt = new Subject<boolean>()
//-------------------------------------------------------------//
/**Will the next navigation attempt be permitted? */
updatePermission(isPermissionGranted: boolean) {
CanNavigateService._isPermissionGranted = isPermissionGranted
}//updatePermission
//-------------------------------------------------------------//
/**Broadcast the last attempt and whether it was permitted */
updateNavigationAttempt(wasPermissionGranted: boolean) {
this.navigationAttempt.next(wasPermissionGranted)
}//updatePermission
//-------------------------------------------------------------//
/**Can we navigate? */
public isPermissionGranted(): boolean {
return CanNavigateService._isPermissionGranted
}//isPermissionGranted
}//Cls
NavigationGuard like @Jithin Nair above but also broadcasts when an attempt to navigate was made and whether it was permitted. Subscribers of CanNavigateService can use it to decide what to do instead of back navigation.
@Injectable()
export class NavigationGuard implements CanDeactivate<any> {
constructor(private canNavigateService: CanNavigateService) { }
//--------------------------------------------------------------------//
// will prevent user from going back if permission has not been granted
canDeactivate(component: any) {
let permitted = this.canNavigateService.isPermissionGranted()
this.canNavigateService.updateNavigationAttempt(permitted)
if (!permitted) {
// push current state again to prevent further attempts.
history.pushState(null, null, location.href)
return false
}
return true
}//canDeactivate
}//Cls
Usage:
constructor(private _navigateService: CanNavigateService) {
super()
_navigateService.navigationAttempt.subscribe(wasPermitted => {
//If navigation was prevented then just go to first tab
if (!wasPermitted)
this.onTabSelected( this._firstTab)
})
}//ctor
//----------------------------------------------------------------------------//
onTabSelected(tab) {
this._selectedTab = tab
//If it's not the first tab you can't back navigate
this._navigateService.updatePermission(this._selectedTab == this._firstTab)
}//onTabSelected
This issue occurs on IE browser. Use below mentioned code it will resolve your issue.
@HostListener('document:keydown', ['$event'])
onKeyDown(evt: KeyboardEvent) {
if (
evt.keyCode === 8 || evt.which === 8
) {
let doPrevent = true;
const types =['text','password','file','search','email','number','date','color','datetime','datetime-local','month','range','search','tel','time','url','week'];
const target = (<HTMLInputElement>evt.target);
const disabled = target.disabled || (<HTMLInputElement>event.target).readOnly;
if (!disabled) {
if (target.isContentEditable) {
doPrevent = false;
} else if (target.nodeName === 'INPUT') {
let type = target.type;
if (type) {
type = type.toLowerCase();
}
if (types.indexOf(type) > -1) {
doPrevent = false;
}
} else if (target.nodeName === 'TEXTAREA') {
doPrevent = false;
}
}
if (doPrevent) {
evt.preventDefault();
return false;
}
}
}
step 1: Import Locatoion from angular commmon
import {Location} from "@angular/common";
step 2: Initialise in constructor
private location: Location
step 3: Add function in ngOnInit of the respective coponent,
this.location.subscribe(currentLocation => {
if (currentLocation.url === '*/basic-info*') {
window.onpopstate = function (event) {
history.go(1);
}
}
});
Note: Here /basic-info will be replaced by your path.
If first time it is not working, try adding outside subscribe,
let currentUrl = window.location.href;
let tmpVar = currentUrl.includes('/basic-info');
if (currentUrl.includes('/basic-info')) {
window.onpopstate = function (event) {
history.go(1);
}
}