Added some form elements and validation
This commit is contained in:
@@ -0,0 +1,4 @@
|
|||||||
|
export interface ValidationError {
|
||||||
|
type: string;
|
||||||
|
message: string;
|
||||||
|
}
|
||||||
@@ -6,5 +6,68 @@
|
|||||||
rutrum velit. Sed vitae ullamcorper sem. Aliquam malesuada nunc sed purus mollis scelerisque. Curabitur bibendum
|
rutrum velit. Sed vitae ullamcorper sem. Aliquam malesuada nunc sed purus mollis scelerisque. Curabitur bibendum
|
||||||
leo quis ante porttitor tincidunt. Nam tincidunt imperdiet tortor eu suscipit. Maecenas ut dui est.
|
leo quis ante porttitor tincidunt. Nam tincidunt imperdiet tortor eu suscipit. Maecenas ut dui est.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
|
<form [formGroup]="formGroup">
|
||||||
|
<div class="create-account__block">
|
||||||
|
<h2>Personuppgifter</h2>
|
||||||
|
|
||||||
|
<div class="create-account__combined-inputs">
|
||||||
|
<digi-ng-form-input
|
||||||
|
class="create-account__input"
|
||||||
|
formControlName="firstName"
|
||||||
|
afLabel="Förnamn"
|
||||||
|
afInvalidMessage="Förnamn är obligatoriskt"
|
||||||
|
[afDisableValidStyle]="true"
|
||||||
|
[afInvalid]="firstNameControl.invalid && firstNameControl.dirty"
|
||||||
|
></digi-ng-form-input>
|
||||||
|
<digi-ng-form-input
|
||||||
|
class="create-account__input"
|
||||||
|
formControlName="lastName"
|
||||||
|
afLabel="Efternamn"
|
||||||
|
afInvalidMessage="Efternamn är obligatoriskt"
|
||||||
|
[afDisableValidStyle]="true"
|
||||||
|
[afInvalid]="lastNameControl.invalid && lastNameControl.dirty"
|
||||||
|
></digi-ng-form-input>
|
||||||
|
</div>
|
||||||
|
<digi-ng-form-input
|
||||||
|
class="create-account__input"
|
||||||
|
formControlName="ssn"
|
||||||
|
afLabel="Personnummer"
|
||||||
|
[afInvalidMessage]="ssnControl.errors?.message || ''"
|
||||||
|
[afDisableValidStyle]="true"
|
||||||
|
[afInvalid]="ssnControl.invalid && ssnControl.dirty"
|
||||||
|
></digi-ng-form-input>
|
||||||
|
<digi-ng-form-input
|
||||||
|
class="create-account__input"
|
||||||
|
formControlName="email"
|
||||||
|
afLabel="Arbetsmejl"
|
||||||
|
afType="email"
|
||||||
|
[afInvalidMessage]="ssnControl.errors?.message || ''"
|
||||||
|
[afDisableValidStyle]="true"
|
||||||
|
[afInvalid]="ssnControl.invalid && ssnControl.dirty"
|
||||||
|
></digi-ng-form-input>
|
||||||
|
<digi-ng-form-input
|
||||||
|
class="create-account__input"
|
||||||
|
formControlName="phone"
|
||||||
|
afLabel="Telefonnummer arbete"
|
||||||
|
afType="tel"
|
||||||
|
[afInvalidMessage]="ssnControl.errors?.message || ''"
|
||||||
|
[afDisableValidStyle]="true"
|
||||||
|
[afInvalid]="ssnControl.invalid && ssnControl.dirty"
|
||||||
|
></digi-ng-form-input>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="create-account__block">
|
||||||
|
<h2>Bemanning av personal</h2>
|
||||||
|
|
||||||
|
<fieldset>
|
||||||
|
<legend>Är {{ firstNameControl.value || 'medarbetaren' }} i aktiv tjänst?</legend>
|
||||||
|
<digi-ng-form-radiobutton-group
|
||||||
|
[afRadiobuttons]="activeRadioButtons"
|
||||||
|
formControlName="active"
|
||||||
|
></digi-ng-form-radiobutton-group>
|
||||||
|
</fieldset>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
</digi-typography>
|
</digi-typography>
|
||||||
</section>
|
</section>
|
||||||
|
|||||||
@@ -0,0 +1,15 @@
|
|||||||
|
.create-account {
|
||||||
|
&__block {
|
||||||
|
max-width: var(--digi--typography--text--max-width);
|
||||||
|
}
|
||||||
|
|
||||||
|
&__combined-inputs {
|
||||||
|
display: flex;
|
||||||
|
gap: var(--digi--layout--gutter);
|
||||||
|
}
|
||||||
|
|
||||||
|
&__input {
|
||||||
|
width: 100%;
|
||||||
|
margin-bottom: var(--digi--layout--gutter);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,4 +1,8 @@
|
|||||||
|
import { RadiobuttonModel } from '@af/digi-ng/_form/form-radiobutton-group';
|
||||||
import { ChangeDetectionStrategy, Component } from '@angular/core';
|
import { ChangeDetectionStrategy, Component } from '@angular/core';
|
||||||
|
import { AbstractControl, FormBuilder, FormGroup } from '@angular/forms';
|
||||||
|
import { RequiredValidator } from '@dafa-validators/required.validator';
|
||||||
|
import { SocialSecurityNumberValidator } from '@dafa-validators/social-security-number.validator';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'dafa-create-account',
|
selector: 'dafa-create-account',
|
||||||
@@ -6,4 +10,42 @@ import { ChangeDetectionStrategy, Component } from '@angular/core';
|
|||||||
styleUrls: ['./create-account.component.scss'],
|
styleUrls: ['./create-account.component.scss'],
|
||||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||||
})
|
})
|
||||||
export class CreateAccountComponent {}
|
export class CreateAccountComponent {
|
||||||
|
formGroup: FormGroup;
|
||||||
|
|
||||||
|
constructor(private formBuilder: FormBuilder) {
|
||||||
|
this.formGroup = this.formBuilder.group({
|
||||||
|
firstName: this.formBuilder.control('', [RequiredValidator('Förnamn')]),
|
||||||
|
lastName: this.formBuilder.control('', [RequiredValidator('Efternamn')]),
|
||||||
|
ssn: this.formBuilder.control('', [RequiredValidator('Personnummer'), SocialSecurityNumberValidator()]),
|
||||||
|
email: this.formBuilder.control('', [RequiredValidator('Arbetsmejl')]),
|
||||||
|
phone: this.formBuilder.control('', [RequiredValidator('Telefonnummer arbete')]),
|
||||||
|
active: this.formBuilder.control(true),
|
||||||
|
});
|
||||||
|
|
||||||
|
this.formGroup.valueChanges.subscribe(values => console.table(values));
|
||||||
|
}
|
||||||
|
|
||||||
|
get activeRadioButtons(): RadiobuttonModel[] {
|
||||||
|
return [
|
||||||
|
{
|
||||||
|
label: 'Ja',
|
||||||
|
value: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Nej',
|
||||||
|
value: false,
|
||||||
|
},
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
get firstNameControl(): AbstractControl {
|
||||||
|
return this.formGroup.get('firstName');
|
||||||
|
}
|
||||||
|
get lastNameControl(): AbstractControl {
|
||||||
|
return this.formGroup.get('lastName');
|
||||||
|
}
|
||||||
|
get ssnControl(): AbstractControl {
|
||||||
|
return this.formGroup.get('ssn');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,11 +1,20 @@
|
|||||||
|
import { DigiNgFormInputModule } from '@af/digi-ng/_form/form-input';
|
||||||
|
import { DigiNgFormRadiobuttonGroupModule } from '@af/digi-ng/_form/form-radiobutton-group';
|
||||||
import { CommonModule } from '@angular/common';
|
import { CommonModule } from '@angular/common';
|
||||||
import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core';
|
import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core';
|
||||||
|
import { ReactiveFormsModule } from '@angular/forms';
|
||||||
import { RouterModule } from '@angular/router';
|
import { RouterModule } from '@angular/router';
|
||||||
import { CreateAccountComponent } from './create-account.component';
|
import { CreateAccountComponent } from './create-account.component';
|
||||||
|
|
||||||
@NgModule({
|
@NgModule({
|
||||||
schemas: [CUSTOM_ELEMENTS_SCHEMA],
|
schemas: [CUSTOM_ELEMENTS_SCHEMA],
|
||||||
declarations: [CreateAccountComponent],
|
declarations: [CreateAccountComponent],
|
||||||
imports: [CommonModule, RouterModule.forChild([{ path: '', component: CreateAccountComponent }])],
|
imports: [
|
||||||
|
CommonModule,
|
||||||
|
RouterModule.forChild([{ path: '', component: CreateAccountComponent }]),
|
||||||
|
ReactiveFormsModule,
|
||||||
|
DigiNgFormInputModule,
|
||||||
|
DigiNgFormRadiobuttonGroupModule,
|
||||||
|
],
|
||||||
})
|
})
|
||||||
export class CreateAccountModule {}
|
export class CreateAccountModule {}
|
||||||
|
|||||||
12
apps/dafa-web/src/app/utils/validators/required.validator.ts
Normal file
12
apps/dafa-web/src/app/utils/validators/required.validator.ts
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
import { AbstractControl, ValidatorFn } from '@angular/forms';
|
||||||
|
import { ValidationError } from '@dafa-models/validation-error.model';
|
||||||
|
|
||||||
|
export function RequiredValidator(label = 'Fältet'): ValidatorFn {
|
||||||
|
return (control: AbstractControl): ValidationError => {
|
||||||
|
if (control && !control.value) {
|
||||||
|
return { type: 'required', message: `${label} är obligatoriskt` };
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -0,0 +1,68 @@
|
|||||||
|
import { AbstractControl, ValidatorFn } from '@angular/forms';
|
||||||
|
import { ValidationError } from '@dafa-models/validation-error.model';
|
||||||
|
|
||||||
|
export function SocialSecurityNumberValidator(): ValidatorFn {
|
||||||
|
return (control: AbstractControl): ValidationError => {
|
||||||
|
if (!control || !control.value) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
const ssn = control.value;
|
||||||
|
|
||||||
|
if (/[^0-9-]/g.test(ssn)) {
|
||||||
|
return { type: 'ssnInvalid', message: 'Inkorrekt personnummer' };
|
||||||
|
}
|
||||||
|
|
||||||
|
let strippedSsn = control.value.replace(/[^0-9]/g, '');
|
||||||
|
|
||||||
|
// Year format 1991 -> 91
|
||||||
|
if (strippedSsn.length === 12) {
|
||||||
|
strippedSsn = strippedSsn.substr(2);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check length
|
||||||
|
if (strippedSsn.length !== 10) {
|
||||||
|
return { type: 'ssnNotComplete', message: 'Personnummret är inte fullständigt' };
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check month
|
||||||
|
if (strippedSsn.substr(2, 2) > 12 || strippedSsn.substr(2, 2) === '00') {
|
||||||
|
return { type: 'ssnInvalid', message: 'Inkorrekt personnummer' };
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check date (valid date + 60 is also apporved because of co-ordination number)
|
||||||
|
if (
|
||||||
|
(strippedSsn.substr(4, 2) > 31 || strippedSsn.substr(4, 2) === '00') &&
|
||||||
|
(strippedSsn.substr(4, 2) > 91 || strippedSsn.substr(4, 2) <= 60)
|
||||||
|
) {
|
||||||
|
return { type: 'ssnInvalid', message: 'Inkorrekt personnummer' };
|
||||||
|
}
|
||||||
|
|
||||||
|
return isControlDigitLegit(strippedSsn) ? null : { type: 'ssnInvalid', message: 'Inkorrekt personnummer' };
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function isControlDigitLegit(ssn: string): boolean {
|
||||||
|
// Run the mod 10 algorithm to produce check digit
|
||||||
|
const enteredControlDigit = +ssn.substr(-1);
|
||||||
|
let inc = 0;
|
||||||
|
let multiplicator = 2;
|
||||||
|
let product: number;
|
||||||
|
|
||||||
|
for (const char of ssn.slice(0, -1)) {
|
||||||
|
product = +char * multiplicator;
|
||||||
|
if (product > 9) {
|
||||||
|
inc += product - 9;
|
||||||
|
} else {
|
||||||
|
inc += product;
|
||||||
|
}
|
||||||
|
multiplicator = multiplicator === 1 ? 2 : 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
let calculatedControlDigit = 10 - (inc - Math.floor(inc / 10) * 10);
|
||||||
|
if (calculatedControlDigit === 10) {
|
||||||
|
calculatedControlDigit = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return calculatedControlDigit === enteredControlDigit;
|
||||||
|
}
|
||||||
@@ -23,6 +23,7 @@
|
|||||||
"@dafa-enums/*": ["apps/dafa-web/src/app/data/enums/*"],
|
"@dafa-enums/*": ["apps/dafa-web/src/app/data/enums/*"],
|
||||||
"@dafa-services/*": ["apps/dafa-web/src/app/services/*"],
|
"@dafa-services/*": ["apps/dafa-web/src/app/services/*"],
|
||||||
"@dafa-utils/*": ["apps/dafa-web/src/app/utils/*"],
|
"@dafa-utils/*": ["apps/dafa-web/src/app/utils/*"],
|
||||||
|
"@dafa-validators/*": ["apps/dafa-web/src/app/utils/validators/*"],
|
||||||
"@dafa-environment": ["apps/dafa-web/src/environments/environment"]
|
"@dafa-environment": ["apps/dafa-web/src/environments/environment"]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|||||||
Reference in New Issue
Block a user