1

I've come to a problem on my Angular project. In my program, I have the user select an employee from a combo box. When that happens, the array for that employee is chosen and set to selectedEmployee. From there, in a different component, the details about the employee will be displayed from the array. Now, I've run into a problem where I need to have first, next, previous, and last buttons to iterate through the different employees and I am not sure how to do that. I've tried to mess around with some things, but I'm really stuck at this point.

Note: my array is being sorted and then displayed so I cannot just simply take the direct index of whatever was selected in the combo box because it won't be the same employee in the other component.

Here's my tracker.component.ts

import { Component, OnInit, Input} from '@angular/core';
import { RouterModule, Routes } from '@angular/router';

import { PTODataService } from './pto-data.service';
import { PTOData } from './pto-data';
import { EmpInfoService } from './emp-info.service';
import { EmpInfo } from './emp-info'; 

@Component({
    selector: 'pto-tracker',
    templateUrl: `./tracker.component.html`,
    styleUrls: ['./tracker.component.css']
})

export class TrackerComponent implements OnInit{
    empInfo: EmpInfo[] = new Array<EmpInfo>();
    ptoData: PTOData[];
    isHidden: boolean = false;
    selectedEmployee: number = 0;

    public selectedType: string = "PTO";

    constructor(
        private empInfoService: EmpInfoService,
        private ptoDataService: PTODataService) { }

    getEmpInfo(): void {
        this.empInfoService.getEmpInfos().then(
            empInfo => {
                this.empInfo = empInfo.sort((a, b) => a.LastName < b.LastName ? -1 : b.LastName < a.LastName ? 1 : 0);
            });
    }

    getPTOData(): void {
        this.ptoDataService.getPTODatas().then(
            ptoData => this.ptoData = ptoData
        );
    }

    ngOnInit(): void {
        this.getEmpInfo();
        this.getPTOData();
    }


    toggleSummary(): void {
        this.isHidden = !this.isHidden;
    }

    isNextValid() {
        if (this.selectedEmployee > 0) {
            return true;
        }
        else {
            return false;
        }
    }

    isPreviousValid() {
        if (this.selectedEmployee < this.empInfo.length - 1) {
            return true;
        }
        else {
            return false;
        }
    }

    nextEmployee(): void {
        this.selectedEmployee = this.selectedEmployee + 1;
    }

    previousEmployee(): void {
        this.selectedEmployee = this.selectedEmployee - 1;
    }

    firstEmployee(): void {
        this.selectedEmployee = 0;
    }

    lastEmployee(): void {
        this.selectedEmployee = this.empInfo.length - 1;
    }
}

my tracker.component.html

<div class="row">
  <div [ngClass]="{'col-xs-12':isHidden === true, 'col-xs-7': isHidden !== false}">
    <button class="btn btn-default btn-primary" style="width:50px; height: 50px; float:right; padding-bottom: 10px; padding-top: 10px;margin:5px;" (click)="toggleSummary()"><i class="fa fa-pencil-square-o fa-2x" aria-hidden="true"></i></button>

    <div class="col-xs-12 no-pad" style="padding-bottom:50px;">
      <div class="col-xs-3">
        <select class="form-control" id="empName" [(ngModel)]="selectedEmployee">
          <option selected="selected" disabled>Employee Name...</option>
          <option *ngFor="let emp of empInfo; let i = index" [ngValue]="i">{{i}} {{emp.EmpID}} - {{emp.FirstName}} {{emp.LastName}}</option>
        </select>
      </div>
      <div class="col-xs-2">
        <select class="form-control" id="PTOtype" [(ngModel)]="selectedType">
          <option selected="selected" value="PTO">PTO</option>
          <option value="etoEarned">ETO - Earned</option>
          <option value="etoUsed">ETO - Used</option>
          <option value="STDLTD">STD/LTD</option>
          <option value="Uncharged">Uncharged</option>
        </select>
      </div>
    </div>
    <div class="col-xs-12">
      <table class="table table-striped table-bordered">
        <thead>
          <tr>
            <th>Date</th>
            <th>Full/Half</th>
            <th>Hours</th>
            <th>Scheduled?</th>
            <th>Notes</th>
            <th>In P/R?</th>
          </tr>
        </thead>
        <tfoot *ngIf="empInfo && empInfo.length > selectedEmployee">
          <tr>
            <td colspan="6">
              <span class="requestText">Requests:</span>
              <button class="btn btn-default btn-primary btn-bargin" style="float: right;" (click)="lastEmployee()"><i class="fa fa-step-forward fa-lrg" aria-hidden="true"></i></button>
              <button [disabled]="!isPreviousValid()" class="btn btn-default btn-primary btn-margin" style="float:right;" (click)="nextEmployee()"><i class="fa fa-play fa-lrg" aria-hidden="true"></i></button>
              <div class="footertext">{{selectedEmployee+1}} of {{empInfo.length}}</div>
              <button [disabled]="!isNextValid()" class="btn btn-default btn-primary btn-margin" style="float: right;" (click)="previousEmployee()"><i class="fa fa-play fa-flip-horizontal fa-lrg" aria-hidden="true"></i></button>
              <button class="btn btn-default btn-primary btn-margin" style="float: right;" (click)="firstEmployee()"><i class="fa fa-step-backward fa-lrg" aria-hidden="true"></i></button>
            </td>
          </tr>
        </tfoot>
        <tbody>
          <tr *ngFor="let pto of ptoData">
            <ng-container *ngIf="pto.type === selectedType">
              <ng-container *ngIf="pto.EmpKey === empInfo[selectedEmployee].EmpKey">
                <td>{{pto.date | date: 'MM/dd/y'}}</td>
                <td>{{pto.fullhalf}}</td>
                <td>{{pto.hours}}</td>
                <td>{{pto.scheduled}}</td>
                <td>{{pto.notes}}</td>
                <td>{{pto.inPR}}</td>
              </ng-container>
            </ng-container>
          </tr>
        </tbody>
      </table>
    </div>
  </div>
  <div *ngIf="isHidden" class="col-xs-5">
    <pto-summary [selectedEmployee]="selectedEmployee"></pto-summary>
  </div>
</div>

my summary.component.ts

import { Component, OnInit, Input } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
import { EmpInfoService } from './emp-info.service';
import { TrackerComponent } from './tracker.component';
import { EmpInfo } from './emp-info'; 

@Component({
    selector: 'pto-summary',
    templateUrl: `./summary.component.html`,
    styleUrls: ['./summary.component.css']
})

export class SummaryComponent implements OnInit{

    empInfo: EmpInfo[];
    @Input() selectedEmployee: number;

    timeVar = " hours";
    checkboxValue = false;

    constructor(private empInfoService: EmpInfoService) { }

    getEmpInfo(): void {
        this.empInfoService.getEmpInfos().then(
            empInfo => {
                this.empInfo = empInfo.sort((a, b) => a.LastName < b.LastName ? -1 : b.LastName < a.LastName ? 1 : 0);
            });
    }

    ngOnInit(): void {
        this.getEmpInfo();
    }

    changeTime(): void {
        if (!this.checkboxValue)
        {
            this.timeVar = " hours"

            this.empInfo[this.selectedEmployee].STDLTD = this.empInfo[this.selectedEmployee].STDLTD * 8;
            this.empInfo[this.selectedEmployee].Uncharged = this.empInfo[this.selectedEmployee].Uncharged * 8;

            this.empInfo[this.selectedEmployee].PTOBase = this.empInfo[this.selectedEmployee].PTOBase * 8;
            this.empInfo[this.selectedEmployee].PTOCarry = this.empInfo[this.selectedEmployee].PTOCarry * 8;
            this.empInfo[this.selectedEmployee].PTOBorrowed = this.empInfo[this.selectedEmployee].PTOBorrowed * 8;
            this.empInfo[this.selectedEmployee].PTOBalance = this.empInfo[this.selectedEmployee].PTOBalance * 8;
            this.empInfo[this.selectedEmployee].PTORequests = this.empInfo[this.selectedEmployee].PTORequests * 8;
            this.empInfo[this.selectedEmployee].PTORemaining = this.empInfo[this.selectedEmployee].PTORemaining * 8;

            this.empInfo[this.selectedEmployee].ETOEarned = this.empInfo[this.selectedEmployee].ETOEarned * 8;
            this.empInfo[this.selectedEmployee].ETORequests = this.empInfo[this.selectedEmployee].ETORequests * 8;
            this.empInfo[this.selectedEmployee].ETORemaining = this.empInfo[this.selectedEmployee].ETORemaining * 8;
        }
        else
        {
            this.timeVar = " days"

            this.empInfo[this.selectedEmployee].STDLTD = this.empInfo[this.selectedEmployee].STDLTD / 8;
            this.empInfo[this.selectedEmployee].Uncharged = this.empInfo[this.selectedEmployee].Uncharged / 8;

            this.empInfo[this.selectedEmployee].PTOBase = this.empInfo[this.selectedEmployee].PTOBase / 8;
            this.empInfo[this.selectedEmployee].PTOCarry = this.empInfo[this.selectedEmployee].PTOCarry / 8;
            this.empInfo[this.selectedEmployee].PTOBorrowed = this.empInfo[this.selectedEmployee].PTOBorrowed / 8;
            this.empInfo[this.selectedEmployee].PTOBalance = this.empInfo[this.selectedEmployee].PTOBalance / 8;
            this.empInfo[this.selectedEmployee].PTORequests = this.empInfo[this.selectedEmployee].PTORequests / 8;
            this.empInfo[this.selectedEmployee].PTORemaining = this.empInfo[this.selectedEmployee].PTORemaining / 8;

            this.empInfo[this.selectedEmployee].ETOEarned = this.empInfo[this.selectedEmployee].ETOEarned / 8;
            this.empInfo[this.selectedEmployee].ETORequests = this.empInfo[this.selectedEmployee].ETORequests / 8;
            this.empInfo[this.selectedEmployee].ETORemaining = this.empInfo[this.selectedEmployee].ETORemaining / 8;
        }
    }
}

and my summary.component.html

<div class="panel panel-default">
  <div class="panel-heading">
    <h3 class="panel-title pull-left">{{empInfo[selectedEmployee].LastName | uppercase}} Summary</h3>
    <div style="float: right;">
      <div class="onoffswitch">
        <input [(ngModel)]="checkboxValue" (change)="changeTime()" type="checkbox" name="onoffswitch" class="onoffswitch-checkbox" id="myonoffswitch" checked>
        <label class="onoffswitch-label" for="myonoffswitch">
          <span class="onoffswitch-inner"></span>
          <span class="onoffswitch-switch"></span>
        </label>
      </div>
    </div>
    <div class="clearfix"></div>
  </div>
  <div class="panel-body">
    <form class="form-horizontal" role="form" style="overflow-x:auto;">
      <fieldset>
        <div class="col-xs-6">
          <div class="form-group" *ngIf="empInfo && empInfo.length > selectedEmployee">
            <label class="col-xs-5"> Status </label>
            <div class="col-xs-7">
              <select class="form-control" id="empStatus" [(ngModel)]="empInfo[selectedEmployee].EmpStat" name="empStatus">
                <option value="Current">Current</option>
                <option value="Terminated">Terminated</option>
              </select>
            </div>
          </div>
        </div>
        <div class="col-xs-6">
          <div class="form-group" *ngIf="empInfo && empInfo.length > selectedEmployee">
            <label class="col-xs-5"> Anniversary </label>
            <div class="col-xs-7">
              <div class="input-group">
                <input class='form-control' type="text" id="empAnniversary" [(ngModel)]="empInfo[selectedEmployee].Anniversary" name="empAnniversary" />
                <span class="input-group-addon">years</span>
              </div>
            </div>
          </div>
         </div>
        <div class="col-xs-6">
          <div class="form-group" *ngIf="empInfo && empInfo.length > selectedEmployee">
            <label class="col-xs-5"> Start Date </label>
            <div class="col-xs-7">
              <input class='form-control' type="text" id="empStartDate" [ngModel]="empInfo[selectedEmployee].StartDate | date: 'MM/dd/y'" name="empStartDate"/>
            </div>
          </div>
        </div>
        <div class="col-xs-6">
          <div class="form-group" *ngIf="empInfo && empInfo.length > selectedEmployee">
            <label class="col-xs-5"> Adjusted Start </label>
            <div class="col-xs-7">
              <input class='form-control' type="text" id="empAdjustedStart" [ngModel]="empInfo[selectedEmployee].AdjustedStart | date: 'MM/dd/y'" name="empAdjustedStart"/>
            </div>
          </div>
        </div>
        <div class="col-xs-6">
          <div class="form-group" *ngIf="empInfo && empInfo.length > selectedEmployee">
            <label class="col-xs-5"> STD/LTD </label>
            <div class="col-xs-7">
              <div class="input-group">
                <input class='form-control' type="text" id="empSTDLTD" [(ngModel)]="empInfo[selectedEmployee].STDLTD" name="empSTDLTD" />
                <span class="input-group-addon">{{timeVar}}</span>
              </div>
            </div>
          </div>
        </div>
        <div class="col-xs-6">
          <div class="form-group" *ngIf="empInfo && empInfo.length > selectedEmployee">
            <label class="col-xs-5"> Uncharged </label>
            <div class="col-xs-7">
              <div class="input-group">
                <input class='form-control' type="text" id="empUncharged" [(ngModel)]="empInfo[selectedEmployee].Uncharged" name="empUncharged" />
                <span class="input-group-addon">{{timeVar}}</span>
              </div>
            </div>
          </div>
        </div>
      </fieldset>


      <fieldset>

        <h4>PTO</h4>
        <br />

        <div class="col-xs-12">
          <div class="form-group" *ngIf="empInfo && empInfo.length > selectedEmployee">
            <div class="col-xs-1"></div>
            <label class="col-xs-2"> Base </label>
            <div class="col-xs-3">
              <div class="input-group">
                <input class='form-control' type="text" id="ptoBase" [(ngModel)]="empInfo[selectedEmployee].PTOBase" name="ptoBase" />
                <span class="input-group-addon">{{timeVar}}</span>
              </div>
            </div>
            <div class="col-xs-6">
            </div>
          </div>
        </div>
        <div class="col-xs-6">
          <div class="form-group" *ngIf="empInfo && empInfo.length > selectedEmployee">
            <label class="col-xs-2" style="font-weight: bold;"> &#43; </label>
            <label class="col-xs-4"> Carryover </label>
            <div class="col-xs-6">
              <div class="input-group">
                <input class='form-control' type="text" id="ptoCarry" [(ngModel)]="empInfo[selectedEmployee].PTOCarry" name="ptoCarry" />
                <span class="input-group-addon">{{timeVar}}</span>
              </div>
            </div>
          </div>
        </div>
        <div class="col-xs-6">
          <div class="form-group" *ngIf="empInfo && empInfo.length > selectedEmployee">
            <div class="col-xs-1"></div>
            <label class="col-xs-4"> Balance </label>
            <div class="col-xs-6">
              <div class="input-group">
                <input class='form-control' type="text" id="ptoBalance" [(ngModel)]="empInfo[selectedEmployee].PTOBalance" name="ptoBalance" />
                <span class="input-group-addon">{{timeVar}}</span>
              </div>
            </div>
            <div class="col-xs-1"></div>
          </div>
        </div>
        <div class="col-xs-6">
          <div class="form-group" *ngIf="empInfo && empInfo.length > selectedEmployee">
            <label class="col-xs-2" style="font-weight: bold;"> &#8213; </label>
            <label class="col-xs-4"> Borrowed </label>
            <div class="col-xs-6">
              <div class="input-group">
                <input class='form-control' type="text" id="ptoBorrowed" [(ngModel)]="empInfo[selectedEmployee].PTOBorrowed" name="ptoBorrowed" />
                <span class="input-group-addon">{{timeVar}}</span>
              </div>
            </div>
          </div>
          <hr style="border: solid 1px black;border-bottom:1px solid black;clear:both" />
        </div>
        <div class="col-xs-6">
          <div class="form-group" *ngIf="empInfo && empInfo.length > selectedEmployee">
            <label class="col-xs-1" style="font-weight: bold;"> &#8213; </label>
            <label class="col-xs-4"> Requests </label>
            <div class="col-xs-6">
              <div class="input-group">
                <input class='form-control' type="text" id="ptoRequests" [(ngModel)]="empInfo[selectedEmployee].PTORequests" name="ptoRequests" />
                <span class="input-group-addon">{{timeVar}}</span>
              </div>
            </div>
            <div class="col-xs-1"></div>
          </div>
          <hr style="border: solid 1px black;border-bottom:1px solid black;clear:both" />
        </div>
        <div class="col-xs-6">
          <div class="form-group" *ngIf="empInfo && empInfo.length > selectedEmployee">
            <label class="col-xs-2" style="font-weight: bold;"> &#61; </label>
            <label class="col-xs-4"> Balance </label>
            <div class="col-xs-6">
              <div class="input-group">
                <input class='form-control' type="text" id="ptoBalance" [(ngModel)]="empInfo[selectedEmployee].PTOBalance" name="ptoBalance" />
                <span class="input-group-addon">{{timeVar}}</span>
              </div>
            </div>
          </div>
        </div>
        <div class="col-xs-6">
          <div class="form-group" *ngIf="empInfo && empInfo.length > selectedEmployee">
            <label class="col-xs-1" style="font-weight: bold;"> &#61; </label>
            <label class="col-xs-4"> Available </label>
            <div class="col-xs-6">
              <div class="input-group">
                <input class='form-control' type="text" id="ptoRemaining" [(ngModel)]="empInfo[selectedEmployee].PTORemaining" name="ptoRemaining" />
                <span class="input-group-addon">{{timeVar}}</span>
              </div>
            </div>
            <div class="col-xs-1"></div>
          </div>
        </div>
      </fieldset>


      <fieldset>

        <h4>ETO</h4>
        <br />

          <div class="col-xs-6">
            <div class="form-group" *ngIf="empInfo && empInfo.length > selectedEmployee">
              <div class="col-xs-2"></div>
              <label class="col-xs-4"> Earned </label>
              <div class="col-xs-6">
                <div class="input-group">
                  <input class='form-control' type="text" id="etoEarned" [(ngModel)]="empInfo[selectedEmployee].ETOEarned" name="etoEarned" />
                  <span class="input-group-addon">{{timeVar}}</span>
                </div>
              </div>
            </div>
            <div class="form-group" *ngIf="empInfo && empInfo.length > selectedEmployee">
              <label class="col-xs-2"> &#8213; </label>
              <label class="col-xs-4"> Requests </label>
              <div class="col-xs-6">
              <div class="input-group">
                <input class='form-control' type="text" id="etoRequests" [(ngModel)]="empInfo[selectedEmployee].ETORequests" name="etoRequests" />
                <span class="input-group-addon">{{timeVar}}</span>
              </div>
              </div>
            </div>
            <hr style="border: solid 1px black;border-bottom:1px solid black;clear:both" />
            <div class="form-group" *ngIf="empInfo && empInfo.length > selectedEmployee">
              <label class="col-xs-2"> &#61; </label>
              <label class="col-xs-4"> Available </label>
              <div class="col-xs-6">
                <div class="input-group">
                  <input class='form-control' type="text" id="etoRemaining" [(ngModel)]="empInfo[selectedEmployee].ETORemaining" name="etoRemaining" />
                  <span class="input-group-addon">{{timeVar}}</span>
                </div>
              </div>
            </div>
          </div>
          <div class="col-xs-6"></div>

      </fieldset>
    </form>
  </div>
</div>

EDIT - Updated Code

Now, everything works except for whenever I go to the summary tab, I'm getting an error in the browser that says "Cannot read property '...' of undefined" where the '...' is the index of whichever employee is selected.

5
  • Just sort the array either in the service or when you resolve the promise from the service, so you can use the index. What's the problem with that? Also, you isPreviousValid() and isNextValid() looks a bit wrong, you should review those. Commented Jun 7, 2017 at 13:04
  • I was unaware that I could sort the array in the service. Would I just move my pipe to the service? Commented Jun 7, 2017 at 13:06
  • No - pipes are only for templates. To sort it in the service, you use plain javascript to sort it before you return the list. Or in getEmpInfo(), right above the line this.empInfo = empInfo; Commented Jun 7, 2017 at 13:09
  • Try just removing the pipe and add this where you set the array: this.empInfo = empInfo.sort((a, b) => a.LastName > b.LastName ? -1 : b.LastName > a.LastName ? 1 : 0); Commented Jun 7, 2017 at 13:29
  • 1
    that worked great! thanks! if you want to put that as an answer, I'll give you credit for it Commented Jun 7, 2017 at 13:39

1 Answer 1

1

Instead of sorting the array in the template with a pipe, do the sorting in the component code when you get the data from the service. Try removing the orderByLastpipe in the template and modify the getEmpInfo() function like this:

getEmpInfo(): void {
   this.empInfoService.getEmpInfos().then(
       empInfo => {
           this.empInfo = empInfo.sort((a, b) => 
                a.LastName > b.LastName ? -1 : b.LastName > a.LastName ? 1 : 0);
   });
}

This will allow you do use the index from the dropdown to select your employee.

Sign up to request clarification or add additional context in comments.

1 Comment

updated my code and question, could you take a look? thanks!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.