When I first picked up Angular many years ago, one of the more frustrating aspects was that on using the router to navigate to another page, the scroll position was kept. This meant you were taken to the new page, but you would be scrolled halfway down the page (Or often right at the bottom if you were filling out a form).

Back then, you had all sorts of crazy fixes involving listening for router events, or maybe even manually scrolling the page. So recently when I ran into the issue on a new project I hoped things had changed. And they have, sort of. I mean, the issue is still there but there is a slightly more elegant fix.

When registering your router module (Typically a new Angular project created using the CLI will have an app-routing.module.ts), you can now edit your import as follows  :

RouterModule.forRoot(routes, {scrollPositionRestoration: 'enabled'})

In future versions of Angular, it’s hoped that this will become the default (Certainly there would be far more use cases of scrolling to the top over keeping the same position), but as of writing you still manually need to add the scrollPositionRestoration param.

Note that this was introduced sometime in Angular 6, for earlier versions (Which hopefully you aren’t creating new projects on), you will still need to do the old school subscribe method. To do this, you need to modify your main component (Often your AppComponent) to subscribe to the router event of NavigationEnd and then call scroll.

export class AppComponent implements OnInit  {
  private router : Router;

  constructor (router : Router)
  {
    this.router = router;
  }

  ngOnInit() {
    this.router.events.subscribe(x => {
      if(x instanceof NavigationEnd)
      {
        window.scrollTo(0, 0);
      }
    });
  }
}

Again this is required only if you are running a version of Angular before 6!

As part of a recent project, I was asked to limit the type of characters that can be input into a text field. I had a quick search around but every single time I thought I had found a solution, it was some form of using the pattern attribute to simply show if invalid characters had been input, but it didn’t actually stop the user from typing them in the first place.

Now, I know that sometimes this can be a bit of an anti-pattern as a limiting the users input like this can be frustrating when you don’t show any warning or validation message, but there are some valid use cases.

The Directive Code

Below is the actual directive which you can add into your Angular project. In my case, I’m developing in Angular 8, but this should work in any modern Angular version.

import { Directive, ElementRef, Input, HostListener } from '@angular/core';

@Directive({
  selector: '[inputrestriction]'
})
export class InputRestrictionDirective {
  @Input('inputrestriction') InputRestriction : string;

  private element : ElementRef;

  constructor(element : ElementRef) {
    this.element = element;
  }

  @HostListener('keypress', ['$event'])
  handleKeyPress(event : KeyboardEvent)
  {
    var regex = new RegExp(this.InputRestriction);
    var str = String.fromCharCode(!event.charCode ? event.which : event.charCode);
    if (regex.test(str)) {
        return true;
    }

    event.preventDefault();
    return false;
  }

}

A quick rundown of the code :

  • I’m using the selector of “inputrestriction” and I’ve made the input variable itself be called the same. Change as you require.
  • The input string takes a regex pattern to match on *allowed* characters.
  • I’m using the host listener to listen for a key press and deciding to allow it or not.

Usage Examples

We can then crack on with some really simple use cases such as letters only :

<input inputrestriction="[a-zA-Z]" type="text" />

Or numbers only :

<input inputrestriction="[0-9]" type="text" />