left-icon

Angular Succinctly®
by Joseph D. Booth

Previous
Chapter

of
A
A
A

CHAPTER 17

Scoring

Scoring


The scoring component allows a person to pick a game from the schedule, update the home and away scores, and then save the updated scores back to the component. The scoring screen is shown in the following figure.

Scoring Screen

Figure 17: Scoring Screen

The user selects a game, and the screen updates both team names as labels, and the team scores as edit boxes. The user can then change the scores and click the Record Scores button to save the updated scores (and possibly update the Standings view).

Scoring component

Code Listing 144

/*  Scoring component */

import { Component } from '@angular/core';

import { Title } from '@angular/platform-browser'; 

import { ViewEncapsulation } from '@angular/core'; 

// Our application services and interfaces

import { iSchedule } from '../interfaces/schedule';

import { SoccerService} from '../services/soccerService';

@Component({

    templateUrl: '../Views/scoring.html',       // HTML template name  

    styles: [` h3 {text-align:center;color:navy;

                  font-size:x- large;margin:0px;font-weight:bold;}

            select { font-size:large;margin-left:25px;} `],

    providers: [Title,SoccerService]

   })

Scoring template

The scoring template is a simple HTML page where the scores can be recorded by the referee.

Code Listing 145

<h3>{{LeagueName}} </h3>

<br />

<form>

    <p>Season starts:  {{ SeasonStart }} &nbsp;</p> 

        <div class="container" [ngSwitch]="CurrentRole*10">

            <div *ngSwitchCase=10>Head Referee</div>           

            <div *ngSwitchCase=20>Referee</div>

            <div *ngSwitchCase=30>Scorekeeper</div>           

            <div *ngSwitchCase=40>Admin</div>

            <div *ngSwitchDefault>End User</div>

        </div>

    <br/>

This code simply changes the header based on the current role, so the type of user running the page is displayed. You could use a similar approach to make certain features or options visible based on the user admin level.

Code Listing 146

<p style="font-size:large;margin-left:50px;">Game:

    <select (change)="onSchedChange($event.target.value)">

        <option *ngFor="let currentRow of MySchedule"

                    value={{currentRow.id}}>

            {{ currentRow.HomeTeam +" vs "+ currentRow.AwayTeam }}

        </option>

    </select>

    </p>

This code uses the *ngFor directive to populate the drop-down box by iterating over an array. It also binds the change event of the select element to an event inside the class code.

Code Listing 147

<div class="row">

     <div class="col-md-2">&nbsp;</div>

     <div class="form-group col-md-3">

       <label for="HomeTeam"

            style="float:left;font-size:large;">{{HomeTeam}}</label>

     </div>   

     <div class="form-group col-md-2">

     <input type="number"

        style="width:80px;float:right;text-align:right;"

        [(ngModel)]="HomeScore" name="HomeScoreVal"

          class="form-control" />

     </div>           

</div>

<div class="row">

     <div class="col-md-2">&nbsp;</div>

     <div class="form-group col-md-3">

         <label for="AwayTeam"

            style="float:left;font-size:large;">{{AwayTeam}}</label>

     </div>               

     <div class="form-group col-md-2">

            <input type="number"

              style="width:80px;float:right;text-align:right;"                   

                [(ngModel)]="AwayScore" name="AwayScoreVal"

                  class="form-control" />

        </div>

  </div>

<br/>   

We then have code to display the home and away team names using interpolation and property binding. This links the edit box value with the variable in the component.

Our final part of the template links the button click event to a method (which must be public) inside the component.

Code Listing 148

    <button type="button" (click)="onRecordScores()"

         style="font-size:large;margin-left:50px;">

         Record Scores

    </button>

</form>

There are several data-binding elements within the HTML template to collect data and trigger events within the component code. The (click) binding will call the onRecordScores() method inside the component.

You will also notice some simple interpolations, such as HomeTeam and AwayTeam, for displaying the selected team names as part of the screen display.

Class code

The class code for the scoring component performs several actions: it populates the schedule array, detects when a user changes the drop-down box, and fills the score based on the schedule information. It also has code to handle the record scores option when the user clicks the button.

Variables

We declare several variables inside the component that we will use both for the component itself and public variables for the template page.

Code Listing 149

private UsingAsync: boolean = false;

     private CurGame: number = 0;

     public MySchedule: iSchedule[];

     public LeagueName: string;

     public HomeTeam : string;

     public AwayTeam : string;

     public HomeScore : number = 0;

     public AwayScore : number = 0;

     public SeasonStart: Date = new Date;

     public CurrentRole: number = 1;

Constructor

The constructor code updates some variables and specifies the service to be used throughout the component.

Code Listing 150

  public constructor(private _soccerService: SoccerService ) {

    this.LeagueName = "Over 30 men's league";

    this.getSchedule();

    this.SeasonStart.setTime( this.SeasonStart.getTime() +4 * 86400000 );      

    if (this.MySchedule.length>0) {

         this.UpdVariables(0);    // Default to first game

         this.CurGame = 1;

      }

  }

Public methods

Any method that the template code references must be declared as public. We need two public methods: one for the select box change, and another for the user clicking the button to record the scores.

Code Listing 151

     public onSchedChange(GameValue:number) {

       if (GameValue>0)

       {

         this.UpdVariables(GameValue);

         this.CurGame = GameValue;

       }

     }

     // Get the score from the form and update it

     public onRecordScores() {

       this.MySchedule[this.CurGame-1].AwayScore = Number(this.AwayScore);

       this.MySchedule[this.CurGame-1].HomeScore = Number(this.HomeScore);      

     }

Private methods

The private methods are generally methods needed to support the component, but do not need to be used outside the component body. We have a couple private methods in this component.

Code Listing 152

     // Update screen variable based on current game

     private UpdVariables(GameID: number) {

          // Need to search Schedule array, looking for game ID

          var x : number = 0;

          if (GameID >0) {

            x = GameID-1;

          } 

          this.HomeTeam = this.MySchedule[x].HomeTeam;

          this.AwayTeam = this.MySchedule[x].AwayTeam;

          this.HomeScore = this.MySchedule[x].HomeScore;

          this.AwayScore = this.MySchedule[x].AwayScore;

     }

     // Get the schedule (only showing games not yet scored)    

     private getSchedule() {

       if (this.UsingAsync) {

        let xx = this._soccerService.getScheduleAsync();

            xx.then((Schedules:iSchedule[])=> this.MySchedule =Schedules );

       }

       else {

        this.MySchedule = this._soccerService.getSchedule();

       }

     }

If you update the scores, and then go back to the Standings page, you will see the changes reflected in the standings, goals for, and goals against. For an actual application, you would most likely write a web service and use the HTTP module to persist the changes to the back-end database.

Summary

In this chapter, we looked at a simple example of getting data back and forth from the form to the component, and responding to form events and button clicks.

Scroll To Top
Disclaimer
DISCLAIMER: Web reader is currently in beta. Please report any issues through our support system. PDF and Kindle format files are also available for download.

Previous

Next



You are one step away from downloading ebooks from the Succinctly® series premier collection!
A confirmation has been sent to your email address. Please check and confirm your email subscription to complete the download.