Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angular2 How to navigate to certain section of the page identified with an id attribute

How to navigate to certain section of the page identified with an id attribute?

Example:

I need to navigate to "structure" paragraph on my page

<div id="info">
  <h3>Info</h3>
  <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit.</p>
</div>    
<div id="structure">
  <h3>Structure</h3>
  <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit.</p>
</div>

And I have a following navigation structure:

<li>
  <ul materialize="collapsible" class="collapsible" data-collapsible="accordion">
    <li><a routerLink="policies" class="collapsible-header">Policies</a>
      <div class="collapsible-body">
         <ul>
           <li><a >Info</a></li>
           <li><a >Structure</a></li>
           <li><a >Something Else</a></li>
         </ul>
      </div>
    </li>
   </ul>
 </li>

It is my understanding that in Angular1.0 I simply could've navigate to the page section using something like: ui-sref="policies({'#':'structure'})" or href="#structure" or ui-sref="policies" href="#structure"...

How can I do it in Angular2? I looked at the Fragment example in the docs: Query Parameters and Fragments section and I am finding they example to be very confusing and a bit overkill for such a potentially simple task

like image 923
Alla Avatar asked Nov 08 '16 23:11

Alla


People also ask

How do you navigate one component to another component?

We can navigate to another component programmatically using the NavigationManager service: Inject the service @inject directive. Use the NavigateTo() method for navigation.

Which attribute is used to navigate from one component to another?

Using the router concept, we can navigate from one component to another component.

How to redirect in Angular component?

To set up a redirect, configure a route with the path you want to redirect from, the component you want to redirect to, and a pathMatch value that tells the router how to match the URL.


3 Answers

Angular 2: I would prefer to go with scrollIntoView() method scrollIntoView. It would provide smooth scrolling transition effect in the browser.

HTML Code

    <div #info id="info">
        <h3>Info</h3>
        <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit.</p>
    </div>
    <div #structure  id="structure">
        <h3>Structure</h3>
        <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit.</p>
    </div>

  <li>
    <ul materialize="collapsible" class="collapsible" data-collapsible="accordion">
      <li><a routerLink="policies" class="collapsible-header">Policies</a>
        <div class="collapsible-body">
           <ul>
             <li (click)="infoStruc()"><a >Info</a></li>
             <li (click)="moveToStructure()"><a  >Structure</a></li>
             <li><a >Something Else</a></li>
         </ul>
       </div>
     </li>
   </ul>
 </li>

and in the Component.

  @Component({
    selector: 'my-app',
    template: `template.html        `
  })
  export class AppComponent {
    @ViewChild('structure') public structure : ElementRef;

    @ViewChild('info') public info : ElementRef;

    public moveToStructure():void {
            this.structure.nativeElement.scrollIntoView({ behavior: 'smooth', block: 'end', inline: 'start' });
    }

    public infoStruc():void {
        setImmediate(() => {
            this.info.nativeElement.scrollIntoView({ behavior: 'smooth', block: 'end', inline: 'start' });
        });
    }
}
like image 132
Praveen M P Avatar answered Nov 15 '22 23:11

Praveen M P


I have used a combination of the previous answer once a click is performed in the HTML file:

<ul>
   <li><a (click)="internalRoute("routeexample1","info")">Info</a></li>
   <li><a (click)="internalRoute("routeexample2","structure")>Structure</a></li>
   <li><a (click)="internalRoute("routeexample3","something")>Something Else</a </li>
</ul>

In the component typescript file (component file) it is necessary to define the corresponding navigation including Router and navigation:

constructor(private router:Router) { }
internalRoute(page,dst){
    this.sectionScroll=dst;
    this.router.navigate([page], {fragment: dst});
}

With this, the app is able to navigate to the corresponding page but not to the specific section. To go to the defined (desirable) section, it is needed to do the scroll. For that, we initially define a function to do the scroll to specific "id" (Scroll Function here):

doScroll() {

    if (!this.sectionScroll) {
      return;
    }
    try {
      var elements = document.getElementById(this.sectionScroll);

      elements.scrollIntoView();
    }
    finally{
      this.sectionScroll = null;
    }
  } 

Finally, we need to capture the navigation event and perform the scroll (modifying the ngInit function) (Event capturing page Init):

ngOnInit() {
    this.router.events.subscribe((evt) => {
      if (!(evt instanceof NavigationEnd)) {
        return;
      }
      this.doScroll();
      this.sectionScroll= null;
    });
  }

It works for me. Hopes help.

like image 30
Aitor Corchero Avatar answered Nov 15 '22 23:11

Aitor Corchero


You could add fragment attribute for your html link

<ul>
   <li><a [routerLink]="['routeexample1']" fragment="info">Info</a></li>
   <li><a [routerLink]="['routeexample2']" fragment="structure">Structure</a></li>
   <li><a [routerLink]="['routeexample3']" fragment="something">Something Else</a></li>
 </ul>

To navigate programmatically you could this

this.router.navigate( ['routeexample1' ], {fragment: 'structure'});
like image 43
Michael Avatar answered Nov 15 '22 23:11

Michael