Skip to content

Commit a46b4e6

Browse files
committed
projeto finalizado
1 parent 9a51e04 commit a46b4e6

20 files changed

+373
-111
lines changed

README.md

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
# Angular Material AutoComplete Demo
2+
3+
Projeto demostrando a utilização do componente; autocomplete, da lib de componenentes; Angular Material.
4+
5+
### Tecnologias Necessárias
6+
7+
* [Node.js v8+]
8+
* [npm]
9+
* [angular cli v6+]
10+
11+
12+
[Node.js v8+]: <https://nodejs.org/en/>
13+
[npm]: <https://www.npmjs.com/>
14+
[angular cli v6+]: <https://cli.angular.io/>
15+
16+
#### Run Project
17+
18+
Digite os seguinte comando através do terminal/cmd, acessando o diretório raiz do projeto cliente em Angular: client-app.
19+
```sh
20+
$ npm install
21+
$ ng build
22+
$ ng serve
23+
```
24+
25+
Agora acesse o projeto pelo seguinte link: http://localhost:4200

angular.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,8 @@
7272
"tsConfig": "src/tsconfig.spec.json",
7373
"karmaConfig": "src/karma.conf.js",
7474
"styles": [
75+
"./node_modules/bootstrap/dist/css/bootstrap.min.css",
76+
"./node_modules/ngx-bootstrap/datepicker/bs-datepicker.css",
7577
"styles.css"
7678
],
7779
"scripts": [],

package-lock.json

Lines changed: 18 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,10 @@
1313
"@angular/platform-browser": "~7.1.0",
1414
"@angular/platform-browser-dynamic": "~7.1.0",
1515
"@angular/router": "~7.1.0",
16+
"@ng-bootstrap/ng-bootstrap": "^5.1.1",
17+
"bootstrap": "4.1.1",
1618
"core-js": "^2.5.4",
19+
"ngx-bootstrap": "^5.2.0",
1720
"rxjs": "~6.3.3",
1821
"tslib": "^1.9.0",
1922
"zone.js": "~0.8.26"

src/app/app.component.css

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
2+
.fill-remaining-space {
3+
/* This fills the remaining space, by using flexbox.
4+
Every toolbar row uses a flexbox row layout. */
5+
flex: 1 1 auto;
6+
}
7+
8+
.container {
9+
padding: 10px;
10+
}
11+
12+
.form {
13+
min-width: 150px;
14+
max-width: 500px;
15+
width: 100%;
16+
}
17+
18+
.form-element {
19+
padding: 5px 0px 25px 2px;
20+
width: 100%;
21+
}
22+
23+
.button {
24+
width: 100%;
25+
}

src/app/app.component.html

Lines changed: 54 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,58 @@
1-
<form [formGroup]="form">
1+
<mat-toolbar color="primary">
2+
<span class="fill-remaining-space">Angular Material AutoComplete Example</span>
3+
</mat-toolbar>
24

3-
<mat-form-field class="full-width">
4-
<input type="text" placeholder="Project"
5-
aria-label="Number"
6-
matInput formControlName="project"
7-
[matAutocomplete]="projectAutoComplete"
8-
[(ngModel)]="state" >
9-
<mat-autocomplete #projectAutoComplete="matAutocomplete">
10-
<mat-option *ngFor="let project of filteredOptions | async" [value]="project">
11-
{{ project }}
12-
</mat-option>
13-
</mat-autocomplete>
5+
<div class="container">
6+
<form [formGroup]="form" class="form">
147

15-
<mat-error *ngIf="form.controls['project'].hasError('required')">
16-
Please enter a value
17-
</mat-error>
8+
<mat-form-field class="form-element">
9+
<input type="text" placeholder="Users"
10+
aria-label="Number"
11+
required
12+
matInput formControlName="formUserControl"
13+
[matAutocomplete]="projectAutoComplete"
14+
[(ngModel)]="user"
15+
(blur)="getAlbumsByUser(user?.id)">
16+
<mat-autocomplete #projectAutoComplete="matAutocomplete" [displayWith]="displayFn">
17+
<mat-option *ngFor="let user of filteredUsersOptions | async" [value]="user">
18+
{{ user.name }}
19+
</mat-option>
20+
</mat-autocomplete>
21+
<mat-error *ngIf="form.controls['formUserControl'].hasError('required')">
22+
Please enter a value
23+
</mat-error>
24+
<mat-error *ngIf="form.controls['formUserControl'].hasError('incorrect')">
25+
Please select a valid user
26+
</mat-error>
27+
</mat-form-field>
1828

19-
<mat-error *ngIf="form.controls['project'].hasError('incorrect')">
20-
Please select a valid project
21-
</mat-error>
22-
</mat-form-field>
29+
<mat-form-field class="form-element">
30+
<input type="text" placeholder="Albums"
31+
aria-label="Number"
32+
matInput formControlName="formAlbumsControl"
33+
[matAutocomplete]="AlbumsAutoComplete"
34+
required>
35+
<mat-autocomplete #AlbumsAutoComplete="matAutocomplete">
36+
<mat-option *ngFor="let album of (albums.length === 0 ? [] : (filteredAlbumsOptions | async))" [value]="album.title">
37+
{{ album.title }}
38+
</mat-option>
39+
</mat-autocomplete>
40+
<mat-error *ngIf="form.controls['formAlbumsControl'].hasError('required')">
41+
Please enter a value
42+
</mat-error>
43+
<mat-error *ngIf="form.controls['formAlbumsControl'].hasError('incorrect')">
44+
Please select a valid album
45+
</mat-error>
46+
</mat-form-field>
2347

24-
</form>
48+
<div class="form-element">
49+
<button mat-raised-button color="primary"
50+
class="button"
51+
(click)="getUser()"
52+
[disabled]="!form.valid">
53+
Send...
54+
</button>
55+
</div>
56+
57+
</form>
58+
</div>

src/app/app.component.ts

Lines changed: 91 additions & 80 deletions
Original file line numberDiff line numberDiff line change
@@ -1,109 +1,120 @@
1-
import { Component, OnInit } from '@angular/core';
2-
import { FormGroup, FormControl, Validators, ValidatorFn, AbstractControl } from '@angular/forms';
3-
import { Project } from './project';
1+
import { Component, OnInit, ViewChild, ElementRef } from '@angular/core';
2+
import { FormGroup, FormControl, Validators } from '@angular/forms';
43
import { Observable } from 'rxjs';
5-
import {map, startWith} from 'rxjs/operators';
4+
import {map, startWith, filter} from 'rxjs/operators';
5+
import { FormCustomValidators } from './validators/FormCustomValidators';
6+
import { UserService } from './service/user.service';
7+
import { UserDTO } from './model/UserDTO';
8+
import { AlbumDTO } from './model/AlbumDTO';
9+
import { AlbumService } from './service/album.service';
10+
import { MatAutocompleteTrigger } from '@angular/material';
11+
612

713
@Component({
814
selector: 'app-root',
915
templateUrl: './app.component.html',
1016
styleUrls: ['./app.component.css']
1117
})
1218
export class AppComponent implements OnInit {
19+
1320
form: FormGroup;
14-
projects: Project[];
15-
filteredOptions: Observable<string[]>;
16-
state: string;
17-
states = [
18-
'Alabama',
19-
'Alaska',
20-
'Arizona',
21-
'Arkansas',
22-
'California',
23-
'Colorado',
24-
'Connecticut',
25-
'Delaware',
26-
'Florida',
27-
'Georgia',
28-
'Hawaii',
29-
'Idaho',
30-
'Illinois',
31-
'Indiana',
32-
'Iowa',
33-
'Kansas',
34-
'Kentucky',
35-
'Louisiana',
36-
'Maine',
37-
'Maryland',
38-
'Massachusetts',
39-
'Michigan',
40-
'Minnesota',
41-
'Mississippi',
42-
'Missouri',
43-
'Montana',
44-
'Nebraska',
45-
'Nevada',
46-
'New Hampshire',
47-
'New Jersey',
48-
'New Mexico',
49-
'New York',
50-
'North Carolina',
51-
'North Dakota',
52-
'Ohio',
53-
'Oklahoma',
54-
'Oregon',
55-
'Pennsylvania',
56-
'Rhode Island',
57-
'South Carolina',
58-
'South Dakota',
59-
'Tennessee',
60-
'Texas',
61-
'Utah',
62-
'Vermont',
63-
'Virginia',
64-
'Washington',
65-
'West Virginia',
66-
'Wisconsin',
67-
'Wyoming',
68-
];
69-
70-
constructor() {
21+
22+
@ViewChild(MatAutocompleteTrigger) trigger: MatAutocompleteTrigger;
23+
@ViewChild('focusMe') _focusMe: ElementRef;
24+
25+
user: UserDTO;
26+
users: Array<UserDTO>;
27+
filteredUsersOptions: Observable<UserDTO[]>;
28+
29+
album: AlbumDTO;
30+
albums: Array<AlbumDTO>;
31+
filteredAlbumsOptions: Observable<AlbumDTO[]>;
32+
33+
constructor(private userService: UserService,
34+
private albumService: AlbumService) {
35+
36+
this.users = new Array<UserDTO>();
37+
this.albums = new Array<AlbumDTO>();
7138
}
7239

7340
ngOnInit() {
41+
this.getUsers();
42+
this.initForm();
43+
}
44+
45+
private initForm(): void {
7446
this.form = new FormGroup({
75-
project: new FormControl('', [Validators.required, FormCustomValidators.valueSelected(this.states)]),
47+
formUserControl: new FormControl('', [Validators.required]),
48+
formAlbumsControl: new FormControl({value: '', disabled: true}, [Validators.required])
7649
});
77-
this.filteredOptions = this.form.get('project').valueChanges.pipe(
50+
51+
this.filteredUsersOptions = this.form.get('formUserControl').valueChanges.pipe(
52+
startWith(''),
53+
filter(value => typeof value === 'string'),
54+
map(value => this._filterUsers(value))
55+
);
56+
this.filteredAlbumsOptions = this.form.get('formAlbumsControl').valueChanges.pipe(
7857
startWith(''),
79-
map(value => this._filter(value))
58+
filter(value => typeof value === 'string'),
59+
map(value => this._filterAlbums(value))
8060
);
8161
}
8262

83-
private _filter(value: string): string[] {
63+
private _filterUsers(value: string): UserDTO[] {
8464
const filterValue = value.toLowerCase();
85-
return this.states.filter(option => option.toLowerCase().indexOf(filterValue) === 0);
65+
return this.users.filter(user => user.name.toLowerCase().indexOf(filterValue) === 0);
8666
}
8767

88-
}
68+
private _filterAlbums(value: string): AlbumDTO[] {
69+
const filterValue = value.toLowerCase();
70+
return this.albums.filter(album => album.title.toLowerCase().indexOf(filterValue) === 0);
71+
}
8972

90-
export class FormCustomValidators {
91-
static valueSelected(myArray: any[]): ValidatorFn {
73+
private addValidUserSelected() {
74+
this.form.get('formUserControl').setValidators(FormCustomValidators.valueSelected(this.users));
75+
}
9276

93-
return (c: AbstractControl): { [key: string]: boolean } | null => {
94-
let selectboxValue = c.value;
95-
let pickedOrNot = myArray.filter(alias => alias === selectboxValue);
77+
private addValidAlbumsSelected() {
78+
const albumsTitle = this.albums.map(album => album.title);
79+
this.form.get('formAlbumsControl').setValidators(FormCustomValidators.valueSelected(albumsTitle));
80+
}
9681

97-
if (pickedOrNot.length > 0) {
98-
// everything's fine. return no error. therefore it's null.
99-
return null;
82+
private getUsers(): void {
83+
this.userService.getUsers().subscribe( res => {
84+
this.users = res;
85+
this.addValidUserSelected();
86+
console.log('Usuários: ', this.users);
87+
}, error =>
88+
console.log(error)
89+
);
90+
}
10091

101-
} else {
102-
//there's no matching selectboxvalue selected. so return match error.
103-
return { 'incorrect': true };
104-
}
105-
}
92+
private verificaSeDeveHabilitarFormAlbumsControl(): void {
93+
const formAlbumsControl = this.form.get('formAlbumsControl');
94+
this.albums.length > 0 ? formAlbumsControl.enable() : formAlbumsControl.disable();
95+
}
96+
97+
getAlbumsByUser(userId: number) {
98+
console.log('User Id: ', userId);
99+
this.albumService.getAlbumsFromUser(userId).subscribe( resp => {
100+
this.albums = resp;
101+
this.addValidAlbumsSelected();
102+
this.verificaSeDeveHabilitarFormAlbumsControl();
103+
console.log('Albums By Users: ', this.albums);
104+
}, error => {
105+
console.log(error);
106+
});
106107
}
108+
109+
getUser(): void {
110+
console.log("Usuario Selecionado: ", this.user);
111+
}
112+
113+
displayFn(user: UserDTO) {
114+
if (user) { return user.name; }
115+
}
116+
107117
}
108118

109119

120+

0 commit comments

Comments
 (0)