Project Name | Stars | Downloads | Repos Using This | Packages Using This | Most Recent Commit | Total Releases | Latest Release | Open Issues | License | Language |
---|---|---|---|---|---|---|---|---|---|---|
Mitosis | 8,887 | 6 | a day ago | 110 | July 28, 2021 | 142 | mit | TypeScript | ||
Write components once, run everywhere. Compiles to React, Vue, Qwik, Solid, Angular, Svelte, and more. | ||||||||||
Builder | 5,127 | 4 | 38 | 7 hours ago | 634 | September 23, 2022 | 98 | mit | TypeScript | |
Drag and drop headless CMS for React, Vue, Svelte, Qwik, and more | ||||||||||
Formio.js | 1,610 | 104 | 95 | 8 hours ago | 1,058 | July 15, 2022 | 775 | mit | JavaScript | |
JavaScript powered Forms with JSON Form Builder | ||||||||||
Angular Builders | 1,080 | 137 | 84 | a day ago | 102 | June 13, 2022 | 53 | mit | TypeScript | |
Angular build facade extensions (Jest and custom webpack configuration) | ||||||||||
Django Report Builder | 699 | 2 years ago | 54 | other | Python | |||||
This is a github mirror for django-report-builder which is hosted on Gitlab. Django Report Builder is a GUI for Django ORM. Build custom queries and display results. Targets sys admins and capable end users who might not be able to program. | ||||||||||
Angular Form Builder | 618 | 5 years ago | 1 | March 13, 2017 | 60 | mit | CoffeeScript | |||
Drag and drop to build bootstrap forms in AngularJS. | ||||||||||
Angular Pizza Creator | 447 | 3 years ago | 2 | TypeScript | ||||||
Source code for Angular advanced Form APIs pizza builder | ||||||||||
Loopback Sdk Builder | 407 | 110 | 11 | 3 years ago | 69 | May 30, 2018 | 114 | other | HTML | |
Tool for auto-generating Software Development Kits (SDKs) for LoopBack | ||||||||||
Spring Flo | 271 | 2 | 3 months ago | 26 | September 23, 2021 | 12 | apache-2.0 | TypeScript | ||
JavaScript angular based embeddable graphical component for pipeline/graph building and editing | ||||||||||
Ngtron | 179 | 3 | a year ago | 40 | February 12, 2021 | 38 | mit | TypeScript | ||
Easily serve and build angular based electron applications |
FormBuilder + class-transformer-global-storage + class-validator-multi-lang = dynamic form group builder for Angular
npm i --save class-transformer-global-storage class-validator-multi-lang ngx-dynamic-form-builder
Version above 2 has a completely rewritten code, partially backwards compatible
Now @Expose
and @Exclude
decorators are used to define model fields, the new version is rigidly dependent on class-transform
Dependencies are not used original, but forks with additional necessary properties, when using this library, you need to replace all original imports with forks with modifications
Fork class-validator-multi-lang - adds translation capability for errors (PR:https://github.com/typestack/class-validator/pull/743)
Fork class-transformer-global-storage - adds the ability to get meta information about all used classes (PR:https://github.com/typestack/class-transformer/pull/929)
For correct parse metadata, need remove compilerOptions.downlevelIteration
and append compilerOptions.emitDecoratorMetadata: true
in tsconfig.json
Demo - Demo application with ngx-dynamic-form-builder.
Stackblitz - Simply sample of usage on https://stackblitz.com
company.ts
import { Validate, IsNotEmptym } from 'class-validator-multi-lang';
import { TextLengthMore15 } from '../utils/custom-validators';
import { marker } from '@ngneat/transloco-keys-manager/marker';
import { Expose, Type } from 'class-transformer-global-storage';
export class Company {
@Expose()
id: number;
@Validate(TextLengthMore15, {
message: marker('The company name must be longer than 15'),
})
@IsNotEmpty()
@Expose()
name: string;
constructor(data?: any) {
if (data === undefined) {
data = {};
}
this.id = data.id;
this.name = data.name;
}
}
app.module.ts
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
import { CompanyPanelComponent } from './company-panel.component';
@NgModule({
imports: [
...
FormsModule,
ReactiveFormsModule,
...
],
declarations: [
...
CompanyPanelComponent,
...
],
...
})
export class AppModule {}
company-panel.component.html
<form [formGroup]="form" *ngIf="form?.customValidateErrors | async as errors" novalidate>
<input formControlName="name" placeholder="Name" />
<p *ngIf="errors.name?.length">Error: {{errors.name[0]}}</p>
<p>Form status: {{ form.status | json }}</p>
<p>Form class-validator-multi-lang errors: {{errors|json}}</p>
<p *ngIf="savedItem">Saved item: {{savedItem|json}}</p>
<button (click)="onLoadClick()">Load</button>
<button (click)="onClearClick()">Clear</button>
<button (click)="onSaveClick()" [disabled]="!form.valid">Save</button>
</form>
company-panel.component.ts
import { DynamicFormGroup, DynamicFormBuilder } from 'ngx-dynamic-form-builder';
import { Company } from './../../shared/models/company';
import { Input, Component } from '@angular/core';
import { Validators } from '@angular/forms';
@Component({
selector: 'company-panel',
templateUrl: './company-panel.component.html',
})
export class CompanyPanelComponent {
form: DynamicFormGroup<Company>;
@Input()
item = new Company({
id: 11,
name: '123456789012345',
});
fb = new DynamicFormBuilder();
savedItem?: Company;
constructor() {
this.form = this.fb.rootFormGroup(Company, {
name: '',
});
}
onLoadClick(): void {
this.savedItem = undefined;
this.form.object = this.item;
}
onClearClick(): void {
this.savedItem = undefined;
this.form.object = new Company();
}
onSaveClick(): void {
if (this.form.valid) {
this.savedItem = this.form.object;
} else {
this.savedItem = undefined;
}
}
}
custom-validators.ts
import { ValidatorConstraintInterface, ValidatorConstraint } from 'class-validator-multi-lang';
@ValidatorConstraint()
export class TextLengthMore15 implements ValidatorConstraintInterface {
validate(text: string) {
return text ? text.length > 15 : false;
}
}
Because multi-language supported in class-validator-multi-lang, now ngx-dynamic-form-builder also support this feature
set validation messages as settings when create form group
this.form = this.fb.rootFormGroup(
Company,
{
name: '',
},
{
classValidatorOptions: {
messages: {
'The company name must be longer than 15': 'company name must be longer than 15 (translate on other language)',
},
},
}
);
set validation messages on runtime after for exists form group
this.form.patchDynamicFormBuilderOptions({
classValidatorOptions: {
messages: {
'The company name must be longer than 15': 'company name must be longer than 15 (translate on other language)',
},
},
});
set translate property name in error
this.form.patchDynamicFormBuilderOptions({
classValidatorOptions: {
titles: {
regionNum: 'number of region (translate property name in error on other language)',
},
},
});
set validation messages and properties name global for all instance of form group in project
setGlobalDynamicFormBuilderOptions({
classValidatorOptions: {
messages: {
'The company name must be longer than 15': 'company name must be longer than 15 (translate on other language)',
},
titles: {
regionNum: 'number of region (translate property name in error on other language)',
},
},
});
The customValidateErrors property can be subscribed for cases in which your code should act on changes in errors
company-panel.component.html
<form [formGroup]="form" *ngIf="form?.customValidateErrors | async as errors" novalidate>
<input formControlName="name" placeholder="Name" />
<p *ngIf="errors.name?.length">Error: {{errors.name[0]}}</p>
<p>Form status: {{ form.status | json }}</p>
<p>Observable validation errors: {{errors|json}}</p>
<p *ngIf="savedItem">Saved item: {{savedItem|json}}</p>
<button (click)="onLoadClick()">Load</button>
<button (click)="onClearClick()">Clear</button>
<button (click)="onSaveClick()" [disabled]="!form.valid">Save</button>
</form>
company-panel.component.ts
import { DynamicFormGroup, DynamicFormBuilder } from 'ngx-dynamic-form-builder';
import { Company } from './../../shared/models/company';
import { Input, Component } from '@angular/core';
import { Validators } from '@angular/forms';
import { Subscription } from 'rxjs';
@Component({
selector: 'company-panel',
templateUrl: './company-panel.component.html',
})
export class CompanyPanelComponent implements onDestroy {
form: DynamicFormGroup<Company>;
@Input()
item = new Company({
id: 11,
name: '123456789012345',
});
@Input()
strings = Company.strings;
fb = new DynamicFormBuilder();
savedItem?: Company;
errorChangeSubscription: Subscription;
constructor() {
this.form = this.fb.rootFormGroup(Company, {
name: '',
});
this.errorChangeSubscription = this.form.customValidateErrors.subscribe((allErrors) => {
console.log(`Errors changed: ${allErrors}`);
});
}
ngOnDestroy() {
if (this.errorChangeSubscription != null && this.errorChangeSubscription.closed === false) {
this.errorChangeSubscription.unsubscribe();
}
}
onLoadClick(): void {
this.savedItem = undefined;
this.form.object = this.item;
this.form.validateAllFormFields();
}
onClearClick(): void {
this.savedItem = undefined;
this.form.object = new Company();
this.form.validateAllFormFields();
}
onSaveClick(): void {
this.form.validateAllFormFields();
if (this.form.valid) {
this.savedItem = this.form.object;
} else {
this.savedItem = undefined;
}
}
}
MIT