[HIMA-47] - autofocus on inputs

This commit is contained in:
Peter Skrlj
2019-02-10 11:29:11 +01:00
parent c679a0e6f2
commit 75424a67b5
7 changed files with 249 additions and 130 deletions

View File

@@ -13,7 +13,7 @@
class="search-box"
placeholder="Titel, Autor, Verlag, Schlagwort, ..."
type="text"
autofocus
#search
/>
<img
(click)="clear()"

View File

@@ -1,29 +1,37 @@
import { Component, OnInit, Input } from '@angular/core';
import { Store, Select } from '@ngxs/store';
import { Observable } from 'rxjs';
import { RecentArticleSearch } from 'src/app/core/models/recent-article-search.model';
import { Product } from 'src/app/core/models/product.model';
import { Router } from '@angular/router';
import { Search } from 'src/app/core/models/search.model';
import { Breadcrumb } from 'src/app/core/models/breadcrumb.model';
import { Filter } from 'src/app/core/models/filter.model';
import { Process } from 'src/app/core/models/process.model';
import { getRandomPic } from 'src/app/core/utils/process.util';
import { Breadcrumb } from 'src/app/core/models/breadcrumb.model';
import { ProcessState } from 'src/app/core/store/state/process.state';
import { Product } from 'src/app/core/models/product.model';
import { RecentArticleSearch } from 'src/app/core/models/recent-article-search.model';
import { Search } from 'src/app/core/models/search.model';
import {
AddProcess,
ChangeCurrentRoute,
AddSearch
AddSearch,
AllowProductLoad,
ChangeCurrentRoute
} from 'src/app/core/store/actions/process.actions';
import { AllowProductLoad } from 'src/app/core/store/actions/process.actions';
import { LoadRecentProducts } from 'src/app/core/store/actions/product.actions';
import { ProcessState } from 'src/app/core/store/state/process.state';
import { getRandomPic } from 'src/app/core/utils/process.util';
import {
AfterViewInit,
Component,
ElementRef,
Input,
OnInit,
ViewChild
} from '@angular/core';
import { Router } from '@angular/router';
import { Select, Store } from '@ngxs/store';
@Component({
selector: 'app-text-search',
templateUrl: './text-search.component.html',
styleUrls: ['./text-search.component.scss']
})
export class TextSearchComponent implements OnInit {
export class TextSearchComponent implements OnInit, AfterViewInit {
@Select(ProcessState.getRecentProducts) recentArticles$: Observable<
RecentArticleSearch[]
>;
@@ -37,8 +45,17 @@ export class TextSearchComponent implements OnInit {
@Input()
searchParams = '';
@ViewChild('search') searchInput: ElementRef;
constructor(private store: Store, private router: Router) {}
ngOnInit() {
this.loadRecentArticles();
}
ngAfterViewInit() {
this.searchInput.nativeElement.focus();
}
search() {
if (!this.searchParams) {
return;
@@ -137,8 +154,4 @@ export class TextSearchComponent implements OnInit {
this.createProcess();
}
}
ngOnInit() {
this.loadRecentArticles();
}
}

View File

@@ -1,66 +1,133 @@
<div class="customer-section-create">
<div class="customer-section-create-title">
<span>Kundendaten erfassen</span>
</div>
<div class="align-center customer-section-create-description">
<span>Damit wir Ihnen die Bestelldetails zukommen lassen können.</span>
</div>
<div class="create-wrapper">
<form class="form" [formGroup]="userForm">
<div class="form-group">
<input type="text" id="name" class="input form-control" formControlName="firstName" [ngClass]="{ 'error-visible': submitted && f.firstName.errors }" required autofocus>
<label class="placeholder form-control-placeholder" for="name">Vorname</label>
<div *ngIf="submitted && f.firstName.errors" class="invalid-feedback">
<div>Vorname wird benötigt</div>
<div class="customer-section-create-title">
<span>Kundendaten erfassen</span>
</div>
<div class="align-center customer-section-create-description">
<span>Damit wir Ihnen die Bestelldetails zukommen lassen können.</span>
</div>
<div class="create-wrapper">
<form class="form" [formGroup]="userForm">
<div class="form-group">
<input
#vornameInput
type="text"
id="name"
class="input form-control"
formControlName="firstName"
[ngClass]="{ 'error-visible': submitted && f.firstName.errors }"
required
autofocus
/>
<label class="placeholder form-control-placeholder" for="name"
>Vorname</label
>
<div *ngIf="submitted && f.firstName.errors" class="invalid-feedback">
<div>Vorname wird benötigt</div>
</div>
<div class="line"></div>
</div>
<div class="form-group">
<input
type="text"
id="lastName"
class="input form-control"
formControlName="lastName"
[ngClass]="{ 'error-visible': submitted && f.lastName.errors }"
required
/>
<label class="placeholder form-control-placeholder" for="lastName"
>Nachname</label
>
<div *ngIf="submitted && f.lastName.errors" class="invalid-feedback">
<div>Nachname wird benötigt</div>
</div>
<div class="line"></div>
</div>
<div class="form-group">
<input
type="text"
id="date"
class="input form-control"
formControlName="dateOfBirth"
required
/>
<label class="placeholder form-control-placeholder" for="date"
>Geburtsdatum (TT.MM.JJJJ)</label
>
<div *ngIf="submitted && f.dateOfBirth.errors" class="invalid-feedback">
<div *ngIf="submitted && f.dateOfBirth.errors.required">
Geburtsdatum wird benötigt
</div>
<div *ngIf="submitted && f.dateOfBirth.errors.invalidDate">
Geburtsdatum hat ein falsches Format
</div>
</div>
<div class="line"></div>
</div>
<div class="form-group">
<input
type="text"
id="address"
class="input form-control"
formControlName="address"
[ngClass]="{ 'error-visible': submitted && f.address.errors }"
required
/>
<label class="placeholder form-control-placeholder" for="address"
>Straße und Hausnummer</label
>
<div *ngIf="submitted && f.address.errors" class="invalid-feedback">
<div>Straße und Hausnummer wird benötigt</div>
</div>
<div class="line"></div>
</div>
<div class="form-group form-group-location">
<div class="form-group-split">
<input
type="text"
id="zipCode"
class="input form-control"
formControlName="zipCode"
[ngClass]="{ 'error-visible': submitted && f.zipCode.errors }"
required
/>
<label class="placeholder form-control-placeholder" for="zipCode"
>PLZ</label
>
<div
*ngIf="submitted && f.zipCode.errors"
class="invalid-feedback invalid-feedback-under invalid-feedback-under-start"
>
<div>PLZ wird benötigt</div>
</div>
<div class="line"></div>
</div>
<div class="form-group">
<input type="text" id="lastName" class="input form-control" formControlName="lastName" [ngClass]="{ 'error-visible': submitted && f.lastName.errors }" required>
<label class="placeholder form-control-placeholder" for="lastName">Nachname</label>
<div *ngIf="submitted && f.lastName.errors" class="invalid-feedback">
<div>Nachname wird benötigt</div>
<div class="form-group-split">
<input
type="text"
id="city"
class="input form-control"
formControlName="city"
[ngClass]="{ 'error-visible': submitted && f.city.errors }"
required
/>
<label
class="placeholder form-control-placeholder city-label"
for="city"
>Ort</label
>
<div
*ngIf="submitted && f.city.errors"
class="invalid-feedback invalid-feedback-under"
>
<div>Ort wird benötigt</div>
</div>
<div class="line"></div>
</div>
<div class="form-group">
<input type="text" id="date" class="input form-control" formControlName="dateOfBirth" required>
<label class="placeholder form-control-placeholder" for="date">Geburtsdatum (TT.MM.JJJJ)</label>
<div *ngIf="submitted && f.dateOfBirth.errors" class="invalid-feedback">
<div *ngIf="submitted && f.dateOfBirth.errors.required">Geburtsdatum wird benötigt</div>
<div *ngIf="submitted && f.dateOfBirth.errors.invalidDate">Geburtsdatum hat ein falsches Format</div>
</div>
<div class="line"></div>
</div>
<div class="form-group">
<input type="text" id="address" class="input form-control" formControlName="address" [ngClass]="{ 'error-visible': submitted && f.address.errors }" required>
<label class="placeholder form-control-placeholder" for="address">Straße und Hausnummer</label>
<div *ngIf="submitted && f.address.errors" class="invalid-feedback">
<div>Straße und Hausnummer wird benötigt</div>
</div>
<div class="line"></div>
</div>
<div class="form-group form-group-location">
<div class="form-group-split">
<input type="text" id="zipCode" class="input form-control" formControlName="zipCode" [ngClass]="{ 'error-visible': submitted && f.zipCode.errors }" required>
<label class="placeholder form-control-placeholder" for="zipCode">PLZ</label>
<div *ngIf="submitted && f.zipCode.errors" class="invalid-feedback invalid-feedback-under invalid-feedback-under-start">
<div>PLZ wird benötigt</div>
</div>
<div class="line"></div>
</div>
<div class="form-group-split">
<input type="text" id="city" class="input form-control" formControlName="city" [ngClass]="{ 'error-visible': submitted && f.city.errors }" required>
<label class="placeholder form-control-placeholder city-label" for="city">Ort</label>
<div *ngIf="submitted && f.city.errors" class="invalid-feedback invalid-feedback-under">
<div>Ort wird benötigt</div>
</div>
<div class="line"></div>
</div>
</div>
<div class="form-group btn-container">
<a class="btn" (click)="createUser()">Speichern</a>
</div>
</form>
</div>
</div>
<div class="form-group btn-container">
<a class="btn" (click)="createUser()">Speichern</a>
</div>
</form>
</div>
</div>

View File

@@ -57,6 +57,7 @@
.form-group-split {
width: 47%;
position: relative;
}
}
}
@@ -206,7 +207,7 @@
top: 18px;
padding: 7px 10px 10px;
transition: all 200ms;
opacity: 0.5;
opacity: 1;
left: 0px;
}

View File

@@ -1,7 +1,22 @@
import { Component, OnInit } from '@angular/core';
import { FormGroup, FormBuilder, Validators, FormControl } from '@angular/forms';
import {
Component,
OnInit,
ViewChild,
ElementRef,
AfterViewInit
} from '@angular/core';
import {
FormGroup,
FormBuilder,
Validators,
FormControl
} from '@angular/forms';
import { Store, Select } from '@ngxs/store';
import { AddUser, ChangeCurrentRoute, AddProcess } from '../../../../core/store/actions/process.actions';
import {
AddUser,
ChangeCurrentRoute,
AddProcess
} from '../../../../core/store/actions/process.actions';
import { User, Address } from '../../../../core/models/user.model';
import { Router } from '@angular/router';
import { Process } from '../../../../core/models/process.model';
@@ -15,43 +30,50 @@ import { Observable } from 'rxjs';
templateUrl: './create-customer-card.component.html',
styleUrls: ['./create-customer-card.component.scss']
})
export class CreateCustomerCardComponent implements OnInit {
export class CreateCustomerCardComponent implements OnInit, AfterViewInit {
@Select(ProcessState.getProcesses) processes$: Observable<Process[]>;
userForm: FormGroup;
submitted = false;
processes: Process[];
@ViewChild('vornameInput') vornameInput: ElementRef;
constructor(
private fb: FormBuilder,
private store: Store,
private router: Router,
) { }
private router: Router
) {}
ngOnInit() {
this.userForm = this.buildForm(this.fb);
}
ngAfterViewInit() {
this.vornameInput.nativeElement.focus();
}
createUser() {
if (this.userForm.valid) {
this.createProcessIfDosntExists();
const address = new Address(
this.userForm.get('firstName').value + ' ' + this.userForm.get('lastName').value,
this.userForm.get('address').value,
+this.userForm.get('zipCode').value,
this.userForm.get('firstName').value +
' ' +
this.userForm.get('lastName').value,
this.userForm.get('address').value,
+this.userForm.get('zipCode').value,
this.userForm.get('city').value
);
const data: User = {
id: Date.now() + Math.random(),
name: this.userForm.get('firstName').value + ' ' + this.userForm.get('lastName').value,
name:
this.userForm.get('firstName').value +
' ' +
this.userForm.get('lastName').value,
date_of_birth: this.userForm.get('dateOfBirth').value,
delivery_addres: address,
poossible_addresses: [
address
],
poossible_addresses: [address],
invoice_address: address,
email: 'random@gmail.com',
shop: (Math.floor(Math.random() * 6) + 1) > 3 ? true : false
shop: Math.floor(Math.random() * 6) + 1 > 3 ? true : false
};
this.store.dispatch(new AddUser(data));
this.store.dispatch(new ChangeCurrentRoute('customer-search'));
@@ -63,9 +85,7 @@ export class CreateCustomerCardComponent implements OnInit {
}
loadProcesses() {
this.processes$.subscribe(
(data: Process[]) => this.processes = data
);
this.processes$.subscribe((data: Process[]) => (this.processes = data));
}
createProcess() {
@@ -74,10 +94,12 @@ export class CreateCustomerCardComponent implements OnInit {
name: '# 1',
selected: true,
icon: getRandomPic(),
breadcrumbs: <Breadcrumb[]>[{
name: 'Kundendaten erfassen',
path: '/customer-search'
}],
breadcrumbs: <Breadcrumb[]>[
{
name: 'Kundendaten erfassen',
path: '/customer-search'
}
],
currentRoute: 'customer-search'
};
@@ -91,17 +113,22 @@ export class CreateCustomerCardComponent implements OnInit {
}
}
get f() { return this.userForm.controls; }
get f() {
return this.userForm.controls;
}
private buildForm(fb: FormBuilder) {
return fb.group({
firstName: ['', Validators.required],
lastName: ['', Validators.required],
dateOfBirth: ['', Validators.required],
address: ['', Validators.required],
zipCode: ['', Validators.required],
city: ['', Validators.required]
}, { validators: this.validateAllFormFields });
return fb.group(
{
firstName: ['', Validators.required],
lastName: ['', Validators.required],
dateOfBirth: ['', Validators.required],
address: ['', Validators.required],
zipCode: ['', Validators.required],
city: ['', Validators.required]
},
{ validators: this.validateAllFormFields }
);
}
validateAllFormFields(formGroup: FormGroup) {
@@ -114,7 +141,7 @@ export class CreateCustomerCardComponent implements OnInit {
const regexpDate: RegExp = /^\s*(3[01]|[12][0-9]|0?[1-9])\.(1[012]|0?[1-9])\.((?:19|20)\d{2})\s*$/;
const validDate = regexpDate.test(control.value);
if ((control.errors && control.errors.invalidDate) && validDate) {
if (control.errors && control.errors.invalidDate && validDate) {
control.setErrors(null);
} else if (!control.errors) {
const regexpDate: RegExp = /^\s*(3[01]|[12][0-9]|0?[1-9])\.(1[012]|0?[1-9])\.((?:19|20)\d{2})\s*$/;

View File

@@ -6,7 +6,7 @@
<span>Wie lautet Ihr Name, Ihre E-Mail, Adresse oder Ihre PLZ?</span>
</div>
<div class="search-wrapper">
<input [(ngModel)]="searchParams" (keypress)="keyHandler($event)" class="search-box" placeholder="Name, E-Mail, PLZ" type="text" autofocus [ngClass]="{'error-visible' : searchError}">
<input [(ngModel)]="searchParams" (keypress)="keyHandler($event)" class="search-box" placeholder="Name, E-Mail, PLZ" type="text" #search [ngClass]="{'error-visible' : searchError}">
<span *ngIf="searchError" class="error-message">Ergibt keine Suchergebnisse</span>
<img (click)="search()" class="search-icon" src="../../../assets/images/search.svg" alt="search">
<img (click)="clear()" *ngIf="searchParams" class="clear-icon" src="../../../assets/images/close.svg" alt="close">

View File

@@ -1,4 +1,11 @@
import { Component, OnInit, Input } from '@angular/core';
import {
Component,
OnInit,
Input,
ElementRef,
AfterViewInit,
ViewChild
} from '@angular/core';
import { Observable } from 'rxjs';
import { RecentArticleSearch } from '../../../../core/models/recent-article-search.model';
import { Product } from '../../../../core/models/product.model';
@@ -8,7 +15,11 @@ import { Router } from '@angular/router';
import { Breadcrumb } from '../../../../core/models/breadcrumb.model';
import { getRandomPic } from '../../../../core/utils/process.util';
import { Store, Select } from '@ngxs/store';
import { SearchUser, ChangeCurrentRoute, AddProcess } from '../../../../core/store/actions/process.actions';
import {
SearchUser,
ChangeCurrentRoute,
AddProcess
} from '../../../../core/store/actions/process.actions';
import { ProcessState } from '../../../../core/store/state/process.state';
import { User } from '../../../../core/models/user.model';
@@ -17,11 +28,10 @@ import { User } from '../../../../core/models/user.model';
templateUrl: './search-customer-card.component.html',
styleUrls: ['./search-customer-card.component.scss']
})
export class SearchCustomerCardComponent implements OnInit {
export class SearchCustomerCardComponent implements OnInit, AfterViewInit {
@Select(ProcessState.getProcesses) processes$: Observable<Process[]>;
@Select(ProcessState.getUsers) users$: Observable<User[]>;
recentArticles$: Observable<RecentArticleSearch[]>;
recentArticles: RecentArticleSearch[];
products$: Observable<Product[]>;
@@ -31,18 +41,20 @@ export class SearchCustomerCardComponent implements OnInit {
searchError = false;
@Input() searchParams = '';
@ViewChild('search') searchInput: ElementRef;
constructor(
private store: Store,
private router: Router
) { }
constructor(private store: Store, private router: Router) {}
ngOnInit() {}
ngAfterViewInit() {
this.searchInput.nativeElement.focus();
}
search() {
if (!this.searchParams) {
if (!this.searchParams) {
this.searchError = false;
return;
return;
}
this.store.dispatch(new SearchUser(this.searchParams));
@@ -53,8 +65,7 @@ export class SearchCustomerCardComponent implements OnInit {
} else {
this.searchError = true;
}
})
});
}
navigateToRoute(route: string) {
@@ -76,9 +87,7 @@ export class SearchCustomerCardComponent implements OnInit {
}
loadProcesses() {
this.processes$.subscribe(
(data: Process[]) => this.processes = data
);
this.processes$.subscribe((data: Process[]) => (this.processes = data));
}
createProcess() {
@@ -87,10 +96,12 @@ export class SearchCustomerCardComponent implements OnInit {
name: '# 1',
selected: true,
icon: getRandomPic(),
breadcrumbs: <Breadcrumb[]>[{
name: 'Kundensuche',
path: '/customer-search'
}],
breadcrumbs: <Breadcrumb[]>[
{
name: 'Kundensuche',
path: '/customer-search'
}
],
currentRoute: 'customer-search',
users: []
};