npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

ngx-myform

v2.0.3

Published

Easy to use,Flexible,Simple,Powerful Angular 4+ module with Bootstrap v4 ui for Rapid Form Development; # Demo screenShot: ### pic1:Normal ![pic1](https://lh3.googleusercontent.com/m4fZd7U4NhNMPj65LNOLc0edVcoOzv9EmMLwKFSL4DbDfV9yWzyDhNo3yjWqCWpknneJO4-Rtw

Downloads

161

Readme

ngx-myform

Easy to use,Flexible,Simple,Powerful Angular 4+ module with Bootstrap v4 ui for Rapid Form Development;

Demo screenShot:

pic1:Normal

pic1

pic2:Use Bootstrap 4 Grid

pic2

Table of Contents

Installation

Usage

FormConfig

ModelTypes

ModelConfig

demo repository

Installation

$ npm install ngx-myform --save
$ yarn add ngx-myform

Usage

Once you have installed the library, you need some preparations:

1: set bootstrap v4 global style if your app based on angular-cli see here; how to configure global style for example:

"styles": [
   "../node_modules/bootstrap/dist/css/bootstrap.css",
   "styles.css"
],

2: import the module:

// Import your library
import { NgxMyFormModule } from 'ngx-myform';
@NgModule({
  declarations: [
    AppComponent
  ],
  imports: [
    BrowserModule,
    NgxMyFormModule.forRoot(),
    ...
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }

3:in you component YourComponent.ts

import { Component, OnInit } from '@angular/core';
import { FormConfig, InputModel, GroupModel, TextareaModel, SelectModel, RadiogroupModel, CheckboxGroupModel, CheckboxModel, } from 'ngx-myform';
import { FormGroup, Validators, ValidatorFn, AbstractControl, ValidationErrors } from '@angular/forms';
function customeValidator(): ValidatorFn {
  return (g: FormGroup) => {
    return g.get('password').value === g.get('repassword').value
      ? null : { mismatch: true };
  }
}
function customValidatorOtherFormat(g: FormGroup) {
  return g.get('password').value === g.get('repassword').value
    ? null : { mismatch: true };
}
function customEmailValidator(): ValidatorFn {
  return (c: AbstractControl) => {
    if (!c.value) { return null; }
    const reg = /^\w+([\.-]?\w+)*@\w+([\.-]?\w+)*(\.\w{2,3})+$/;
    return reg.test(c.value) ? null : { email_validator_key: true }
  }
}
function customEmailduplicated(control: AbstractControl) {
  const q = new Promise<{ [key: string]: boolean }>((resolve, reject) => {
    setTimeout(() => {
      if (control.value === '[email protected]') {
        resolve({ 'duplicated': true });
      } else {
        resolve(null);
      }
    }, 1000);
  });
  return q;
}
function customCheckboxGroupValidator_1(g: FormGroup) {
  return g.get('checkbox_4').value
    ? null : { shouldlike: true };
}
function customCheckboxGroupValidator_2(g: FormGroup) {
  const num = Object.keys(g.controls).reduce((curr, key) => {
    if (g.get(key).value) {
      curr++;
    }
    return curr;
  }, 0);
  return num > 2 ? null : {
    shouldlikeatleast: true
  }
}
@Component({
  selector: 'app-demo1',
  templateUrl: './demo1.component.html',
  styleUrls: ['./demo1.component.css'],
})
export class Demo1Component implements OnInit {
  models = [
    new InputModel({
      id: 'username',
      label: 'username:(use custom class `label_class_1`)',
      validators: [
        { key: 'required', validator: Validators.required, message: 'username is required' },
        { key: 'minlength', validator: Validators.minLength(3), message: 'username must 3 chars at least' }
      ],
      wrappersClass: {
        labelWrapper: ['label_class_1'],
      },
    }),

    new InputModel({
      id: 'age',
      label: 'your age:',
      disabled: true,
      value: "it's a secret :)"
    }),
    new InputModel({
      id: 'niceperson',
      label: '<div style="color:blue;">a nice person?(html label support)</div>',
      value: 'definitly',
      attributes: {
        readonly: 'readonly',
      }
    }),
    new InputModel({
      id: 'avatar',
      label: 'avatar:',
      attributes: {
        type: 'file',
        multiple: 'multiple'
      },
      events: {
        change: (e) => {
          console.log(e.target.files);
        }
      }
    }),
    new CheckboxGroupModel({
      id: 'intrests',
      // inline: false,
      label: 'what do you like:',

      options: [
        {
          id: 'checkbox_1',
          checkLabel: 'basketball',
        },
        {
          id: 'checkbox_2',
          checkLabel: 'football',
        },
        {
          id: 'checkbox_3',
          checkLabel: 'swimming',
        },
        {
          id: 'checkbox_4',
          checkLabel: 'reading',
        },
        {
          id: 'checkbox_5',
          checkLabel: 'music',
        },
      ],
      validators: [
        { key: 'shouldlike', validator: customCheckboxGroupValidator_1, message: 'why not like reading?' },
        { key: 'shouldlikeatleast', validator: customCheckboxGroupValidator_2, message: 'you should like at least 3 item' }
      ],
    }),
    new GroupModel({
      id: 'passwordGroup',
      group: [
        new InputModel({
          id: 'password',
          label: 'password:',
          // disabled: true,
          attributes: {
            type: 'password',
          },
          validators: [
            { key: 'required', validator: Validators.required, message: 'password is required' }
          ],
        }),
        new InputModel({
          id: 'repassword',
          label: 're-password:',

          attributes: {
            type: 'password',
          },
          validators: [
            { key: 'required', validator: Validators.required, message: 'please retype your password' }
          ],
        }),
      ],
      validators: [
        { key: 'mismatch', validator: customeValidator(), message: 'the password not match' },
      ],
    }),
    new InputModel({
      id: 'email',
      label: 'email:',

      prefix: {
        html: '@',
        class: ['input-group-addon'],
      },
      validators: [
        { key: 'email_validator_key', validator: customEmailValidator(), message: 'invalid Email' }
      ],
      asyncValidators: [
        { key: 'duplicated', validator: customEmailduplicated, message: 'Email is already existed!' }
      ],
      wrappersClass: {
        controlWrapper: ['input-group']
      },
    }),
    new InputModel({
      id: 'phone',
      label: 'phone number:',

      validators: [
        { key: 'required', validator: Validators.required, message: 'please fill the phone number' }
      ],
    }),
    new InputModel({
      id: 'verificationcode',
      label: 'verifacation code:',

      validators: [{ key: 'required', validator: Validators.required, message: 'this is required' }],
      suffix: {
        html: '<button type="button" class="btn btn-success" onclick="alert(\'send me verificaton code!\');">send code</button>',
        class: ['border-0', 'ml-3', 'p-0'],
      },
      wrappersClass: {
        controlWrapper: ['input-group']
      },
    }),
    new SelectModel({
      id: 'country',
      label: 'country:',

      value: 'england',
      options: [
        { label: 'select one country', value: '' },
        { label: 'China', value: 'china' },
        { label: 'USA', value: 'usa' },
        { label: 'Japan', value: 'japan' },
        { label: 'England', value: 'england' },
        { label: 'France', value: 'france' },
      ],
      validators: [
        { key: 'required', validator: Validators.required, message: 'country is required' }
      ],
      events: {
        change: () => {
          console.log('ok--changed!');
        }
      }
    }),
    new SelectModel({
      id: 'occupation',
      attributes: {
        multiple: 'multiple',
      },
      label: 'occupation:',
      validators: [{ key: 'required', validator: Validators.required, message: 'occupation is required' }],
      options: [
        { label: 'Programmer', value: 'programmer' },
        { label: 'Teacher', value: 'teacher' },
        { label: 'Dodctor', value: 'doctor' },
        { label: 'Driver', value: 'driver' }
      ],
    }),
    new RadiogroupModel({
      id: 'gender:',
      label: 'gender:',
      legend: {
        value: 'Radio Group Legend!',
      },
      inline: true,
      options: [
        { label: 'Male', value: 'male' },
        { label: 'Female', value: 'female' },
        { label: 'xxx', value: 'xxx', disabled: true }
      ],
      validators: [
        { key: 'required', validator: Validators.required, message: 'the gender is required' }
      ],
    }),
    new CheckboxModel({
      id: 'agree',
      value: true,
      required: true,
      checkLabel: 'agree some terms?',
      validators: [
        { key: 'required', validator: Validators.required, message: 'you must agree these terms' }
      ],
    }),
  ];
  formConfig: FormConfig = {
    models: this.models,
    attributes: {
      autocomplete: 'off',
    },
    showErrorsOnSubmit: true,
  };
  constructor() { }
  ngOnInit() {
  }

  test_submit(form) {
    console.log('test_submit', form.value);
  }
  test_change(data) {
    console.log('test_change', data);
  }
}

4: in the template YourComponent.html;

<ngx-bootstrap-form [formConfig]="formConfig" (ngSubmit)="test_submit($event);" #myform (ngValueChange)='test_change($event);'>
  <button class="btn btn-primary" type="submit">submit</button>
</ngx-bootstrap-form>

FormConfig

say it's easy to use,because,you just need to configure a json format data; and bind this data to the ngx-bootstrap-form form component;

interface FormConfig {
    models: BaseModel[],
    attributes?: { [key: string]: string },
    wrappersClass?: WrappersClassInterFace,
    showErrorsOnSubmit?: boolean;
}

models:

models is an array in which the basic form elements are include for exaple: InputModel represents input element SelectModel represents select element.

attributes:

you can use dynamically set any attibute for your form attributes:{ 'autocomplete':'off', } the form will add "autocomplete"="off" to you form

wrappersClass:

before talking about The "wrappersClass";let's see the DOM structuor for a model,pseudo code:

<div mainWrapper>
  <label labelWrapper></label>
  <div secondaryWrapper>
    <div controlWrapper>
      <div prefix></div>
      input|select|radio|checkbox|radiogroup|checkgroup...
      <div suffix></div>
    </div>
    <div form-conrol-feedback>some error message</div>
  </div>
</div>

if you are familar with bootstrap v4 it should be easy to understand;it's based on the bootstrap form structor; so,the purpose of WrappersClass is just Globally configure for form layout while every model also has this individually;

you can custom any class with:

{
   models:...
   attributes:...
   wrappersClass:{
      mainWrapper:['custom_class_1','custom_class_2',...],
      labelWrapper:[...],
      ....
   },
   ...
}

ModelTypes

InputModel, TextareaModel, SelectModel, CheckboxModel, RadiogroupModel, CheckboxGroupModel,GroupModel

GroupModel is a special model which used for creating FormGroup; for example:

models=[
   new InputModel({...}),
   ...
   new GroupModel({
      id:'anyid',
      group:[// the `group` is the same as the `model`;
         new InputModel({...}),
         new SelectModel({...}),
         ....
      ],
   }),
   new CheckBoxModel({...}),
   ...
];

ModelConfig

{
 id: string;
 value?: string | boolean;
 disabled?: boolean;
 attributes?: { [key: string]: string };
 events?: { [key: string]: (any) => void };
 validators?: {
     key: string,
     validator: ValidatorFn | ValidationErrors,
     message?: string,
 }[];
 asyncValidators?: {
     key: string,
     validator: AsyncValidatorFn | ValidationErrors,
     message?: string,
 }[];
 wrappersClass?: WrappersClassInterFace;
 label?: {
     html?: string,
     class?: Array<string>,
 };
 prefix?: {
     html?: string,
     class?: Array<string>,
 };
 suffix?: {
     html?: string,
     class?: Array<string>,
 };    
}

License

MIT © [guzuomuse] "# ngx-myform"