Issue
I have an Angular SPA, page contains either listing of records or edit a record section (includes history of editing as well). Initial state is to show list of records.
Because some record has long history of editing, so placing a Back to top of Editing will make it easier to use. HTML5 supports #top
, right? Well, it actually toggles back to non-editing mode shows list of records 🙁
HTML below:
<div *ngIf="editMode">
<a id="top"></a>
record detailed content here
<hr>
long history of record editing here
<a href="#top">Back to top of Editing</a><!-- Nope, it actually toggles back to non-editing mode shows list of records -->
<div>
<div *ngIf="!editMode">
<mat-card *ngFor="let rec of listRec">
...
<input type=button (click)="switchToEditMode()">Edit</input>
</mat-card>
</div>
.TS:
editMode: boolean = false;
...
switchToEditMode() { editMode=true; ...}
Update, this is how it works following @RedJandal suggestion using Manual Scrolling, add this to HTML
<span #myTop id="myTop"></span>
<button (click)="toMyTop()">go to Top</button>
add this to TS
@ViewChild("myTop") myTop: ElementRef;
toMyTop()
{
const targetElement = this.myTop.nativeElement;
targetElement.scrollIntoView({behavior: "smooth"});
}
Note, to use <a>
in place of <button>
, important to remove href=#<anything>
Solution
Because you are using an anchor tag the page is being refreshed, that is why it toggles back to non-editing mode.
Automatic Scrolling
Since Angular v6, there is the new anchorScrolling
option for the RouterModule
. You can set it in the module’s import:
imports: [
...,
RouterModule.forRoot(routes, {anchorScrolling: 'enabled'})
With this, Angular will automatically scroll to the element with the id of the given fragment.
⚠️ However, this does not work when the data is loaded asynchronously, see this Github issue. ⚠️
Manual Scrolling
Smooth scrolling is not yet possible via the RouterModule
, but you can do it manually:
Get your target e.g. with ViewChild
:
@ViewChild('pageInfo') pageInfo: ElementRef;
Call scrollIntoView
on the nativeElement
:
const targetElement = this.pageInfo.nativeElement
targetElement.scrollIntoView({behavior: "smooth"})