ngx-mm is an Angular developers toolkit for simplified Angular application development
I develop many applications and notice a lot of repeating patterns that I decided to move to a separate library. You can see a lot of connection to PrimeNG as I mainly use it in my Angular applications. If you see potential to be used with another library, don't hesitate to use it. If you find a bug or have an idea for improvement, you can create an issue with a good description.
x.y.z
x
- Angular versiony
- Generally add new feature(s). It can be breaking changesz
- Fixes
Angular | ngx-mm | Comments |
---|---|---|
14.x | 14.x.x | ... |
15.x | 15.x.x | ... |
15.x | 15.x.2 | Fix to suppor |
15.x | 15.2.x | Breaking changes or add new feature |
npm install ngx-mm --save
Import MMFormsModule
to your AppModule
@NgModule({
declarations: [
AppComponent
],
imports: [
BrowserModule,
AppRoutingModule,
MMFormsModule.forRoot({
// confgiuration
}, {
// providers
}),
],
providers: [
],
bootstrap: [AppComponent]
})
export class AppModule { }
Now you can use in your forms:
app.component.html
<form [formGroup]="myForm">
<mm-form-field formControlName="username" label="Username">
<ng-template mmFormControl let-control>
<input [formControl]="control">
</ng-template>
</mm-form-field>
</form>
app.component.ts
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
})
export class AppComponent {
myForm: FormGroup;
constructor(private formBuilder: FormBuilder) {
this.myForm = this.formBuilder.group({
username: [{value: null, disabled: false}, Validators.compose([
Validators.required,
Validators.minLength(3),
Validators.maxLength(5)
])]
})
}
}
Create your own implementation of MMErrorMessageResolver
.
export class CustomMessageResolver implements MMErrorMessageResolver {
resolveErrorMessage(key: string, value?: any, formControlName?: string | number | null): string {
switch (key) {
case 'required':
return 'This field is required';
case 'minlength':
return `The min length of ${value.requiredLength} characters is not reached, you typed in ${value.actualLength} characters`;
case 'maxlength':
return `The max length of ${value.requiredLength} characters is reached, you typed in ${value.actualLength} characters`;
default:
return 'This field is invalid'
}
}
}
Provide your implementation in global configuration. Additionally, you can also configure the default style, class, and behaviors in the global configuration.
The full list of configurations can be found below
@NgModule({
declarations: [
AppComponent
],
imports: [
BrowserModule,
AppRoutingModule,
MMFormsModule.forRoot({
fieldClass: 'field',
errorClass: 'text-red-900',
showMandatory: true,
mandatorySymbol: '#',
invalidOnTouch: true,
invalidOnDirty: false,
}, {
errorMessageResolver: CustomMessageResolver
}),
],
providers: [
],
bootstrap: [AppComponent]
})
export class AppModule { }
You have many options for overriding the global configuration:
- by providers
- by input
- by template
Wherever you can provide providers (module, component, routes) you can override the forms configuration.
...
providers: [
{
provide: MM_FORMS_CONFIG,
useValue: {}
},
{
provide: MMErrorMessageResolver,
useClass: CustomMessageResolver
}
]
...
Every possible configuration can be override by component Input
(all possible inputs are below).
...
<mm-form-field formControlName="field"
label="Username"
class="col-12"
[showMandatory]="false"
mandatorySymbol="#" labelStyleClass="text-red-500"
[invalidOnTouch]="true">
<ng-template mmFormControl let-control>
<input pInputText
[formControl]="control"
class="w-full"
[class.ng-dirty]="control?.touched && control?.invalid"
[class.ng-invalid]="control?.touched && control?.invalid">
</ng-template>
</mm-form-field>
...
If providers and inputs are not enough, you can use templates to modify the component (all possible templates are below).
...
<mm-form-field formControlName="field"
label="Username"
class="col-12"
[showMandatory]="false"
mandatorySymbol="#" labelStyleClass="text-red-500"
[invalidOnTouch]="true">
<ng-template mmFormControl let-control>
<input pInputText
[formControl]="control"
class="w-full"
[class.ng-dirty]="control?.touched && control?.invalid"
[class.ng-invalid]="control?.touched && control?.invalid">
</ng-template>
<ng-template mmMmFormLabel let-label>
MyLabel is {{label}}
</ng-template>
</mm-form-field>
...
Name | Type | Default | Description |
---|---|---|---|
label |
string | '' | Form field label |
id |
string | '' | Unique identifier of form field ("for" use case) |
helper |
string | '' | Help text for form field |
invalidOnTouch |
boolean | true | Show invalid state when form field is touched (use invalidOnTouch or invalidOnDirty not both) |
invalidOnDirty |
boolean | false | Show invalid state when form field is dirty (use invalidOnTouch or invalidOnDirty not both) |
reverseLabelControl |
boolean | false | Reverse order of label and control form |
style |
string | '' | Inline style of field |
styleClass |
string | 'field' | Style class of field |
labelStyle |
string | '' | Inline style of label |
labelStyleClass |
string | '' | Style class of label |
helperStyle |
string | '' | Inline style of helper |
helperStyleClass |
string | '' | Style class of helper |
errorStyle |
string | '' | Inline style of error |
errorStyleClass |
string | '' | Style class of error |
mandatorySymbol |
string | * | Symbol of mandatory |
mandatoryStyle |
string | '' | Inline style of mandatory |
mandatoryClass |
string | '' | Style class of mandatory |
showMandatroy |
boolean | true | When present show mandatory symbol if form contorol has required validator |
Template displaying form control. Required
<ng-template mmFormControl let-control></ng-template>
Context
Name | Type | Implicit |
---|---|---|
control | AbstractControl | true |
Template displaying form label.
<ng-template mmFormLabel let-label></ng-template>
Context
Name | Type | Implicit |
---|---|---|
label | string | true |
id | string | false |
mandatory | boolean | false |
showMandatory | boolean | false |
mandatorySymbol | string | false |
Template displaying form mandatory.
<ng-template mmFormMandatory let-mandatory></ng-template>
Context
Name | Type | Implicit |
---|---|---|
mandatory | boolean | true |
showMandatory | boolean | false |
mandatorySymbol | string | false |
Template displaying form helper.
<ng-template mmFormHelper let-helper></ng-template>
Context
Name | Type | Implicit |
---|---|---|
helper | string | true |
Template displaying errors
<ng-template mmFormError></ng-template>
Context
Name | Type | Implicit |
---|---|---|
message | string | true |
key | string | false |
value | string | false |
controlName | string | false |
MMConfig
export interface MMFormsConfig {
// Field
fieldClass?: string;
style?: string;
reverseLabelControl?: boolean;
// Label
labelClass?: string;
labelStyle?: string;
// Helper
helperClass?: string;
helperStyle?: string;
// Error
errorClass?: string;
errorStyle?: string;
// Mandatory
mandatoryClass?: string;
mandatoryStyle?: string;
mandatorySymbol?: string;
showMandatory?: boolean;
// Validation
invalidOnTouch?: boolean;
invalidOnDirty?: boolean;
}
MMErrorMessageResolver
export abstract class MMErrorMessageResolver {
public abstract resolveErrorMessage(key: string, value?: any, formControlName?: string | null | number): string;
}