ngx-nz-formly
TypeScript icon, indicating that this package has built-in type declarations

0.0.11 • Public • Published

NgxNzFormly

This library was generated with Angular CLI version 16.2.0.
The only best library to integrate ngx-formly with ng-zorro

Installation

Angular version 16.x.x
Adding ngx-nz-formly to your application is super easy but in order to use ngx-nz-formly you should install three more packages.

Install ng-zorro-antd

$ npm install ng-zorro-antd --save

Import the pre-built stylesheet in angular.json

{
  "styles": [
    "node_modules/ng-zorro-antd/ng-zorro-antd.min.css"
  ]
}

Install ngx-formly

$ npm install @angular/forms @ngx-formly/core --save

Install ngx-mask

$ npm insatll ngx-mask --save

Install Bootstrap (Optional)

If you want to find the final demo more clearly and beautiful, install bootstrap, too.

$ npm insatll bootstrap --save

Then add following lines to angular.json

{
  "styles": [
    ...
    "node_modules/bootstrap/dist/css/bootstrap.min.css",
    "src/styles.css"
  ],
  "scripts": [
    ...
    "node_modules/bootstrap/dist/js/bootstrap.min.js"
  ]
}

Install ngx-nz-formly

$ npm install ngx-nz-formly --save

Last step is to add below modules to app.module.ts

@NgModule({
  declarations: [...],
  imports: [
    ...,
    OverlayModule,
    HttpClientModule,
    BrowserAnimationsModule,
    NgxMaskModule.forRoot({}),
    FormlyModule.forRoot(NzFormlyForRoot),
  ],
  providers: [
    ...,
    { provide: NZ_I18N, useValue: en_US }
  ],
})
export class AppModule {}

As an explanation, HttpClientModule and providers relates to Ant design setup. In order to use special masks on inputs, you need to add NgxMaskModule, too. At last, we have OverlayModule, BrowserAnimationsModule and FormlyModule to complete the setup. Finally, you need NzFormlyForRoot config to FormlyModule for root to be able to have your formly with Ant Design.

Usage

add below html code to your app.component.html

<formly-form
  [form]="form"
  [fields]="fields"
  [model]="model"
></formly-form>

Finally, your app.component.ts file could be something like following box. So please take this as sample documentation of available features, until I write one

class FormModel {
  firstName: string;
  lastName: string;
  phoneNumber: string;
  email: string;
  password: string;
  budget: number;
  age: number;
  olderThan20: boolean;
  allowNotifications: boolean;
  city: any;
  gender: string;

  constructor(element: any) {
    this.firstName = element?.firstName;
    this.lastName = element?.lastName;
    this.phoneNumber = element?.phoneNumber;
    this.email = element?.email;
    this.password = element?.password;
    this.budget = element?.budget;
    this.age = element?.age;
    this.olderThan20 = element?.olderThan20;
    this.allowNotifications = element?.allowNotifications;
    this.city = element?.city;
    this.gender = element?.gender;
  }
}

@Component({
  selector: "app-root",
  templateUrl: "./app.component.html",
  styleUrls: ["./app.component.scss"],
})
export class AppComponent implements OnInit {
  model = new FormModel({});
  form = new FormGroup({});
  fields: FormlyFieldConfig[] = [];
  labelObs$ = new BehaviorSubject("Label");

  ngOnInit() {
    this.initForm();
    from(["Label 1", "Label 2", "Label 3"])
      .pipe(concatMap(item => of(item).pipe(delay(1000))))
      .subscribe(item => this.labelObs$.next(item));
  }

  initForm() {
    const fb = new NzFormlyFieldBuilder<FormModel>();
    this.fields = [
      fb.input("firstName", {
        className: "px-2",
        props: {
          labelPosition: "float",
          required: true,
          minLen: 3,
          showError: false,
          labelObs: this.labelObs$,
          focus: () => console.log("input focused"),
          blur: () => console.log("input blurred"),
          styles: {
            labelWidth: "110px",
            wrapperClass: "mb-4",
          },
        },
        validators: {
          validation: ["minLen"],
        },
      }),
      fb.input("lastName", {
        className: "px-2",
        props: {
          required: true,
          maxLen: 10,
          labelPosition: "top",
          label: "Last Name",
          styles: {
            labelWidth: "110px",
            wrapperClass: "mb-4",
          },
        },
        validators: {
          validation: ["maxLen"],
        },
      }),
      fb.input("phoneNumber", {
        className: "px-2",
        props: {
          label: "Phone No",
          mask: "phone",
          placeholder: "e.x. 9127403028",
          styles: {
            labelWidth: "110px",
            wrapperClass: "mb-4",
          },
        },
      }),
      fb.input("email", {
        className: "px-2",
        props: {
          required: true,
          label: "Email address",
          placeholder: "e.x. sajjad@gmail.com",
          styles: {
            labelWidth: "110px",
            wrapperClass: "mb-4",
          },
          change: (field, event) => console.log("input changed to:", event),
        },
        validators: {
          validation: ["email"],
        },
      }),
      fb.input("password", {
        className: "px-2",
        props: {
          required: true,
          type: "password",
          label: "Password",
          placeholder: "use complex one",
          styles: {
            labelWidth: "110px",
            wrapperClass: "mb-4",
          },
        },
        validators: {
          validation: ["password"],
        },
      }),
      fb.input("budget", {
        className: "px-2",
        props: {
          nzPrefix: "$",
          label: "Budget",
          mask: "separator.2",
          thousandSeparator: ",",
          nzAddOnBeforeIcon: "wallet",
          placeholder: "e.x. 2000",
          styles: {
            labelWidth: "110px",
            wrapperClass: "mb-4",
          },
          change: (field, event) => console.log("number changed to:", event),
          focus: () => console.log("number focused"),
          blur: () => console.log("number blurred"),
        },
        validators: {
          custom: {
            expression: (control: FormControl) => control.value > 2500,
            message: "Your budget is less than expected budget",
          },
        },
      }),
      fb.checkbox("olderThan20", {
        className: "px-2 mb-4",
        props: {
          label: "I am older that 20",
          change: (field, event) => console.log("checkbox changed to:", event),
        },
      }),
      fb.input("age", {
        className: "px-2",
        props: {
          minValue: 20,
          maxValue: 100,
          label: "Age",
          placeholder: "enter your age",
          styles: {
            labelWidth: "110px",
            wrapperClass: "mb-4",
          },
        },
        expressionProperties: {
          "props.disabled": model => !model.olderThan20,
        },
        validators: {
          validation: ["minValue", "maxValue"],
        },
      }),
      fb.switch("allowNotifications", {
        className: "px-2",
        props: {
          nzCheckedChildren: "1",
          nzUnCheckedChildren: "0",
          label: "Allow notifications",
          styles: {
            labelWidth: "auto",
            wrapperClass: "mb-4",
          },
          change: (field, event) => console.log("switch changed to:", event),
        },
        expressionProperties: {
          "props.hidden": model => !model.olderThan20,
        },
      }),
      fb.select("city", {
        className: "px-2",
        props: {
          objectValue: false,
          label: "City",
          nzAllowClear: true,
          nzShowSearch: true,
          placeholder: "select your city",
          styles: {
            labelWidth: "110px",
            wrapperClass: "mb-4",
          },
          nzOptionOverflowSize: 4,
          nzOptions: [
            {
              label: "Zanjan",
              value: "Znj",
              nzCustomContent: `<strong>Zanjan</strong>`,
            },
            {
              label: "Tehran",
              value: "Teh",
              nzCustomContent: `<i>Tehran</i>`,
            },
            {label: "Isfahan", value: "Isf"},
            {label: "Shiraz", value: "Shi"},
            {label: "Gilan", value: "Gil"},
          ],
          nzFilterOption: (input?: string, option?: NzOptionComponent) => {
            return option?.nzLabel?.toString().includes(input || "") || false;
          },
          compareWith: (o1: any, o2: any): boolean => o1 == o2,
          nzOpenChange: event => console.log("selection open status:", event),
          nzScrollToBottom: () => console.log("scroll"),
          nzOnSearch: event => console.log("search", event),
          change: (field, event) => console.log("selection changed to:", event),
        },
        expressionProperties: {
          "props.disabled": model => !model.olderThan20,
        },
      }),
      fb.radio("gender", {
        className: "px-2",
        props: {
          label: "Gender",
          nzType: "nz-radio-button",
          styles: {
            labelWidth: "110px",
          },
          nzOptions: [
            {
              label: "Male",
              value: "Male",
            },
            {
              label: "Female",
              value: "Female",
            },
            {
              label: "None",
              value: null,
            },
          ],
          nzButtonStyle: "solid",
          change: (field, event) => console.log("Radio changed to:", event),
        },
      }),
      fb.button({
        className: "d-flex",
        props: {
          text: "Reset",
          nzType: "primary",
          nzLoading: false,
          nzDanger: false,
          nzBlock: true,
          click: () => console.log("clicked"),
        },
      }),
    ];
  }

  onSubmit() {
    // Object.keys(this.form.controls).forEach(key => {
    //   console.log(key, this.form.get(key)?.errors);
    // });
    // console.log(this.model);
  }
}

Appreciate

At last, I want to thank every one of you who supports and use the provided library. Be sure that there are lots of more features coming up. So please share your feedbacks and comments with me. I will be so happy of getting more of them.

Package Sidebar

Install

npm i ngx-nz-formly

Weekly Downloads

7

Version

0.0.11

License

MIT

Unpacked Size

510 kB

Total Files

37

Last publish

Collaborators

  • sajjadbayat
  • zahramokhtari