Getting Started | Building an Application with Angular
Angular 10 Front-end
In this tutorial We will build an application School To display the database Add, update or delete.
Technology
Angular 10
Angular HTTPClient
Angular Router
Angular CLI version (10.1.1)
ng new
The Angular CLI makes it easy to create an application that already works, right out of the box. It already follows our best practices!
ng generate
Generate components, routes, services and pipes with a simple command. The CLI will also create simple test shells for all of these.
ng serve
Easily test your app locally while developing.
$ npm install -g @angular/cli
$ ng new school
$ cd school
$ ng serve
Project Structure
Font Awesome
Font Awesome is a font and icon toolkit based on CSS and Less. It was made by Dave Gandy for use with Bootstrap, and later was incorporated into the BootstrapCDN. Font Awesome has a 38% market share among those websites that use third-party font scripts on their platform, ranking it second place after Google Fonts.
Add this link in index.html to use Font Awesome
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.2.0/css/all.css" integrity="sha384-hWVjflwFxL6sNzntih27bfxkr27PmbbK/iSvJ+a4+0owXq79v+lsFkW54bOGbiDQ" crossorigin="anonymous">
Angular Material Tutorial
The idea of this is article is to teach you how to use Angular Material through a hands-on exercise. First, you will check the dependencies that you need on your computer to use and develop with Angular Material, then you will learn how to configure and use different components.
Install Angular Material
Angular Material In addition to the install schematic, Angular Material comes with several schematics (like nav, table, address-form, etc.) that can be used to easily generate pre-built components in your application.
$ ng add @angular/material
MaterialModule
In earlier versions of Angular Material, we could import MaterialModule which imports all components from Angular Material and makes them available in our app. Most of the time we will need to import the most of material.
src/app/material-module.ts
import { NgModule } from '@angular/core';
import { MatAutocompleteModule } from '@angular/material/autocomplete';
import { MatBadgeModule } from '@angular/material/badge';
import { MatBottomSheetModule } from '@angular/material/bottom-sheet';
import { MatButtonModule } from '@angular/material/button';
import { MatButtonToggleModule } from '@angular/material/button-toggle';
import { MatCardModule } from '@angular/material/card';
import { MatCheckboxModule } from '@angular/material/checkbox';
import { MatChipsModule } from '@angular/material/chips';
import { MatStepperModule } from '@angular/material/stepper';
import { MatDatepickerModule } from '@angular/material/datepicker';
import { MatDialogModule } from '@angular/material/dialog';
import { MatDividerModule } from '@angular/material/divider';
import { MatExpansionModule } from '@angular/material/expansion';
import { MatGridListModule } from '@angular/material/grid-list';
import { MatIconModule } from '@angular/material/icon';
import { MatInputModule } from '@angular/material/input';
import { MatListModule } from '@angular/material/list';
import { MatMenuModule } from '@angular/material/menu';
import { MatNativeDateModule, MatRippleModule } from '@angular/material/core';
import { MatPaginatorModule } from '@angular/material/paginator';
import { MatProgressBarModule } from '@angular/material/progress-bar';
import { MatProgressSpinnerModule } from '@angular/material/progress-spinner';
import { MatRadioModule } from '@angular/material/radio';
import { MatSelectModule } from '@angular/material/select';
import { MatSidenavModule } from '@angular/material/sidenav';
import { MatSliderModule } from '@angular/material/slider';
import { MatSlideToggleModule } from '@angular/material/slide-toggle';
import { MatSnackBarModule } from '@angular/material/snack-bar';
import { MatSortModule } from '@angular/material/sort';
import { MatTableModule } from '@angular/material/table';
import { MatTabsModule } from '@angular/material/tabs';
import { MatToolbarModule } from '@angular/material/toolbar';
import { MatTooltipModule } from '@angular/material/tooltip';
import { MatTreeModule } from '@angular/material/tree';
@NgModule({
exports: [
MatAutocompleteModule,
MatBadgeModule,
MatBottomSheetModule,
MatButtonModule,
MatButtonToggleModule,
MatCardModule,
MatCheckboxModule,
MatChipsModule,
MatStepperModule,
MatDatepickerModule,
MatDialogModule,
MatDividerModule,
MatExpansionModule,
MatGridListModule,
MatIconModule,
MatInputModule,
MatListModule,
MatMenuModule,
MatNativeDateModule,
MatPaginatorModule,
MatProgressBarModule,
MatProgressSpinnerModule,
MatRadioModule,
MatRippleModule,
MatSelectModule,
MatSidenavModule,
MatSliderModule,
MatSlideToggleModule,
MatSnackBarModule,
MatSortModule,
MatTableModule,
MatTabsModule,
MatToolbarModule,
MatTooltipModule,
MatTreeModule,
],
imports: [
MatAutocompleteModule,
MatBadgeModule,
MatBottomSheetModule,
MatButtonModule,
MatButtonToggleModule,
MatCardModule,
MatCheckboxModule,
MatChipsModule,
MatStepperModule,
MatDatepickerModule,
MatDialogModule,
MatDividerModule,
MatExpansionModule,
MatGridListModule,
MatIconModule,
MatInputModule,
MatListModule,
MatMenuModule,
MatNativeDateModule,
MatPaginatorModule,
MatProgressBarModule,
MatProgressSpinnerModule,
MatRadioModule,
MatRippleModule,
MatSelectModule,
MatSidenavModule,
MatSliderModule,
MatSlideToggleModule,
MatSnackBarModule,
MatSortModule,
MatTableModule,
MatTabsModule,
MatToolbarModule,
MatTooltipModule,
MatTreeModule,
]
})
export class MaterialModule { }
Modals interfaces
The purpose of this class is to map the specified fields with the fields of Spring entity class.
Angular NgModules differ from and complement JavaScript (ES2015) modules. An NgModule declares a compilation context for a set of components that is dedicated to an application domain, a workflow, or a closely related set of capabilities. An NgModule can associate its components with related code, such as services, to form functional units.
Every Angular app has a root module, conventionally named AppModule, which provides the bootstrap mechanism that launches the application. An app typically contains many functional modules.
src/app/modal/Modal.ts
export interface PersistableElement {
id: number ;
createdAt: any;
description: string;
}
export interface Activity extends PersistableElement {
type: string;
day: string;
endDate: string;
startDate: string;
date: string;
}
export interface Coefficient extends PersistableElement {
grade: number ;
}
export interface Exam extends PersistableElement {
date: string;
start: string;
end: string;
}
export interface Manager extends PersistableElement {
id: number ;
firstName: string;
lastName: string;
}
export interface Subject extends PersistableElement {
name: string;
color: string;
programs: Program[];
coefficients: Coefficient[];
}
export interface Note extends PersistableElement {
score: number ;
}
export interface Program extends PersistableElement {
name: string;
}
export interface Room extends PersistableElement {
code: string;
capacity: number ;
levels: Level[];
}
export interface School extends PersistableElement {
name: string;
city: string;
department: string;
open: string;
close: string;
}
export interface Schooling extends PersistableElement {
year: number ;
}
export interface Level extends PersistableElement {
label: string;
courses: Course[];
}
export interface Course extends PersistableElement {
date: string;
endDate: string;
startDate: string;
}
Angular Services
Angular services are singleton objects that get instantiated only once during the lifetime of an application. They contain methods that maintain data throughout the life of an application, i.e. data does not get refreshed and is available all the time. The main objective of a service is to organize and share business logic, models, or data and functions with different components of an Angular application.
An example of when to use services would be to transfer data from one controller to another custom service.
Why Should We Use Services in Angular? The separation of concerns is the main reason why Angular services came into existence. An Angular service is a stateless object and provides some very useful functions. These functions can be invoked from any component of Angular, like Controllers, Directives, etc. This helps in dividing the web application into small, different logical units which can be reused.
Create Data services
This service will use Angular HTTPClient to send HTTP requests. You can see that its functions includes CRUD operations and finder method
Create these services in the service package
-> activity.service.ts
-> coefficient.service.ts
-> course.service.ts
-> exam.service.ts
-> level.service.ts
-> manager.service.ts
-> note.service.ts
-> program.service.ts
-> room.service.ts
-> school.service.ts
-> schooling.service.ts
-> subject.service.ts
-> tree-application.service.ts
src/app/service/activity.service.ts
import { Injectable } form '@angular/core';
import { Observable } form 'rxjs';
import { HttpClient } form '@angular/common/http';
@Injectable({
providedIn: 'root'
})
export class ActivityService {
constructor(private http: HttpClient) { }
addActivity(data: any, id: number): Observable<any> {
return this.http.post<any>(`http://localhost:8080/api/addActivity/${id}`, data);
}
editActivity(data: any, id: number): Observable<any> {
return this.http.put<any>(`http://localhost:8080/api/editActivity/${id}`, data);
}
findActivity(id: number): Observable<any> {
return this.http.get<any>(`http://localhost:8080/api/findActivity/${id}`);
}
deleteActivity(id: number): Observable<any> {
return this.http.delete<any>(`http://localhost:8080/api/deleteActivity/${id}`);
}
findActivitiesForSchool(id: number): Observable<any> {
return this.http.get<any>(`http://localhost:8080/api/findActivitiesForSchool/${id}`);
}
}
src/app/service/coefficient.service.ts
import { Injectable } form '@angular/core';
import { Observable } form 'rxjs';
import { HttpClient } form '@angular/common/http';
@Injectable({
providedIn: 'root'
})
export class CoefficientService {
constructor(private http: HttpClient) { }
addCoefficient(data: any, id: number): Observable<any> {
return this.http.post<any>(`http://localhost:8080/api/addCoefficient/${id}`, data);
}
editCoefficient(data: any, id: number): Observable<any> {
return this.http.put<any>(`http://localhost:8080/api/editCoefficient/${id}`, data);
}
findCoefficient(id: number): Observable<any> {
return this.http.get<any>(`http://localhost:8080/api/findCoefficient/${id}`);
}
deleteCoefficient(id: number): Observable<any> {
return this.http.delete<any>(`http://localhost:8080/api/deleteCoefficient/${id}`);
}
}
src/app/service/course.service.ts
import { Injectable } form '@angular/core';
import { Observable } form 'rxjs';
import { HttpClient } form '@angular/common/http';
@Injectable({
providedIn: 'root'
})
export class CourseService {
constructor(private http: HttpClient) { }
addCourse(data: any, idLevel: number, idSubject: number): Observable<any> {
return this.http.post<any>(`http://localhost:8080/api/addCourse/${idLevel}/${idSubject}`, data);
}
editCourse(data: any, idCourse: number, idSubject: number): Observable<any> {
return this.http.put<any>(`http://localhost:8080/api/editCourse/${idCourse}/${idSubject}`, data);
}
findCourse(id: number): Observable<any> {
return this.http.get<any>(`http://localhost:8080/api/findCourse/${id}`);
}
deleteCourse(id: number): Observable<any> {
return this.http.delete<any>(`http://localhost:8080/api/deleteCourse/${id}`);
}
}
src/app/service/exam.service.ts
import { Injectable } form '@angular/core';
import { Observable } form 'rxjs';
import { HttpClient } form '@angular/common/http';
@Injectable({
providedIn: 'root'
})
export class ExamService {
constructor(private http: HttpClient) { }
addExam(data: any, idSchool: number, idSubject: number): Observable<any> {
return this.http.post<any>(`http://localhost:8080/api/addExam/${idSchool}/${idSubject}`, data);
}
editExam(data: any, idCourse: number, idSubject: number): Observable<any> {
return this.http.put<any>(`http://localhost:8080/api/editExam/${idCourse}/${idSubject}`, data);
}
findExam(id: number): Observable<any> {
return this.http.get<any>(`http://localhost:8080/api/findExam/${id}`);
}
deleteExam(id: number): Observable<any> {
return this.http.delete<any>(`http://localhost:8080/api/deleteExam/${id}`);
}
findExamsForSchool(id: number): Observable<any> {
return this.http.get<any>(`http://localhost:8080/api/findExamsForSchool/${id}`);
}
}
src/app/service/exam.service.ts
import { Injectable } form '@angular/core';
import { Observable } form 'rxjs';
import { HttpClient } form '@angular/common/http';
@Injectable({
providedIn: 'root'
})
export class LevelService {
constructor(private http: HttpClient) { }
addLevel(data: any, id: number): Observable<any> {
return this.http.post<any>(`http://localhost:8080/api/addLevel/${id}`, data);
}
editLevel(data: any, id: number): Observable<any> {
return this.http.put<any>(`http://localhost:8080/api/editLevel/${id}`, data);
}
findLevel(id: number): Observable<any> {
return this.http.get<any>(`http://localhost:8080/api/findLevel/${id}`);
}
deleteLevel(id: number): Observable<any> {
return this.http.delete<any>(`http://localhost:8080/api/deleteLevel/${id}`);
}
addLevelToRoom(idRoom: number, idLevel: number): Observable<any> {
return this.http.post<any>(`http://localhost:8080/api/addLevelToRoom/${idRoom}/${idLevel}`);
}
findLevelForRoom(id: number): Observable<any> {
return this.http.get<any>(`http://localhost:8080/api/findLevelForRoom/${id}`);
}
findLevels(): Observable<any> {
return this.http.get<any>(`http://localhost:8080/api/findLevels`);
}
deleteLevelFromRoom(idRoom: number, idLevel: number): Observable<any> {
return this.http.delete<any>(`http://localhost:8080/api/deleteLevelFromRoom/${idRoom}/${idLevel}`);
}
}
src/app/service/manager.service.ts
import { Injectable } form '@angular/core';
import { Observable } form 'rxjs';
import { HttpClient } form '@angular/common/http';
@Injectable({
providedIn: 'root'
})
export class ManagerService {
constructor(private http: HttpClient) { }
addManager(data: any, id: number): Observable<any> {
return this.http.post<any>(`http://localhost:8080/api/addManager/${id}`, data);
}
editManager(data: any, id: number): Observable<any> {
return this.http.put<any>(`http://localhost:8080/api/editManager/${id}`, data);
}
deleteManager(id: number): Observable<any> {
return this.http.delete<any>(`http://localhost:8080/api/deleteManager/${id}`);
}
findManager(id: number): Observable<any> {
return this.http.get<any>(`http://localhost:8080/api/findManager/${id}`);
}
findManagerForSchool(id: number): Observable<any> {
return this.http.get<any>(`http://localhost:8080/api/findManagerForSchool/${id}`);
}
}
src/app/service/note.service.ts
import { Injectable } form '@angular/core';
import { Observable } form 'rxjs';
import { HttpClient } form '@angular/common/http';
@Injectable({
providedIn: 'root'
})
export class NoteService {
constructor(private http: HttpClient) { }
addNote((data: any, id: number): Observable<any> {
return this.http.post<any>(`http://localhost:8080/api/addNote/${id}`, data);
}
editNote(data: any, id: number): Observable<any> {
return this.http.put<any>(`http://localhost:8080/api/editNote/${id}`, data);
}
findNote(id: number): Observable<any> {
return this.http.get<any>(`http://localhost:8080/api/findNote/${id}`);
}
deleteNote(id: number): Observable<any> {
return this.http.delete<any>(`http://localhost:8080/api/deleteNote/${id}`);
}
}
src/app/service/program.service.ts
import { Injectable } form '@angular/core';
import { Observable } form 'rxjs';
import { HttpClient } form '@angular/common/http';
@Injectable({
providedIn: 'root'
})
export class ProgramService {
constructor(private http: HttpClient) { }
addProgram((data: any, id: number): Observable<any> {
return this.http.post<any>(`http://localhost:8080/api/addProgram/${id}`, data);
}
editProgram(data: any, id: number): Observable<any> {
return this.http.put<any>(`http://localhost:8080/api/editProgram/${id}`, data);
}
findProgram(id: number): Observable<any> {
return this.http.get<any>(`http://localhost:8080/api/findProgram/${id}`);
}
deleteProgram(id: number): Observable<any> {
return this.http.delete<any>(`http://localhost:8080/api/deleteProgram/${id}`);
}
}
src/app/service/room.service.ts
import { Injectable } form '@angular/core';
import { Observable } form 'rxjs';
import { HttpClient } form '@angular/common/http';
@Injectable({
providedIn: 'root'
})
export class RoomService {
constructor(private http: HttpClient) { }
addRoom((data: any, id: number): Observable<any> {
return this.http.post<any>(`http://localhost:8080/api/addRoom/${id}`, data);
}
editRoom(data: any, id: number): Observable<any> {
return this.http.put<any>(`http://localhost:8080/api/editRoom/${id}`, data);
}
findRoom(id: number): Observable<any> {
return this.http.get<any>(`http://localhost:8080/api/findRoom/${id}`);
}
deleteRoom(id: number): Observable<any> {
return this.http.delete<any>(`http://localhost:8080/api/deleteRoom/${id}`);
}
findRoomsForSchool(id: number): Observable<any> {
return this.http.get<any>(`http://localhost:8080/api/findRoomsForSchool/${id}`);
}
}
src/app/service/school.service.ts
import { Injectable } form '@angular/core';
import { Observable } form 'rxjs';
import { HttpClient } form '@angular/common/http';
@Injectable({
providedIn: 'root'
})
export class SchoolService {
constructor(private http: HttpClient) { }
addSchool((data: any): Observable<any> {
return this.http.post<any>(`http://localhost:8080/api/addSchool`, data);
}
editSchool(data: any, id: number): Observable<any> {
return this.http.put<any>(`http://localhost:8080/api/editSchool/${id}`, data);
}
findSchool(id: number): Observable<any> {
return this.http.get<any>(`http://localhost:8080/api/findSchool/${id}`);
}
deleteSchool(id: number): Observable<any> {
return this.http.delete<any>(`http://localhost:8080/api/deleteSchool/${id}`);
}
findSchools(): Observable<any> {
return this.http.get<any>(`http://localhost:8080/api/findSchools`);
}
}
src/app/service/schooling.service.ts
import { Injectable } form '@angular/core';
import { Observable } form 'rxjs';
import { HttpClient } form '@angular/common/http';
@Injectable({
providedIn: 'root'
})
export class SchoolingService {
constructor(private http: HttpClient) { }
addSchooling((data: any, id: number): Observable<any> {
return this.http.post<any>(`http://localhost:8080/api/addSchooling/${id}`, data);
}
editSchooling(data: any, id: number): Observable<any> {
return this.http.put<any>(`http://localhost:8080/api/editSchooling/${id}`, data);
}
findSchooling(id: number): Observable<any> {
return this.http.get<any>(`http://localhost:8080/api/findSchooling/${id}`);
}
deleteSchooling(id: number): Observable<any> {
return this.http.delete<any>(`http://localhost:8080/api/deleteSchooling/${id}`);
}
findSchoolingsForSchool(id: number): Observable<any> {
return this.http.get<any>(`http://localhost:8080/api/findSchoolingsForSchool/${id}`);
}
}
src/app/service/subject.service.ts
import { Injectable } form '@angular/core';
import { Observable } form 'rxjs';
import { HttpClient } form '@angular/common/http';
@Injectable({
providedIn: 'root'
})
export class SubjectService {
constructor(private http: HttpClient) { }
addSubject((data: any, id: number): Observable<any> {
return this.http.post<any>(`http://localhost:8080/api/addSubject/${id}`, data);
}
editSubject(data: any, id: number): Observable<any> {
return this.http.put<any>(`http://localhost:8080/api/editSubject/${id}`, data);
}
findSubject(id: number): Observable<any> {
return this.http.get<any>(`http://localhost:8080/api/findSubject/${id}`);
}
deleteSubject(id: number): Observable<any> {
return this.http.delete<any>(`http://localhost:8080/api/deleteSubject/${id}`);
}
findAllSubjectsForSchool(id: number): Observable<any> {
return this.http.get<any>(`http://localhost:8080/api/findAllSubjectsForSchool/${id}`);
}
findSubjectForExam(id: number): Observable<any> {
return this.http.get<any>(`http://localhost:8080/api/findSubjectForExam/${id}`);
}
findSubjectForCourse(id: number): Observable<any> {
return this.http.get<any>(`http://localhost:8080/api/findSubjectForCourse/${id}`);
}
findSubjectsForSchool(id: number): Observable<any> {
return this.http.get<any>(`http://localhost:8080/api/findSubjectsForSchool/${id}`);
}
}
Flat tree
The mat-tree provides a Material Design styled tree that can be used to display hierarchy data.
This tree builds on the foundation of the CDK tree and uses a similar interface for its data source input and template, except that its element and attribute selectors will be prefixed with mat- instead of cdk-.
There are two types of trees: Flat tree and nested tree. The DOM structures are different for these two types of trees.
In a flat tree, the hierarchy is flattened; nodes are not rendered inside of each other, but instead are rendered as siblings in sequence. An instance of TreeFlattener is used to generate the flat list of items from hierarchical data. The "level" of each tree node is read through the getLevel method of the TreeControl; this level can be used to style the node such that it is indented to the appropriate level.
src/app/service/tree-application.service.ts
import { Injectable } form '@angular/core' ;
import { ActivatedRoute } form '@angular/router' ;
import { BehaviorSubject, Observable } form 'rxjs' ;
import { School } form '../modal/Modal' ;
import { SchoolService } form './school.service' ;
export class NodeAction {
linkActive: string;
url: string;
title: string;
}
export class ApplicationItemNode {
children: ApplicationItemNode[] = [];
name: string;
id: number;
clazz: string;
actions: NodeAction[] = [];
title: string;
routerLink: any;
}
export class ApplicationItemFlatNode {
id: number;
item: string;
clazz: string;
level: number;
name: string;
expandable: boolean;
actions: NodeAction[] = [];
title: string;
routerLink: any;
}
@Injectable({
providedIn: 'root'
})
export class TreeApplicationService {
idSchool: any;
applicationData = new BehaviorSubject<ApplicationItemNode[]>([]);
applicationState = new BehaviorSubject<School>({} as School);
constructor(private route: ActivatedRoute, private schoolService: SchoolService) {
this.initialize();
}
initialize() {
this.idSchool = this.route.snapshot.params.idSchool;
this.applicationState.subscribe(() => {
this.buildFileTree(0).subscribe(value => {
this.applicationData.next(value);
});
});
this.buildFileTree(0).subscribe(value => {
this.applicationData.next(value);
});
}
get data(): ApplicationItemNode[] {
return this.applicationData.value;
}
buildFileTree(level: number): Observable<ApplicationItemNode[]> {
const nodes: ApplicationItemNode[] = [];
return new Observable((observer) => {
return this.schoolService.findSchool(this.idSchool).subscribe(school => {
const activityRoot = new ApplicationItemNode();
activityRoot.name = 'Activities';
activityRoot.title = 'More details';
activityRoot.clazz = 'fas fa-swimmer';
activityRoot.routerLink = '/find-school/' + school.id + '/find-activities';
nodes.push(activityRoot);
if(school.activities.length > 0) {
school.activities.forEach((activity) => {
const activityNodeRoot = new ApplicationItemNode();
activityNodeRoot.name = 'Activity ' + activity.type;
activityNodeRoot.title = 'Level details';
activityNodeRoot.clazz = 'fas fa-swimmer';
activityNodeRoot.routerLink = '/find-school/' + school.id + '/find-activity/' + activity.id;
activityRoot.children.push(activityNodeRoot);
});
}
const SubjectRoot = new ApplicationItemNode();
SubjectRoot.name = 'Subjects';
SubjectRoot.title = 'More details';
SubjectRoot.clazz = 'far fa-copy';
SubjectRoot.routerLink = '/find-school/' + school.id + '/find-subjects';
nodes.push(SubjectRoot);
if (school.subjects.length > 0 && Array.isArray(school.subjects)) {
school.subjects.forEach((subject) => {
const subjectNodeRoot = new ApplicationItemNode();
subjectNodeRoot.name = subject.name;
subjectNodeRoot.title = 'Parent details';
subjectNodeRoot.clazz = 'far fa-copy';
subjectNodeRoot.routerLink = '/find-school/' + school.id + '/find-subject/' + subject.id;
SubjectRoot.children.push(subjectNodeRoot);
if(subject.programs.length > 0) {
subject.programs.forEach((program) => {
const programNodeRoot = new ApplicationItemNode();
programNodeRoot.name = program.name;
programNodeRoot.clazz = 'fas fa-project-diagram';
programNodeRoot.routerLink = '/find-school/' + school.id + '/find-program/' + program.id;
subjectNodeRoot.children.push(programNodeRoot);
if(program.coefficients.length > 0) {
program.coefficients.forEach((coefficient) => {
const coefficientNodeRoot = new ApplicationItemNode();
coefficientNodeRoot.name = 'Coefficient = (' + coefficient.grade + ')';
coefficientNodeRoot.clazz = 'fas fa-not-equal';
coefficientNodeRoot.routerLink = '/find-school/' + school.id + '/find-coefficient/' + coefficient.id;
programNodeRoot.children.push(coefficientNodeRoot);
});
}
});
}
});
}
const examRoot = new ApplicationItemNode();
examRoot.name = 'Exams';
examRoot.title = 'More details';
examRoot.clazz = 'fas fa-book-open';
examRoot.routerLink = '/find-school/' + school.id + '/find-exams';
nodes.push(examRoot);
if(school.exams.length > 0) {
school.exams.forEach((exam) => {
const examNodeRoot = new ApplicationItemNode();
examNodeRoot.name = 'Date: ' + exam.date;
examNodeRoot.title = 'Level details';
examNodeRoot.clazz = 'fas fa-book-open';
examNodeRoot.routerLink = '/find-school/' + school.id + '/find-exam/' + exam.id;
examRoot.children.push(examNodeRoot);
if(exam.notes.length > 0) {
exam.notes.forEach((note, index) => {
const noteNodeRoot = new ApplicationItemNode();
const noteLength = index + 1;
noteNodeRoot.name = 'Note ' + noteLength;
noteNodeRoot.clazz = 'fas fa-book';
noteNodeRoot.routerLink = '/find-school/' + school.id + '/find-note/' + note.id;
examNodeRoot.children.push(noteNodeRoot);
});
}
});
}
const roomRoot = new ApplicationItemNode();
roomRoot.name = 'Rooms';
roomRoot.title = 'More details';
roomRoot.clazz = 'fas fa-university';
roomRoot.routerLink = '/find-school/' + school.id + '/find-rooms';
nodes.push(roomRoot);
if(school.rooms.length > 0) {
school.rooms.forEach((room) => {
const roomNodeRoot = new ApplicationItemNode();
roomNodeRoot.name = 'Room ' + room.code;
roomNodeRoot.title = 'Level details';
roomNodeRoot.clazz = 'fas fa-university';
roomNodeRoot.routerLink = '/find-school/' + school.id + '/find-room/' + room.id;
roomRoot.children.push(roomNodeRoot);
});
}
const yearRoot = new ApplicationItemNode();
yearRoot.name = 'Schoolings';
yearRoot.title = 'More details';
yearRoot.clazz = 'fas fa-calendar-alt';
yearRoot.routerLink = '/find-school/' + school.id + '/find-schoolings';
nodes.push(yearRoot);
if(school.schoolings.length > 0) {
school.schoolings.forEach((schooling) => {
const schoolingNodeRoot = new ApplicationItemNode();
schoolingNodeRoot.name = 'Year ' + schooling.year;
schoolingNodeRoot.title = 'Year details';
schoolingNodeRoot.clazz = 'fas fa-calendar-alt';
schoolingNodeRoot.routerLink = '/find-school/' + school.id + '/find-schoolling/' + schooling.id;
yearRoot.children.push(schoolingNodeRoot);
if (schooling.levels.length > 0) {
schooling.levels.forEach((level) => {
const levelNodeRoot = new ApplicationItemNode();
levelNodeRoot.name = level.label;
levelNodeRoot.title = 'More details';
levelNodeRoot.clazz = 'fas fa-swatchbook';
levelNodeRoot.routerLink = '/find-school/' + school.id + '/find-level/' + level.id;
schoolingNodeRoot.children.push(levelNodeRoot);
if(level.courses.length > 0) {
level.courses.forEach((course, index) => {
const courseNodeRoot = new ApplicationItemNode();
const courseLength = index + 1;
courseNodeRoot.name = 'Course: ' + courseLength;
courseNodeRoot.title = 'More details';
courseNodeRoot.clazz = 'fas fa-atlas';
courseNodeRoot.routerLink = '/find-school/' + school.id + '/find-course/' + course.id;
levelNodeRoot.children.push(courseNodeRoot);
});
}
});
}
});
}
observer.next(nodes);
})
});
}
}
Components
The @Component decorator identifies the class immediately below it as a component class, and specifies its metadata. In the example code below, you can see that Component is just a class, with no special Angular notation or syntax at all. It's not a component until you mark it as one with the @Component decorator.
The metadata for a component tells Angular where to get the major building blocks that it needs to create and present the component and its view. In particular, it associates a template with the component, either directly with inline code, or by reference. Together, the component and its template describe a view.
In addition to containing or pointing to the template, the @Component metadata configures, for example, how the component can be referenced in HTML and what services it requires.
The above files were created by default when we created new project using the angular-cli command.
We need to create these components
ng generate component add-activity
ng generate component add-coefficient
ng generate component add-course
ng generate component add-exam
ng generate component add-level-to-room
ng generate component add-level
ng generate component add-manager
ng generate component add-note
ng generate component add-program
ng generate component add-room
ng generate component add-school
ng generate component add-schooling
ng generate component add-subject
ng generate component dashboard
ng generate component display-school
ng generate component find-activities
ng generate component find-activity
ng generate component find-coefficient
ng generate component find-course
ng generate component find-exam
ng generate component find-exams
ng generate component find-level-to-room
ng generate component find-level
ng generate component find-note
ng generate component find-program
ng generate component find-room
ng generate component find-rooms
ng generate component find-school
ng generate component find-schooling
ng generate component find-schoolings
ng generate component find-subject
ng generate component find-subjects
ng generate component home
Add the AppRoutingModule
In Angular, the best practice is to load and configure the router in a separate, top-level module that is dedicated to routing and imported by the root AppModule.
By convention, the module class name is AppRoutingModule and it belongs in the app-routing.module.ts in the src/app folder.
app-routing-module.ts
src/app/app-routing.module.ts
import { NgModule } form '@angular/core';
import { Routes, RouterModule } form '@angular/router';
import { HomeComponent } form './home/home.component';
import { FindSchoolComponent } form './find-school/find-school.component';
import { DisplaySchoolComponent } form './display-school/display-school.component';
import { FindActivityComponent } form './find-activity/find-activity.component';
import { FindActivitiesComponent } form './find-activities/find-activities.component';
import { FindSchoolingsComponent } form './find-schoolings/find-schoolings.component';
import { FindSchoolingComponent } form './find-schooling/find-schooling.component';
import { FindRoomsComponent } form './find-rooms/find-rooms.component';
import { FindRoomComponent } form './find-room/find-room.component';
import { FindSubjectsComponent } form './find-subjects/find-subjects.component';
import { FindSubjectComponent } form './find-subject/find-subject.component';
import { FindProgramComponent } form './find-program/find-program.component';
import { FindCoefficientComponent } form './find-coefficient/find-coefficient.component';
import { FindExamsComponent } form './find-exams/find-exams.component';
import { FindExamComponent } form './find-exam/find-exam.component';
import { FindNoteComponent } form './find-note/find-note.component';
import { FindLevelComponent } form './find-level/find-level.component';
import { AddCourseComponent } form './add-course/add-course.component';
import { FindCourseComponent } form './find-course/find-course.component';
import { DashboardComponent } form './dashboard/dashboard.component';
const routes: Routes = [
{ path: '', redirectTo: '/home', pathMatch: 'full' },
{
path: 'home',
component: HomeComponent
},
{
path: 'find-school/:idSchool',
component: FindSchoolComponent,
children: [
{
path: '',
component: DashboardComponent
},
{
path: 'display-school/:idSchool',
component: DisplaySchoolComponent
},
{
path: 'find-activities',
component: FindActivitiesComponent
},
{
path: 'find-activity/:idActivity',
component: FindActivityComponent
},
{
path: 'find-schoolings',
component: FindSchoolingsComponent
},
{
path: 'find-schoolling/:idSchooling',
component: FindSchoolingComponent
},
{
path: 'find-rooms',
component: FindRoomsComponent
},
{
path: 'find-room/:idRoom',
component: FindRoomComponent
},
{
path: 'find-subjects',
component: FindSubjectsComponent
},
{
path: 'find-subject/:idSubject',
component: FindSubjectComponent
},
{
path: 'find-program/:idProgram',
component: FindProgramComponent
},
{
path: 'find-coefficient/:idCoefficient',
component: FindCoefficientComponent
},
{
path: 'find-exams',
component: FindExamsComponent
},
{
path: 'find-exam/:idExam',
component: FindExamComponent
},
{
path: 'find-note/:idNote',
component: FindNoteComponent
},
{
path: 'find-level/:idLevel',
component: FindLevelComponent
},
{
path: 'add-course/:idLevel',
component: AddCourseComponent
},
{
path: 'edit-course/:idCourse',
component: AddCourseComponent
},
{
path: 'find-course/:idCourse',
component: FindCourseComponent
}
]
}
];
@NgModule({
imports: [RouterModule.forRoot(routes)],
exports: [RouterModule]
})
export class AppRoutingModule { }
src/app/app.component.html
<style>
body {
margin: 0;
font-family: Arial, Helvetica, sans-serif;
}
.topnav {
overflow: hidden;
background-color: #333;
}
.topnav a {
float: left;
color: #f2f2f2;
text-align: center;
padding: 14px 16px;
text-decoration: none;
font-size: 17px;
}
.topnav a:hover {
background-color: #ddd;
color: black;
}
.topnav a.active {
background-color: #4CAF50;
color: white;
}
</style>
<div class="topnav">
<a class="active" href="/home">Home</;a>
<a href="#news">News</a>
<a href="#contact">Contact</a>
<a href="#about">About</a>
>/div>
<router-outlet>>/router-outlet>
src/app/home-component.ts
import { Component, OnInit } from '@angular/core';
import { MatDialog } from '@angular/material/dialog';
import { AddSchoolComponent } from '../add-school/add-school.component';
import { School } from '../modal/Modal';
import { SchoolService } from '../service/school.service';
@Component({
selector: 'app-home',
templateUrl: './home.component.html',
styleUrls: ['./home.component.css']
})
export class HomeComponent implements OnInit {
schools: School[];
constructor(private dialog: MatDialog, private schoolService: SchoolService) { }
ngOnInit(): void {
this.schoolService.findSchools().subscribe((schools) => {
this.schools = schools;
});
}
addSchool() {
const id = null;
this.dialog.open(AddSchoolComponent, {
data: {id},
height: '580px',
width: '400px',
});
}
}
Home Components
In home commnent we will display all school and add a new school
src/app/home-component.html
<div style="width: 30%; float:left">
<mat-card>
<mat-card-header>
<mat-card-title>Find all schools </mat-card-title>
</mat-card-header><hr>
<mat-card-content>
<mat-list *ngFor="let school of schools">
<mat-list-item>
<mat-icon mat-list-icon>school</mat-icon>
<div mat-line style="cursor: pointer; color: #73AD21;" [routerLink]="['/find-school/', school.id]">{{school.name}}</div>
<div mat-line style="color: #99a1a8;"> {{school.createdAt|date}} </div>
</mat-list-item>
<mat-divider></mat-divider>
</mat-list>
<h4 style="color: rgba(117, 114, 114, 0.87); margin-top: 240px; background: #f2f2f2; padding: 5px 10px;">All copy right reserved by issamdrmas</h4>
</mat-card-content>
</mat-card>
</div>
<div style="width: 70%; float:right">
<div style="margin: auto; width: 50%; border: 3px solid #73AD21; padding: 10px; margin-top: 40px;">
<mat-card>
<mat-card-header>
<mat-card-title>Welcome to gestion school</mat-card-title>
</mat-card-header><hr>
<mat-card-content>
<i class="fas fa-school" style="font-size: 200px; margin-left: 130px;"></i>
</mat-card-content><hr>
<mat-card-actions>
<button mat-raised-button color="warn" (click)="addSchool()">Add a new school</button>
</mat-card-actions>
</mat-card>
</div>
</div>
Dashboard Components
In dashboard commnent we will display the length of school, activity, subject, exam, room and schooling
src/app/dashboard-component.ts
import { Component, OnInit } from '@angular/core';
import { SchoolService } from '../service/school.service';
import { ActivityService } from '../service/activity.service';
import { ActivatedRoute } from '@angular/router';
import { SubjectService } from '../service/subject.service';
import { ExamService } from '../service/exam.service';
import { RoomService } from '../service/room.service';
import { SchoolingService } from '../service/schooling.service';
@Component({
selector: 'app-dashboard',
templateUrl: './dashboard.component.html',
styleUrls: ['./dashboard.component.css']
})
export class DashboardComponent implements OnInit {
schoolLength = 0;
activityLength = 0;
subjectLength = 0;
examsLength = 0;
roomLength = 0;
schoolingLength = 0;
constructor(private schoolService: SchoolService, private activityService: ActivityService,
private route: ActivatedRoute, private subjectService: SubjectService, private examService: ExamService,
private roomService: RoomService, private schoolingService: SchoolingService) { }
ngOnInit(): void {
const id = this.route.parent.snapshot.params.idSchool;
this.schoolService.findSchools().subscribe(schools => {
this.schoolLength = schools.length;
})
this.activityService.findActivitiesForSchool(id).subscribe(activities => {
this.activityLength = activities.length;
})
this.subjectService.findAllSubjectsForSchool(id).subscribe(subjects => {
this.subjectLength = subjects.length;
})
this.examService.findExamsForSchool(id).subscribe(exams => {
this.examsLength = exams.length;
})
this.roomService.findRoomsForSchool(id).subscribe(rooms => {
this.roomLength = rooms.length;
})
this.schoolingService.findSchoolingsForSchool(id).subscribe(schoolings => {
this.schoolingLength = schoolings.length;
})
}
}
src/app/dashboard-component.ts
<div id="container">
<div id="left">
<mat-card style="background-color: #9b59b6">
<mat-card-header>
<mat-card-title *ngIf="schoolLength>0">
<button mat-mini-fab disabled style="color: #ecf0f1">
{{schoolLength}}
</button>
</mat-card-title>
<mat-card-title *ngIf="schoolLength==0">
<button mat-mini-fab disabled style="color: #ecf0f1">
0
</button>
</mat-card-title>
<mat-card-subtitle style="font-weight: bold">Schools</mat-card-subtitle>
<mat-card-subtitle style="margin-top: -14px;">Total schools</mat-card-subtitle>
</mat-card-header>
<mat-divider></mat-divider>
<mat-card-actions>
<i class="fas fa-school"></i>
</mat-card-actions>
</mat-card>
</div>
<div id="center">
<mat-card style="background-color: #3498db">
<mat-card-header>
<mat-card-title *ngIf="activityLength>0">
<button mat-mini-fab disabled style="color: #ecf0f1">
{{activityLength}}
</button>
</mat-card-title>
<mat-card-title *ngIf="activityLength==0">
<button mat-mini-fab disabled style="color: #ecf0f1">
0
</button>
</mat-card-title>
<mat-card-subtitle style="font-weight: bold">Activities</mat-card-subtitle>
<mat-card-subtitle style="margin-top: -14px;">Total activities</mat-card-subtitle>
</mat-card-header>
<mat-divider></mat-divider>
<mat-card-actions>
<i class="fas fa-swimmer"></i>
</mat-card-actions>
</mat-card>
</div>
<div id="right">
<mat-card style="background-color: #e67e22">
<mat-card-header>
<mat-card-title *ngIf="subjectLength>0">
<button mat-mini-fab disabled style="color: #ecf0f1">
{{subjectLength}}
</button>
</mat-card-title>
<mat-card-title *ngIf="subjectLength==0">
<button mat-mini-fab disabled style="color: #ecf0f1">
0
</button>
</mat-card-title>
<mat-card-subtitle style="font-weight: bold">Subjects</mat-card-subtitle>
<mat-card-subtitle style="margin-top: -14px;">Total subjects</mat-card-subtitle>
</mat-card-header>
<mat-divider></mat-divider>
<mat-card-actions>
<i class="far fa-copy"></i>
</mat-card-actions>
</mat-card>
</div>
</div>
<div id="container">
<div id="left" style="margin-top: 20px !important;">
<mat-card style="background-color: #16a085">
<mat-card-header>
<mat-card-title *ngIf="examsLength>0">
<button mat-mini-fab disabled style="color: #ecf0f1">
{{examsLength}}
</button>
</mat-card-title>
<mat-card-title *ngIf="examsLength==0">
<button mat-mini-fab disabled style="color: #ecf0f1">
0
</button>
</mat-card-title>
<mat-card-subtitle style="font-weight: bold">Exams</mat-card-subtitle>
<mat-card-subtitle style="margin-top: -14px;">Total exams</mat-card-subtitle>
</mat-card-header>
<mat-divider></mat-divider>
<mat-card-actions>
<i class="fas fa-book-open"></i>
</mat-card-actions>
</mat-card>
</div>
<div id="center" style="margin-top: 20px !important;">
<mat-card style="background-color: #c0392b">
<mat-card-header>
<mat-card-title *ngIf="roomLength>0">
<button mat-mini-fab disabled style="color: #ecf0f1">
{{roomLength}}
</button>
</mat-card-title>
<mat-card-title *ngIf="roomLength==0">
<button mat-mini-fab disabled style="color: #ecf0f1">
0
</button>
</mat-card-title>
<mat-card-subtitle style="font-weight: bold">Rooms</mat-card-subtitle>
<mat-card-subtitle style="margin-top: -14px;">Total rooms</mat-card-subtitle>
</mat-card-header>
<mat-divider></mat-divider>
<mat-card-actions>
<i class="far fa-hospital"></i>
</mat-card-actions>
</mat-card>
</div>
<div id="right" style="margin-top: 20px !important;">
<mat-card style="background-color: #7f8c8d">
<mat-card-header>
<mat-card-title *ngIf="schoolingLength>0">
<button mat-mini-fab disabled style="color: #ecf0f1">
{{schoolingLength}}
</button>
</mat-card-title>
<mat-card-title *ngIf="schoolingLength==0">
<button mat-mini-fab disabled style="color: #ecf0f1">
0
</button>
</mat-card-title>
<mat-card-subtitle style="font-weight: bold">Schoolings</mat-card-subtitle>
<mat-card-subtitle style="margin-top: -14px;">Total schoolings</mat-card-subtitle>
</mat-card-header>
<mat-divider></mat-divider>
<mat-card-actions>
<i class="fas fa-calendar-alt"></i>
</mat-card-actions>
</mat-card>
</div>
</div>
src/app/dashboard-component.css
#container
{
width:100%;
}
#left, #center, #right
{
width:32%;
float:left;
text-align:center;
}
#center
{
overflow:hidden;
margin: 0 1%;
}
mat-card-title,
mat-card-subtitle {
padding-left: 80px;
color: #ecf0f1;
}
#container i {
font-size: 40px;
color: #ecf0f1;
}
Find Activities Components
In find activities commnent we can display all activities
src/app/school/find-activities.component.html
<mat-card class="example-card">
<mat-card-content style="margin: 16px;">
<img mat-card-image src="https://blogsimages.adobe.com/creative/files/2019/06/Fotolia_224946995_M-1.jpg"
alt="photo">
</mat-card-content>
</mat-card>
Find school Components
In find school commnent We can display all information in tree like list
src/app/find-school.ts
import { Component, OnInit } from '@angular/core';
import { ActivatedRoute } from '@angular/router';
import { School } from '../model/Model';
import { SchoolService } from '../service/school.service';
import { FlatTreeControl } from '@angular/cdk/tree';
import { MatDialog } from '@angular/material/dialog';
import { MatTreeFlattener, MatTreeFlatDataSource } from '@angular/material/tree';
import { AddSchoolComponent } from '../add-school/add-school.component';
import { ApplicationItemFlatNode, ApplicationItemNode, TreeApplicationService } from '../service/tree-application.service';
@Component({
selector: 'app-find-school',
templateUrl: './find-school.component.html',
styleUrls: ['./find-school.component.css'],
providers: [TreeApplicationService]
})
export class FindSchoolComponent implements OnInit {
school: School = {} as School;
idSchool: number;
flatNodeMap = new Map<ApplicationItemFlatNode, ApplicationItemNode>();
nestedNodeMap = new Map<ApplicationItemNode, ApplicationItemFlatNode>();
treeControl: FlatTreeControl<ApplicationItemFlatNode>;
treeFlattener: MatTreeFlattener<ApplicationItemNode, ApplicationItemFlatNode>;
dataSource: MatTreeFlatDataSource<ApplicationItemNode, ApplicationItemFlatNode>;
expandedNodes: ApplicationItemFlatNode[];
constructor(private route: ActivatedRoute, private schoolService: SchoolService, private dialog: MatDialog,
private treeApplicationService: TreeApplicationService) {
this.route.params.subscribe(
params => {
this.idSchool = this.route.snapshot.params.idSchool;
this.treeFlattener = new MatTreeFlattener(this.transform, this.getLevel, this.isExpandable, this.getChildren);
this.treeControl = new FlatTreeControl<ApplicationItemFlatNode>(this.getLevel, this.isExpandable);
this.dataSource = new MatTreeFlatDataSource(this.treeControl, this.treeFlattener);
this.saveExpandedNodes();
this.restoreExpandedNodes();
treeApplicationService.applicationData.subscribe(school => {
this.dataSource.data = school;
});
this.treeApplicationService.applicationState.next(this.school);
this.schoolService.findSchool(this.idSchool).subscribe((school) => {
this.school = school;
})
}
)
}
ngOnInit(): void {}
getLevel = (node: ApplicationItemFlatNode) => node.level;
isExpandable = (node: ApplicationItemFlatNode) => node.expandable;
getChildren = (node: ApplicationItemNode): ApplicationItemNode [] => node.children;
hasChild = (_: number, nodeDate: ApplicationItemFlatNode) => nodeDate.expandable;
hasNoContent = (_: number, nodeData: ApplicationItemFlatNode) => nodeData.item === '';
transform = (node: ApplicationItemNode, level: number) => {
const existingNode = this.nestedNodeMap.get(node);
const flatNode = existingNode && existingNode.name === node.name ? existingNode : new ApplicationItemFlatNode();
flatNode.name = node.name;
flatNode.id = node.id;
flatNode.clazz = node.clazz;
flatNode.level = level;
flatNode.title = node.title;
flatNode.routerLink = node.routerLink;
flatNode.actions = node.actions;
flatNode.expandable = (node.children && node.children.length > 0);
this.flatNodeMap.set(flatNode, node);
this.nestedNodeMap.set(node, flatNode);
return flatNode;
}
private saveExpandedNodes() {
if(this.treeControl && this.treeControl.dataNodes) {
this.expandedNodes = new Arrayalt;ApplicationItemFlatNode>();
this.treeControl.dataNodes.forEach(node => {
if(node.expandable && this.treeControl.isExpanded(node)) {
this.expandedNodes.push(node);
}
});
}
}
private restoreExpandedNodes() {
if(this.expandedNodes && this.expandedNodes.length > 0) {
this.expandedNodes.forEach(node => {
this.treeControl.expand(this.treeControl.dataNodes.find(n => n.id === node.id));
});
}
}
deleteSchool() {
if(confirm('Are you sure')) {
this.schoolService.deleteSchool(this.idSchool).subscribe(() => {
window.location.replace('/home');
})
}
}
editSchool(id: number) {
this.dialog.open(AddSchoolComponent, {
data: {id},
height: '580px',
width: '400px',
});
}
}
src/app/find-school.html
<div style="width: 30%; float:left">
<mat-card>
<mat-card-header>
<mat-card-title> {{school.name}} </mat-card-title>
<mat-card-subtitle>{{school.createdAt|date}}</mat-card-subtitle>
</mat-card-header>
<hr>
<mat-card-content>
<mat-list-item><i class="fas fa-th-list" style="margin: 0 15px 0 10px;"></i>
<a style="color: #4CAF50;" [routerLink]="['/find-school/', school.id]" routerLinkActive="router-link-active" >Dashbaord</a></mat-list-item>
<mat-tree [dataSource]="dataSource" [treeControl]="treeControl">
<mat-tree-node *matTreeNodeDef="let node" matTreeNodePadding matTreeNodeToggle>
<mat-basic-chip class="checklist-leaf-node root" [routerLink]="[node.routerLink]"
routerLinkActive="linkActive">
<a title="{{node.title}}">
<i [ngClass]="node.clazz" style="margin-right: 5px; color: #666a6c;"></i>
{{node.name}}
</a>
</mat-basic-chip>
</mat-tree-node>
<mat-tree-node *matTreeNodeDef="let node; when: hasChild" matTreeNodePadding>
<span [attr.aria-label]="'toggle ' + node.filename" id="chevronIcon" matTreeNodeToggle
style="background: transparent;">
<mat-icon class="mat-icon-rtl-mirror" id="mat-icon-plus">
{{treeControl.isExpanded(node) ? 'arrow_drop_down' : 'arrow_right'}}
</mat-icon>
</span>
<mat-basic-chip class="root" [routerLink]="[node.routerLink]" routerLinkActive="linkActive">
<a title="{{node.title}}">
<i [ngClass]="node.clazz" style="margin-right: 5px; color: #666a6c;"></i>
{{node.name}}
</a>
</mat-basic-chip>
</mat-tree-node>
</mat-tree>
</mat-card-content>
<mat-card-actions>
<button mat-raised-button color="primary" (click)="editSchool(school.id)">Update school</button>
<button mat-raised-button color="warn" (click)="deleteSchool()">Delete school</button>
<button mat-raised-button [routerLink]="['/find-school/' + school.id + '/display-school/', school.id]">School details</button>
</mat-card-actions>
</mat-card>
</div>
<div style="width: 68%; float:right; margin-top: 30px; padding: 1%;">
<router-outlet></router-outlet>
</div>
src/app/find-school.css
.full-height {
background: #f1f2f6;
}
.root {
width: 100%;
font-size: 16px;
display: block;
background: #f5f6fa;
padding: 0 10px;
border-radius: 4px;
}
a {
font-family: initial;
color: #2f3542;
text-decoration: none;
}
#mat-icon-plus {
color: #666a6c;
font-size: 24px;
margin-top: 4px;
}
.root:hover {
-webkit-transition: all .4s ease-in-out;
-moz-transition: all .4s ease-in-out;
transition: all .4s ease-in-out;
cursor: pointer;
}
#chevronIcon {
cursor: pointer;
}
.mat-tree-node {
margin-bottom: -15px;
}
h2 {
background: #e58e26;
padding: 0 16px;
border-radius: 5px;
}
.linkActive {
background-color: #bcffb6 !important;
padding: 2px 10px 0 3px;
border-top-right-radius: 5px;
border-bottom-right-radius: 5px;
color: #a94442 !important;
-webkit-transition: all .4s ease-in-out;
-moz-transition: all .4s ease-in-out;
transition: all .4s ease-in-out;
}
.content-logo {
padding-top: 15px;
padding-left: 30px;
margin-bottom: 10px;
}
.content-logo .fa-user-graduate {
font-size: 24px;
color: #2d3436;
}
Find Subjects Components
In find subjects commnent we can display all subjects
src/app/school/find-subjects.component.html
<mat-card class="example-card">
<mat-card-content style="margin: 16px;">
<img mat-card-image src="https://i.ytimg.com/vi/AnZxeX_8mVk/maxresdefault.jpg"
alt="photo">
</mat-card-content>
</mat-card>
Find Exams Components
In find subjects commnent we can display all exams
src/app/school/find-exams.component.html
<mat-card class="example-card">
<mat-card-content style="margin: 16px;">
<img mat-card-image src="https://static01.nyt.com/images/2020/11/22/magazine/22Ethicist/22Ethicist-superJumbo.jpg"
alt="photo">
</mat-card-content>
</mat-card>
Find Rooms Components
In find rooms commnent we can display all rooms
src/app/school/find-rooms.component.html
<mat-card class="example-card">
<mat-card-content style="margin: 16px;">
<img mat-card-image src="https://thumbs.dreamstime.com/b/illustration-du-vecteur-concept-d-encadrement-professionnel-chef-%C3%A9quipe-promotion-des-employ%C3%A9s-cours-de-perfectionnement-156525531.jpg"
alt="photo">
</mat-card-content>
</mat-card>
Find Schoolings Components
In find schoolings commnent we can display all schoolings
src/app/school/find-schoolings.component.html
<mat-card class="example-card">
<mat-card-content style="margin: 16px;">
<img mat-card-image src="https://i.ytimg.com/vi/AnZxeX_8mVk/maxresdefault.jpg"
alt="photo">
</mat-card-content>
</mat-card>
Add School Components
In add school commnent we can add a new school
src/app/add-school-component.ts
import { Component, Inject, OnInit } from '@angular/core';
import { MAT_DIALOG_DATA } from '@angular/material/dialog';
import { School } from '../modal/Modal';
import { SchoolService } from '../service/school.service';
@Component({
selector: 'app-add-school',
templateUrl: './add-school.component.html',
styleUrls: ['./add-school.component.css']
})
export class AddSchoolComponent implements OnInit {
progressBar = false;
school: School = {} as School;
constructor(private schoolService: SchoolService, @Inject(MAT_DIALOG_DATA) private data: any) {}
ngOnInit(): void {
if(this.data.id != null) {
this.schoolService.findSchool(this.data.id).subscribe((school) => {
this.school = school;
});
}
}
addSchool() {
this.progressBar = true;
if(this.data.id != null) {
this.schoolService.editSchool(this.school, this.data.id).subscribe((school) => {
this.school = school;
window.location.reload();
});
} else {
this.schoolService.addSchool(this.school).subscribe((school) => {
this.school = school;
window.location.reload();
});
}
}
}
src/app/add-school-component.html
<div style="margin: auto; width: 100%; border: 3px solid #73AD21;">
<mat-card>
<mat-card-header>
<mat-card-title>Add a new school</mat-card-title>
</mat-card-header>
<mat-card-content><br>
<mat-progress-bar mode="buffer" *ngIf="progressBar"></mat-progress-bar>
<form>
<mat-form-field appearance=fill style="width: 100%;">
<mat-label>Enter name</mat-label>
<input matInput type="text" placeholder="name" name="name" [(ngModel)]="school.name" #name="ngModel" required>
</mat-form-field><br>
<mat-form-field appearance=fill style="width: 100%;">
<mat-label>Enter city</mat-label>
<input matInput type="text" placeholder="city" name="city" [(ngModel)]="school.city" #city="ngModel" required>
</mat-form-field><br>
<mat-form-field appearance=fill style="width: 100%;">
<mat-label>Enter department</mat-label>
<input matInput type="text" placeholder="department" name="department" [(ngModel)]="school.department"
#department="ngModel" required>
</mat-form-field><br>
<mat-form-field>
<mat-label>Enter open</mat-label>
<input type="time" matInput placeholder="open" name="open" [(ngModel)]="school.open" #open="ngModel" required>
</mat-form-field> <br>
<mat-form-field>
<mat-label>Enter close</mat-label>
<input type="time" matInput placeholder="close" name="close" [(ngModel)]="school.close" #close="ngModel"
required>
</mat-form-field> <br>
<mat-form-field style="width: 100%;">
<mat-label>Enter description</mat-label>
<textarea matInput placeholder="Description" name="description" [(ngModel)]="school.description"
#description="ngModel"></textarea>
</mat-form-field><br>
<button mat-raised-button color="primary"
[disabled]="name.invalid || city.invalid || description.invalid || department.invalid || open.invalid || close.invalid"
(click)="addSchool()" style="width: 10em !important">Save</button>
</form>
</mat-card-content>
</mat-card>
</div>
Display School Components
In Display school commnent We will display the school information open time and close time or update/delete. We can also add a new activity, subject, exam, room and schooling
src/app/display-school-component.ts
import { Component, OnInit } from '@angular/core';
import { ActivatedRoute } from '@angular/router';
import { MatDialog } from '@angular/material/dialog';
import { AddActivityComponent } from '../add-activity/add-activity.component';
import { AddManagerComponent } from '../add-manager/add-manager.component';
import { School, Manager } from '../modal/Modal';
import { ManagerService } from '../service/manager.service';
import { SchoolService } from '../service/school.service';
import { AddSchoolingComponent } from '../add-schooling/add-schooling.component';
import { AddRoomComponent } from '../add-room/add-room.component';
import { AddSubjectComponent } from '../add-subject/add-subject.component';
import { AddExamComponent } from '../add-exam/add-exam.component';
@Component({
selector: 'app-display-school',
templateUrl: './display-school.component.html',
styleUrls: ['./display-school.component.css']
})
export class DisplaySchoolComponent implements OnInit {
school: School = {} as School;
manager: Manager = {} as Manager;
idSchool: number;
constructor(private route: ActivatedRoute, private schoolService: SchoolService, private dialog: MatDialog,
private managerService: ManagerService) {
this.route.params.subscribe(
params => {
this.idSchool = this.route.snapshot.params.idSchool;
this.schoolService.findSchool(this.idSchool).subscribe((school) => {
this.school = school;
if(this.manager!=null) {
this.managerService.findManagerForSchool(this.idSchool).subscribe((manager) => {
this.manager = manager
})
}
})
})
}
ngOnInit(): void {}
addManager(id: number) {
this.dialog.open(AddManagerComponent, {
data: {id},
height: '320px',
width: '400px',
});
}
editManager(idManager: number) {
this.dialog.open(AddManagerComponent, {
data: {idManager},
height: '320px',
width: '400px',
});
}
deleteManager(idManager: number, idSchool: number) {
if(confirm('Are you sur')) {
this.managerService.deleteManager(idManager, idSchool).subscribe(() => {
window.location.reload();
})
}
}
addSchoolling(idSchool: number) {
this.dialog.open(AddActivityComponent, {
data: {idSchool},
height: '600px',
width: '400px',
});
}
addActivity(idSchool: number) {
this.dialog.open(AddSchoolingComponent, {
data: {idSchool},
height: '300px',
width: '400px',
});
}
addRoom(idSchool: number) {
this.dialog.open(AddRoomComponent, {
data: {idSchool},
height: '370px',
width: '400px',
});
}
addSubject(idSchool: number) {
this.dialog.open(AddSubjectComponent, {
data: {idSchool},
height: '620px',
width: '400px',
});
}
addExam(idSchool: number) {
this.dialog.open(AddExamComponent, {
data: {idSchool},
height: '480px',
width: '400px',
});
}
}
src/app/display-school-component.html
<mat-card>
<mat-card-header>
<mat-card-title>Welcome to {{school.name}} </mat-card-title>
<mat-card-subtitle>{{school.createdAt|date}}</mat-card-subtitle>
</mat-card-header><hr>
<mat-card-content>
<mat-list>
<mat-list-item>
<div mat-line style="color: #222f3e;">
<h2 *ngIf="manager!=null">Manager: {{manager.firstName}} {{manager.lastName}}
<span class="material-icons" (click)="deleteManager(manager.id, school.id)"
style="cursor: pointer; color: #c0392b;">close</span>
</h2>
</div>
<div mat-line style="color: #222f3e;">City: {{school.city}}</div>
<div mat-line style="color: #222f3e;">Department: {{school.department}}</div>
</mat-list-item>
</mat-list><</br>
<mat-chip-list cdkDropList cdkDropListOrientation="horizontal">
<mat-chip>Open: {{school.open}} </mat-chip>
<mat-chip>Close: {{school.close}} </mat-chip>
</mat-chip-list>
<p style="background: #f5f6fa; padding: 10px; border-radius: 5px; color: #444;">
{{school.description}}
</p>
</mat-card-content><hr>
<mat-card-actions><br>
<button mat-stroked-button color="accent" (click)="editManager(manager.id)" *ngIf="manager!=null">Edit the manager</button>
<button mat-stroked-button color="accent" (click)="addManager(school.id)" *ngIf="manager==null">Add a manager</button>
<button mat-stroked-button color="primary" (click)="addActivity(school.id)">Add an activity</button>
<button mat-stroked-button color="primary" (click)="addSchoolling(school.id)">Add a schooling</button>
<button mat-stroked-button color="primary" (click)="addRoom(school.id)">Add a room</button>
<button mat-stroked-button color="primary" (click)="addSubject(school.id)">Add a subject</button>
<button mat-stroked-button color="primary" (click)="addExam(school.id)">Add an exam</button>
</mat-card-actions>
</mat-card>
Add Manager Components
In add manager commnent we can add a new manager for each school
src/app/add-manager-component.ts
import { Component, Inject, OnInit } from '@angular/core';
import { MAT_DIALOG_DATA } from '@angular/material/dialog';
import { Manager } from '../model/Model';
import { ManagerService} from '../service/manager.service';
@Component({
selector: 'app-add-manager',
templateUrl: './add-manager.component.html',
styleUrls: ['./add-manager.component.css']
})
export class AddManagerComponent implements OnInit {
progressBar = false;
manager: Manager = {} as Manager;
constructor(private managerService: ManagerService, @Inject(MAT_DIALOG_DATA) private data: any) { }
ngOnInit(): void {
if(this.data.idManager!=null) {
this.managerService.findManager(this.data.idManager).subscribe((manager) => {
this.manager = manager;
})
}
}
addManager() {
this.progressBar = true;
if(this.data.idManager!=null) {
this.managerService.editManager(this.manager, this.data.idManager).subscribe((manager) => {
this.manager = manager;
window.location.reload()
})
} else {
this.managerService.addManager(this.manager, this.data.id).subscribe((manager) => {
this.manager = manager;
window.location.reload()
})
}
}
}
src/app/add-manager-component.html
<div style="margin: auto; width: 100%; border: 3px solid #73AD21;">
<mat-card=>
<mat-card-header>
<mat-card-title>Add a new manager</mat-card-title>
</mat-card-header>
<mat-card-content><br>
<mat-progress-bar mode="buffer" *ngIf="progressBar"></mat-progress-bar>
<form>
<mat-form-field appearance= fill style="width: 100%;">
<mat-label>Enter firstName</mat-label>
<input matInput type="text" placeholder="firstName" name="firstName" [(ngModel)]="manager.firstName" #firstName="ngModel" required>
</mat-form-field><br>
<mat-form-field appearance= fill style="width: 100%;">
<mat-label>Enter lastName</mat-label>
<input matInput type="text" placeholder="lastName" name="lastName" [(ngModel)]="manager.lastName" #lastName="ngModel" required>
</mat-form-field><br>
<button mat-raised-button color="primary"
[disabled]="firstName.invalid || lastName.invalid"
(click)="addManager()" style="width: 10em !important">Save</button>
</form>
</mat-card-content>
</mat-card=
</div>
Add Activity Components
In add activity commnent we can add a new activity for each school
src/app/add-activity-component.ts
import { Component, Inject, OnInit } from '@angular/core';
import { MAT_DIALOG_DATA } from '@angular/material/dialog';
import { Activity } from '../model/Model';
import { ActivityService } from '../service/activity.service';
@Component({
selector: 'app-add-activity',
templateUrl: './add-activity.component.html',
styleUrls: ['./add-activity.component.css']
})
export class AddActivityComponent implements OnInit {
progressBar = false;
activity: Activity = {} as Activity;
weekDay: any = {};
constructor(private activityService: ActivityService, @Inject(MAT_DIALOG_DATA) private data: any) {}
ngOnInit(): void {
if(this.data.idActivity) {
this.activityService.findActivity(this.data.idActivity).subscribe((activity) => {
this.activity = activity;
});
}
}
onSelectedDay() {
this.activity.day = this.weekDay;
}
onDateTime(e) {
this.activity.date = e.target.value;
}
addActivity() {
this.progressBar = true;
if(this.data.idActivity) {
this.activityService.editActivity(this.activity, this.data.idActivity).subscribe((activity) => {
this.activity = activity;
window.location.reload();
});
} else {
this.activityService.addActivity(this.activity, this.data.idSchool).subscribe((activity) => {
this.activity = activity;
window.location.reload();
});
}
}
}
src/app/add-activity-component.html
<div style="margin: auto; width: 100%; border: 3px solid #73AD21;">
<mat-card>
<mat-card-header>
<mat-card-title>Add a new activity</mat-card-title>
</mat-card-header>
<mat-card-content><br>
<mat-progress-bar mode="buffer" *ngIf="progressBar"></mat-progress-bar>
<form>
<mat-form-field appearance="fill" style="width: 100%;">
<mat-label>Enter type</mat-label>
<input matInput type="text" placeholder="type" name="type"
[(ngModel)]="activity.type" #type="ngModel" required>
</mat-form-field><br>
<div style="margin-bottom: 15px;">
<strong>Day</strong>
</div>
<mat-radio-group [(ngModel)]="weekDay" name="weekDay" (change)="onSelectedDay()">
<mat-radio-button value="Monday">Monday</mat-radio-button>
<mat-radio-button value="Tuesday">Tesday</mat-radio-button>
<mat-radio-button value="Wednesday">Wendesday</mat-radio-button>
<mat-radio-button value="Thursday">Thursday</mat-radio-button>
<mat-radio-button value="Friday">Friday</mat-radio-button>
</mat-radio-group> <hr>
<mat-form-field style="width: 100%;">
<input matInput type="date" name="date" min="minDate"
[(ngModel)]="activity.date" #date="ngModel" required (change)="onDateTime($event)">
</mat-form-field> <br>
<mat-form-field style="width: 100%;">
<mat-label>START</mat-label>
<input matInput type="time" placeholder="startTime" name="startTime"
[(ngModel)]="activity.startDate" #startTime="ngModel" required>
</mat-form-field> <br>
<mat-form-field style="width: 100%;">
<mat-label>END</mat-label>
<input matInput type="time" placeholder="endTime" name="endTime"
[(ngModel)]="activity.endDate" #endTime="ngModel" required>
</mat-form-field> <br>
<mat-form-field style="width: 100%;">
<mat-label>Enter description</mat-label>
<textarea matInput placeholder="Description" name="description" [(ngModel)]="activity.description"
#description="ngModel"></textarea>
</mat-form-field><br>
<button mat-raised-button color="primary"
[disabled]="type.invalid || description.invalid
|| startTime.invalid || endTime.invalid"
(click)="addActivity()" style="width: 10em !important">Save</button>
</form>
</mat-card-content>
</mat-card>
</div>
Add schooling Components
In add schooling commnent we can add a new schooling for each school
src/app/add-schooling-component.ts
import { Component, Inject, OnInit } from '@angular/core';
import { MAT_DIALOG_DATA } from '@angular/material/dialog';
import { Schooling } from '../model/Model';
import { SchoolingService } from '../service/schooling.service';
@Component({
selector: 'app-add-schooling',
templateUrl: './add-schooling.component.html',
styleUrls: ['./add-schooling.component.css']
})
export class AddSchoolingComponent implements OnInit {
progressBar = false;
schooling: Schooling = {} as Schooling;
constructor(private schoolingService: SchoolingService, @Inject(MAT_DIALOG_DATA) private data: any) { }
ngOnInit(): void {
if (this.data.idSchooling!=null) {
this.schoolingService.findSchooling(this.data.idSchooling).subscribe(schooling => {
this.schooling = schooling;
})
}
}
addSchoolling() {
this.progressBar = true;
if (this.data.idSchooling!=null) {
this.schoolingService.editSchooling(this.schooling, this.data.idSchooling).subscribe(schooling => {
this.schooling = schooling;
window.location.reload();
})
} else {
this.schoolingService.addSchooling(this.schooling, this.data.idSchool).subscribe(schooling => {
this.schooling = schooling;
window.location.reload();
})
}
}
}
src/app/add-schooling-component.html
<div style="margin: auto; width: 100%; border: 3px solid #73AD21;">
<mat-card>
<mat-card-header>
<mat-card-title>Add a new schoolling</mat-card-title>
</mat-card-header>
<mat-card-content><br>
<mat-progress-bar mode="buffer" *ngIf="progressBar"></mat-progress-bar>
<form>
<mat-form-field style="width: 100%;">
<mat-label>Year</mat-label>
<input matInput type="number" placeholder="Year" name="year"
[(ngModel)]="schooling.year" #year="ngModel" required>
</mat-form-field> <br>
<mat-form-field style="width: 100%;">
<mat-label>Enter description</mat-label>
<textarea matInput placeholder="Description" name="description" [(ngModel)]="schooling.description"
#description="ngModel"></textarea>
</mat-form-field><br>
<button mat-raised-button color="primary"
[disabled]="year.invalid || description.invalid"
(click)="addSchoolling()" style="width: 10em !important">Save</button>
</form>
</mat-card-content>
</mat-card>
</div>
Add room Components
In add room commnent we can add a new room for each school
src/app/add-room-component.ts
import { Component, Inject, OnInit } from '@angular/core';
import { MAT_DIALOG_DATA } from '@angular/material/dialog';
import { Room } from '../model/Model';
import { RoomService } from '../service/room.service';
@Component({
selector: 'app-add-room',
templateUrl: './add-room.component.html',
styleUrls: ['./add-room.component.css']
})
export class AddRoomComponent implements OnInit {
progressBar = false;
room: Room = {} as Room;
constructor(private roomService: RoomService, @Inject(MAT_DIALOG_DATA) private data: any) { }
ngOnInit(): void {
if(this.data.idRoom !=null) {
this.roomService.findRoom(this.data.idRoom).subscribe(room => {
this.room = room;
})
}
}
addRoom() {
this.progressBar = true;
if(this.data.idRoom !=null ) {
this.roomService.editRoom(this.room, this.data.idRoom ).subscribe(room => {
this.room = room;
window.location.reload();
})
} else {
this.roomService.addRoom(this.room, this.data.idSchool).subscribe(room => {
this.room = room;
window.location.reload();
})
}
}
}
src/app/add-room-component.html
<div style="margin: auto; width: 100%; border: 3px solid #73AD21;">
<mat-card>
<mat-card-header>
<mat-card-title>Add a new room</mat-card-title>
</mat-card-header>
<mat-card-content><br>
<mat-progress-bar mode="buffer" *ngIf="progressBar"></mat-progress-bar>
<form>
<mat-form-field style="width: 100%;">
<mat-label>Code</mat-label>
<input matInput type="text" placeholder="Code" name="code"
[(ngModel)]="room.code" #code="ngModel" required>
</mat-form-field> <br>
<mat-form-field style="width: 100%;">
<mat-label>Capacity</mat-label>
<input matInput type="number" placeholder="Capacity" name="capacity"
[(ngModel)]="room.capacity" #capacity="ngModel" required>
</mat-form-field> <br>
<mat-form-field style="width: 100%;">
<mat-label>Enter description</mat-label>
<textarea matInput placeholder="Description" name="description"
[(ngModel)]="room.description" #description="ngModel"></textarea>
</mat-form-field><br>
<button mat-raised-button color="primary"
[disabled]="capacity.invalid || description.invalid
|| code.invalid"
(click)="addRoom()" style="width: 10em !important">Save</button>
</form>
</mat-card-content>
</mat-card>
</div>
Add subject Components
In add subject commnent we can add a new subject for each school
src/app/add-subject-component.ts
import { Component, Inject, OnInit } from '@angular/core';
import { MAT_DIALOG_DATA } from '@angular/material/dialog';
import { Subject } from '../model/Model';
import { SubjectService } from '../service/subject.service';
@Component({
selector: 'app-add-subject',
templateUrl: './add-subject.component.html',
styleUrls: ['./add-subject.component.css']
})
export class AddSubjectComponent implements OnInit {
progressBar = false;
subject: Subject = {} as Subject;
public arrayColors: any = {
color1: '#f8c291',
color2: '#d1f28e',
color3: 'rgb(255,245,0)',
color4: 'rgb(236,64,64)',
color5: 'rgba(45,208,45,1)'
};
color1: '#d1f28e';
public selectedColor = 'color2';
constructor(private subjectService: SubjectService, @Inject(MAT_DIALOG_DATA) private data: any) { }
ngOnInit(): void {
if(this.data.idSubject!=null) {
this.subjectService.findSubject(this.data.idSubject).subscribe(subject => {
this.subject = subject;
})
}
}
updateColor(event) {
this.color1 = event;
this.subject.color = this.color1;
}
addMatter() {
this.progressBar = true;
if(this.data.idSubject!=null) {
this.subjectService.editSubject(this.subject, this.data.idSubject).subscribe(subject => {
this.subject = subject;
window.location.reload();
})
} else {
this.subjectService.addSubject(this.subject, this.data.idSchool).subscribe(subject => {
this.subject = subject;
window.location.reload();
})
}
}
}
src/app/add-subject-component.html
<div style="margin: auto; width: 100%; border: 3px solid #73AD21;">
<mat-card>
<mat-card-header>
<mat-card-title>Add a new subject</mat-card-title>
</mat-card-header>
<mat-card-content><br>
<mat-progress-bar mode="buffer" *ngIf="progressBar"></mat-progress-bar>
<form>
<mat-form-field style="width: 100%;">
<mat-label>Name</mat-label>
<input matInput type="text" placeholder="Name" name="name"
[(ngModel)]="subject.name" #name="ngModel" required>
</mat-form-field> <br>
<mat-form-field style="width: 100%;">
<mat-label>Description</mat-label>
<textarea matInput placeholder="Description" name="description"
[(ngModel)]="subject.description" #description="ngModel" required></textarea>
</mat-form-field>
<div>
<span [style.background]="arrayColors[selectedColor]"
[cpToggle]="true"
[cpDialogDisplay]="'inline'"
[cpCancelButton]="true"
[(colorPicker)]="arrayColors[selectedColor]"
(colorPickerChange)="updateColor($event)" ></span>
</div><br>
<button mat-raised-button color="primary"
[disabled]="name.invalid || description.invalid"
(click)="addMatter()" style="width: 10em !important">Save</button>
</form>
</mat-card-content>
</mat-card>
</div>
Add exam Components
In add exam commnent we can add a new exam for each school
src/app/add-exam-component.ts
import { Component, Inject, OnInit } from '@angular/core';
import { MAT_DIALOG_DATA } from '@angular/material/dialog';
import { Exam, Subject } from '../model/Model';
import { ExamService } from '../service/exam.service';
import { dashCaseToCamelCase } from '@angular/compiler/src/util';
import { SubjectService } from '../service/subject.service';
@Component({
selector: 'app-add-exam',
templateUrl: './add-exam.component.html',
styleUrls: ['./add-exam.component.css']
})
export class AddExamComponent implements OnInit {
progressBar = false;
exam: Exam = {} as Exam;
idSubject: number;
subjects: Subject[];
subject: Subject = {} as Subject;
constructor(private examService: ExamService, private subjectService: SubjectService,
@Inject(MAT_DIALOG_DATA) private data: any) { }
ngOnInit(): void {
if(this.data.idExam!=null) {
this.examService.findExam(this.data.idExam).subscribe(exam => {
this.exam = exam;
this.subjectService.findSubjectForExam(this.data.idExam).subscribe(subject => {
this.subject = subject;
})
})
}
this.subjectService.findAllSubjectsForSchool(this.data.idSchool).subscribe(subjects => {
this.subjects = subjects;
})
}
onSelecSubject(e) {
this.idSubject = e.target.value;
}
onDateTime(e) {
this.exam.date = e.target.value;
}
addExam() {
this.progressBar = true;
if(this.data.idExam!=null) {
this.examService.editExam(this.exam, this.data.idExam).subscribe(exam => {
this.exam = exam;
window.location.reload();
})
} else {
this.examService.addExam(this.exam, this.data.idSchool, this.idSubject).subscribe(exam => {
this.exam = exam;
window.location.reload();
})
}
}
}
src/app/add-exam-component.html
<div style="margin: auto; width: 100%; border: 3px solid #73AD21;">
<mat-card>
<mat-card-header>
<mat-card-title>Add a new exam</mat-card-title>
</mat-card-header>
<mat-card-content><br>
<mat-progress-bar mode="buffer" *ngIf="progressBar"></mat-progress-bar>
<form>
<mat-form-field style="width: 100%;">
<mat-label>Please choose a subject</mat-label>
<select matNativeControl required (change)="onSelecSubject($event)">
<option selected disabled>Subjects</option>
<option *ngFor="let s of subjects" [value]="s.id" [selected]="s.name==subject.name">{{s.name}}</option>
</select>
</mat-form-field><br>
<mat-form-field style="width: 100%;">
<input matInput type="date" name="date" min="minDate"
[(ngModel)]="exam.date" #date="ngModel" required (change)="onDateTime($event)">
</mat-form-field> <br>
<mat-form-field style="width: 100%;">
<mat-label>START</mat-label>
<input matInput type="time" placeholder="startTime" name="start"
[(ngModel)]="exam.start" #startTime="ngModel" required>
</mat-form-field> <br>
<mat-form-field style="width: 100%;">
<mat-label>END</mat-label>
<input matInput type="time" placeholder="endTime" name="end"
[(ngModel)]="exam.end" #endTime="ngModel" required>
</mat-form-field> <br>
<mat-form-field style="width: 100%;">
<mat-label>Enter description</mat-label>
<textarea matInput placeholder="Description" name="description" [(ngModel)]="exam.description"
#description="ngModel"></textarea>
</mat-form-field><br>
<button mat-raised-button color="primary"
[disabled]="description.invalid
|| startTime.invalid || endTime.invalid"
(click)="addExam()" style="width: 10em !important">Save</button>
</form>
</mat-card-content>
</mat-card>
</div>