Browse Source

example

pull/24547/head
erdemcaygor 11 months ago
parent
commit
990f9890fa
  1. 124
      npm/ng-packs/apps/dev-app/src/app/home/custom-input.ts
  2. 3
      npm/ng-packs/apps/dev-app/src/app/home/home.component.html
  3. 47
      npm/ng-packs/apps/dev-app/src/app/home/home.component.ts
  4. 1
      templates/app/angular/src/app/home/home.component.html
  5. 75
      templates/app/angular/src/app/home/home.component.ts

124
npm/ng-packs/apps/dev-app/src/app/home/custom-input.ts

@ -0,0 +1,124 @@
import {
ChangeDetectionStrategy,
ChangeDetectorRef,
Component,
DestroyRef,
forwardRef,
inject,
Injector,
input,
OnInit,
} from '@angular/core';
import {
ControlValueAccessor,
FormBuilder,
FormControl,
FormControlName,
FormGroupDirective,
NG_VALUE_ACCESSOR,
NgControl,
FormGroup,
ReactiveFormsModule,
} from '@angular/forms';
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
import { FormFieldConfig } from '@abp/ng.components/dynamic-form';
const CUSTOM_INPUT_CONTROL_VALUE_ACCESSOR = {
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef(() => AppCustomInputComponent),
multi: true,
};
@Component({
selector: 'abp-dynamic-form-field',
template: `
<div [formGroup]="fieldFormGroup">
<input type="text" label="text label" formControlName="value" />
</div>
`,
providers: [
CUSTOM_INPUT_CONTROL_VALUE_ACCESSOR
],
changeDetection: ChangeDetectionStrategy.OnPush,
imports: [ReactiveFormsModule],
})
export class AppCustomInputComponent implements OnInit, ControlValueAccessor {
field = input.required<FormFieldConfig>();
visible = input<boolean>(true);
control!: FormControl;
fieldFormGroup: FormGroup;
readonly changeDetectorRef = inject(ChangeDetectorRef);
readonly destroyRef = inject(DestroyRef);
private injector = inject(Injector);
private formBuilder = inject(FormBuilder);
constructor() {
this.fieldFormGroup = this.formBuilder.group({
value: [{ value: '' }]
});
}
ngOnInit() {
const ngControl = this.injector.get(NgControl, null);
if (ngControl) {
this.control = this.injector.get(FormGroupDirective).getControl(ngControl as FormControlName);
}
this.value.valueChanges.pipe(takeUntilDestroyed(this.destroyRef)).subscribe(value => {
this.onChange(value);
});
}
writeValue(value: any[]): void {
this.value.setValue(value || '');
this.changeDetectorRef.markForCheck();
}
registerOnChange(fn: any): void {
this.onChange = fn;
}
registerOnTouched(fn: any): void {
this.onTouched = fn;
}
setDisabledState(isDisabled: boolean): void {
if (isDisabled) {
this.value.disable();
} else {
this.value.enable();
}
this.changeDetectorRef.markForCheck();
}
get isInvalid(): boolean {
if (this.control) {
return (this.control.invalid && (this.control.dirty || this.control.touched));
}
return false;
}
get errors(): string[] {
if (this.control && this.control.errors) {
const errorKeys = Object.keys(this.control.errors);
return errorKeys.map(key => {
const validator = this.field().validators.find(v => v.type.toLowerCase() === key.toLowerCase());
console.log(this.field().validators, key);
if (validator && validator.message) {
return validator.message;
}
// Fallback error messages
if (key === 'required') return `${this.field().label} is required`;
if (key === 'email') return 'Please enter a valid email address';
if (key === 'minlength') return `Minimum length is ${this.control.errors[key].requiredLength}`;
if (key === 'maxlength') return `Maximum length is ${this.control.errors[key].requiredLength}`;
return `${this.field().label} is invalid due to ${key} validation.`;
});
}
}
get value() {
return this.fieldFormGroup.get('value');
}
private onChange: (value: any) => void = () => {};
private onTouched: () => void = () => {};
}

3
npm/ng-packs/apps/dev-app/src/app/home/home.component.html

@ -1,5 +1,8 @@
<div class="container">
<abp-dynamic-form [fields]="formFields" (onSubmit)="submit($event)">
<ng-template #customInput>
<custom-input></custom-input>
</ng-template>
</abp-dynamic-form>
<div class="p-5 text-center">
<div class="d-inline-block bg-success text-white p-1 h5 rounded mb-4" role="alert">

47
npm/ng-packs/apps/dev-app/src/app/home/home.component.ts

@ -3,11 +3,19 @@ import { Component, inject, ViewChild } from '@angular/core';
import { NgTemplateOutlet } from '@angular/common';
import { ButtonComponent, CardBodyComponent, CardComponent } from '@abp/ng.theme.shared';
import { DynamicFormComponent, FormFieldConfig } from '@abp/ng.components/dynamic-form';
import { AppCustomInputComponent } from './custom-input';
@Component({
selector: 'app-home',
templateUrl: './home.component.html',
imports: [NgTemplateOutlet, LocalizationPipe, CardComponent, CardBodyComponent, ButtonComponent, DynamicFormComponent],
imports: [
NgTemplateOutlet,
LocalizationPipe,
CardComponent,
CardBodyComponent,
ButtonComponent,
DynamicFormComponent,
],
})
export class HomeComponent {
@ViewChild(DynamicFormComponent, { static: true }) dynamicFormComponent: DynamicFormComponent;
@ -22,10 +30,11 @@ export class HomeComponent {
required: true,
validators: [
{ type: 'required', message: 'First name is required' },
{ type: 'minLength', value: 2, message: 'Minimum 2 characters required' }
{ type: 'minLength', value: 2, message: 'Minimum 2 characters required' },
],
gridSize: 6,
order: 1
order: 1,
component: AppCustomInputComponent
},
{
key: 'lastName',
@ -33,11 +42,9 @@ export class HomeComponent {
label: 'Last Name',
placeholder: 'Enter last name',
required: true,
validators: [
{ type: 'required', message: 'Last name is required' }
],
validators: [{ type: 'required', message: 'Last name is required' }],
gridSize: 12,
order: 3
order: 3,
},
{
key: 'email',
@ -47,10 +54,10 @@ export class HomeComponent {
required: true,
validators: [
{ type: 'required', message: 'Email is required' },
{ type: 'email', message: 'Please enter a valid email' }
{ type: 'email', message: 'Please enter a valid email' },
],
gridSize: 6,
order: 2
order: 2,
},
{
key: 'userType',
@ -60,12 +67,10 @@ export class HomeComponent {
options: [
{ key: 'admin', value: 'Administrator' },
{ key: 'user', value: 'Regular User' },
{ key: 'guest', value: 'Guest User' }
],
validators: [
{ type: 'required', message: 'Please select user type' }
{ key: 'guest', value: 'Guest User' },
],
order: 4
validators: [{ type: 'required', message: 'Please select user type' }],
order: 4,
},
{
key: 'adminNotes',
@ -77,11 +82,17 @@ export class HomeComponent {
dependsOn: 'userType',
condition: 'equals',
value: 'admin',
action: 'show'
}
action: 'show',
},
],
order: 5
}
order: 5,
},
{
key: 'isSelected',
type: 'checkbox',
label: 'Is Selected',
order: 6,
},
];
loading = false;

1
templates/app/angular/src/app/home/home.component.html

@ -1,4 +1,5 @@
<div class="row mb-3">
<abp-dynamic-form [fields]="formFields" />
<div class="col-xl-6 col-12 d-flex">
<div class="card h-lg-100 w-100 overflow-hidden">
<div class="card-body">

75
templates/app/angular/src/app/home/home.component.ts

@ -1,16 +1,89 @@
import {AuthService, LocalizationPipe} from '@abp/ng.core';
import { Component, inject } from '@angular/core';
import {NgTemplateOutlet} from "@angular/common";
import {DynamicFormComponent, FormFieldConfig} from "@abp/ng.components/dynamic-form";
@Component({
selector: 'app-home',
templateUrl: './home.component.html',
styleUrls: ['./home.component.scss'],
imports: [NgTemplateOutlet, LocalizationPipe]
imports: [NgTemplateOutlet, LocalizationPipe, DynamicFormComponent]
})
export class HomeComponent {
private authService = inject(AuthService);
formFields: FormFieldConfig[] = [
{
key: 'firstName',
type: 'text',
label: 'First Name',
placeholder: 'Enter first name',
value: 'erdemc',
required: true,
validators: [
{ type: 'required', message: 'First name is required' },
{ type: 'minLength', value: 2, message: 'Minimum 2 characters required' }
],
gridSize: 6,
order: 1
},
{
key: 'lastName',
type: 'text',
label: 'Last Name',
placeholder: 'Enter last name',
required: true,
validators: [
{ type: 'required', message: 'Last name is required' }
],
gridSize: 12,
order: 3
},
{
key: 'email',
type: 'email',
label: 'Email Address',
placeholder: 'Enter email',
required: true,
validators: [
{ type: 'required', message: 'Email is required' },
{ type: 'email', message: 'Please enter a valid email' }
],
gridSize: 6,
order: 2
},
{
key: 'userType',
type: 'select',
label: 'User Type',
required: true,
options: [
{ key: 'admin', value: 'Administrator' },
{ key: 'user', value: 'Regular User' },
{ key: 'guest', value: 'Guest User' }
],
validators: [
{ type: 'required', message: 'Please select user type' }
],
order: 4
},
{
key: 'adminNotes',
type: 'textarea',
label: 'Admin Notes',
placeholder: 'Enter admin-specific notes',
conditionalLogic: [
{
dependsOn: 'userType',
condition: 'equals',
value: 'admin',
action: 'show'
}
],
order: 5
}
];
get hasLoggedIn(): boolean {
return this.authService.isAuthenticated;
}

Loading…
Cancel
Save