Adding custom form components while using a library integration? #184
Replies: 1 comment 14 replies
|
Hey @scottmccaughey, thanks so much for the kind words, and for being an early adopter! I'd love to hear more about your experience so far - what's working well, what's confusing, any rough edges you've hit? I'm looking to continue improving it, and feedback from usage is very important for me :) To answer your question: Yes, you can add custom field types while using the built-in PrimeNG integration. No need to switch to a full custom integration. The import { provideDynamicForm } from '@ng-forge/dynamic-forms';
import { withPrimeNgFields } from '@ng-forge/dynamic-forms-primeng';
import { pickListFieldType, jsonEditorFieldType } from './custom-fields';
export const appConfig: ApplicationConfig = {
providers: [
provideDynamicForm(
...withPrimeNgFields(),
pickListFieldType, // Your custom PrimeNG PickList
jsonEditorFieldType // Your custom JSON Editor
),
],
};For reference, you can look at how the PrimeNG fields are implemented on our side. For most custom fields, you can use the json-editor.field.tsimport { FieldTypeDefinition, BaseValueField } from '@ng-forge/dynamic-forms';
import { valueFieldMapper } from '@ng-forge/dynamic-forms/integration';
export interface JsonEditorFieldDef extends BaseValueField<{ placeholder?: string }, object> {
type: 'json-editor';
}
export const jsonEditorFieldType: FieldTypeDefinition<JsonEditorFieldDef> = {
name: 'json-editor',
loadComponent: () => import('./json-editor.component'),
mapper: (fieldDef) => valueFieldMapper(fieldDef),
};
// Module augmentation for type-safety (optional)
declare module '@ng-forge/dynamic-forms' {
interface FieldRegistryLeaves {
'json-editor': JsonEditorFieldDef;
}
}json-editor.component.tsimport { Component, input } from '@angular/core';
import { FieldTree, FormField } from '@angular/forms/signals';
import { ValueFieldComponent } from '@ng-forge/dynamic-forms';
import { JsonTextareaComponent } from './json-textarea.component';
type JsonEditorComponent = ValueFieldComponent<JsonEditorFieldDef>;
@Component({
selector: 'df-json-editor',
imports: [JsonTextareaComponent, FormField],
template: `
@if (label()) {
<label [for]="key()">{{ label() }}</label>
}
<app-json-textarea [formField]="field()" />
`,
})
export default class JsonEditorComponent implements JsonEditorComponent {
readonly field = input.required<FieldTree<object>>();
readonly key = input.required<string>();
readonly label = input<string>();
}json-textarea.component.ts (FormValueControl wrapper)import { Component, model, signal, effect } from '@angular/core';
import { FormValueControl } from '@angular/forms/signals';
@Component({
selector: 'app-json-textarea',
template: `
<textarea
[value]="jsonString()"
(input)="onInput($event)"
[class.invalid]="parseError()"
rows="6"
></textarea>
@if (parseError()) {
<div class="error">{{ parseError() }}</div>
}
`,
})
export class JsonTextareaComponent implements FormValueControl<object> {
// FormValueControl interface - synced by [formField]
readonly value = model<object>({});
// Local string for the textarea (doesn't reset on invalid JSON)
protected readonly jsonString = signal('{}');
protected readonly parseError = signal<string | null>(null);
constructor() {
// Sync incoming object value -> string
effect(() => {
this.jsonString.set(JSON.stringify(this.value(), null, 2));
});
}
protected onInput(event: Event): void {
const text = (event.target as HTMLTextAreaElement).value;
this.jsonString.set(text);
try {
this.value.set(JSON.parse(text));
this.parseError.set(null);
} catch {
this.parseError.set('Invalid JSON');
}
}
}You can also find more details on building custom integrations here, I'll try to enhance the docs on this topic on the next iterations. |
Uh oh!
There was an error while loading. Please reload this page.
Thanks for all the work you've put into this library - it's really great.
I started off building a custom integration for my project, but ran into some issues and ended up using the PrimeNG integration instead. That said, I still need to add a couple of custom field types (a PickList, which is built into PrimeNG, and a JSON Editor, which is not). Is there a way to add custom field types while still using the built-in PrimeNG integration, or do I need to switch back to a full custom integration?
All reactions