Enhancing the train departure board with autocomplete

Live departure board with autocomplete

This post demonstrates how to add an autocomplete enabled input field to the live departure board to make it easy to find train departure information for any station in the UK.

The completed version can be accessed here and the project can be found on GitHub. The project has been refactored since the publication of the earlier post and if you are following along ensure you are working on the latest version.

In this post I will focus on adding the autocomplete functionality and skip over the minutiae of adding and styling the new html elements.

Which autocomplete?

There are several options for adding autocomplete functionality to an angular project; Angular Material, angular-ng-autocomplete and jQuery UI. I decided on jQuery-ui because of two reasons. Firstly the application uses Bootstrap so already had a dependency on jQuery and secondly it appeared to be the easiest to get up and running.

Adding jQuery and jQuery UI to Angular.

Open the project and navigate to index.html and add the jQuery and jQuery UI cdn links. I used the min version of both libraries.

jQuery and jQuery UI added to index.html

StationNamesService

This new service contains a private read only property

stationNamesAndCRS 

which is an array containing the names and the Computer Reservation System (CRS) codes for all train stations in the UK. I obtained the information by calling the Huxley api:

https://huxley.apphb.com/crs    

There is also another private read only property

stationNames

which contain just the station names. This property will be used as the source for the autocomplete list.

The service has two methods.

getStationNames()  

which returns the stationNames property and

getCRSForStation(stationNameToFind: string)

which returns the CRS code for a supplied station. As an example if the station name is Lougborough it will return LBO. The CRS code will ultimately be used to invoke Huxley. In an earlier version I passed the station name to Huxley but ran in to problems with names containing the ampersand character.

Changes to app.component.ts

To use jQuery in the component you should add the following line after the import statements

declare let $: any;
Adding jQuery to an Angular TypeScript component

The new stationNamesService should be injected into the component via the constructor:

constructor(private trainInformationService: TrainInformationService,                  
            private stationNamesService: StationNamesService) {}

To populate the source option of the jQuery-ui autocomplete widget. The following method is used.

private populateStationAutocomplete() {    
  this.trainStationNames = this.getTrainStationNames();    
  $('#stationName').autocomplete({source: this.trainStationNames});  
}

populateStationAutocomplete is called from ngOnInit

ngOnInit showing the addition call to populateStationAutocomplete()

The final new method is

trainStationSelected(stationName: string) {
  const crsCode = this.stationNamesService.getCRSForStation(stationName);
  const trainStationUrl = this.trainInformationService.getFullUrl(crsCode);
  this.getDepartureBoard(trainStationUrl);
 } 

which is invoked when the train station has been selected and the user has pressed the enter key or select button. The method obtains the CRS code for the selected station, constructs the URL that will be passed to Huxley and calls the getDepartureBoard method.

app.component.html

A new html text input and button are created.

<input type="text" 
        class="form-control col-sm-6 ml-md 3" 
        id="stationName" 
        value="Loughborough (Leics)" 
        (keyup.enter)="trainStationSelected(stationName.value)" 
        #stationName>  

The interesting attribute of this object is invocation of the trainStationSelected method when the enter key has been pressed which allows the selection of a different train station using the keyboard.

It is also possible to select a different train station using a button

<button class="btn btn-warning" 
        id="selectStationName" 
        (click)="trainStationSelected(stationName.value)">

With these elements in place autocomplete functionality has now been added.

One thought on “Enhancing the train departure board with autocomplete

Leave a Reply

Please log in using one of these methods to post your comment:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.