experiment some thing spicy

This commit is contained in:
Kenta420 2023-12-01 11:14:25 +07:00
parent ce28a757b1
commit 3411ae333d
18 changed files with 211 additions and 10 deletions

View file

@ -0,0 +1,24 @@
import { Component, Input, OnInit } from '@angular/core';
import { AbstractControl, FormControl, FormGroup } from '@angular/forms';
import { FormComponent } from '../formBuilder/types/form.type';
import { TextBox } from '../formBuilder/types/atoms-types';
@Component({
selector: 'textbox',
template: `
<input
class="form-control"
[formControl]="form"
[id]="field.id"
[type]="field.body.label"
[placeholder]="field.body.placeholder"
/>
`,
})
export class TextBoxComponent implements OnInit {
@Input() field!: FormComponent;
@Input() form!: FormControl;
constructor() {}
ngOnInit() {}
}

View file

@ -0,0 +1,51 @@
import { Component, Input, OnInit } from '@angular/core';
import { FormComponent } from '../types/form.type';
import { FormGroup, FormControl } from '@angular/forms';
@Component({
selector: 'field-builder',
template: `
<div class="form-group row" [formGroup]="form">
<label class="col-md-3 form-control-label" [attr.for]="field.body.label">
{{ field.body.label }}
<strong
class="text-danger"
*ngIf="field.body.required && form.get(field.id)?.invalid"
>*</strong
>
</label>
<div class="col-md-9" [ngSwitch]="field.type">
<textbox
*ngSwitchCase="'text'"
[field]="field"
[form]="control"
></textbox>
<div
class="alert alert-danger my-1 p-2 fadeInDown animated"
*ngIf="!isValid && isDirty"
>
{{ field.body.label }} is required
</div>
</div>
</div>
`,
})
export class FieldBuilderComponent implements OnInit {
@Input({ required: true }) field!: FormComponent;
@Input() form!: FormGroup;
get isValid() {
return this.form.controls[this.field.id].valid;
}
get isDirty() {
return this.form.controls[this.field.id].dirty;
}
get control(): FormControl {
return this.form.controls[this.field.id] as FormControl;
}
constructor() {}
ngOnInit() {}
}

View file

@ -0,0 +1,15 @@
export class FormID {
private static CHARACTERS =
'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
private static BASE_ID = 'form-';
private static generateRandomString(length: number): string {
let result = '';
for (let i = 0; i < length; i++) {
result += this.CHARACTERS.charAt(
Math.floor(Math.random() * this.CHARACTERS.length)
);
}
return result;
}
}

View file

@ -0,0 +1,19 @@
import { Component, Input } from '@angular/core';
import { FormGroup } from '@angular/forms';
@Component({
selector: 'form-builder',
template: `
<form [formGroup]="formGroup" class="form-horizontal">
<div *ngFor="let field of fields">
<field-builder [field]="field" [form]="formGroup"></field-builder>
</div>
<div class="form-row"></div>
</form>
`,
})
export class FormBuilderComponent {
@Input() fields: any[] = [];
@Input() formGroup!: FormGroup;
constructor() {}
}

View file

@ -0,0 +1,14 @@
import { NgModule } from '@angular/core';
import { FormBuilderComponent } from './formBuilder.component';
import { CommonModule } from '@angular/common';
import { ReactiveFormsModule } from '@angular/forms';
import { FieldBuilderComponent } from './field-builder/field-builder.component';
import { TextBoxComponent } from '../atoms/textbox.component';
@NgModule({
imports: [CommonModule, ReactiveFormsModule],
declarations: [FormBuilderComponent, FieldBuilderComponent, TextBoxComponent],
exports: [FormBuilderComponent],
providers: [],
})
export class FormBuilderModule {}

View file

@ -0,0 +1,34 @@
type TextBox = {
type: 'text';
body: {
type: string;
label: string;
name: string;
value: string;
required: boolean;
placeholder: string;
};
};
type CheckBox = {
type: 'checkbox';
body: {
label: string;
name: string;
value: string;
required: boolean;
placeholder: string;
};
};
type DropDown = {
type: 'dropdown';
body: {
label: string;
items: string[];
required: boolean;
placeholder: string;
};
};
export { TextBox, CheckBox, DropDown };

View file

@ -0,0 +1,6 @@
import { CheckBox, DropDown, TextBox } from './atoms-types';
export type FormComponent = (TextBox | CheckBox | DropDown) & {
id: string;
type: string;
};