1.0.5 • Published 4 months ago

form-builder-dynamically v1.0.5

Weekly downloads
-
License
MIT
Repository
-
Last release
4 months ago

Angular Dynamic Form Builder

Using Angular Reactive Forms Module

Features

It Works with any type of inputs, textarea and selects and featured a custom type
called `select-with-input` that gives you a div contains an input field and select
to be used together ex. phone number
If you used Input Type File you can easily get
File object of your uploaded file and base64Url of this file
You can easily detect any changes happens in the form using
formChanges EventEmitter with detectChange boolean value equals true

Just install it and call the DynamicFormBuilderModule inside your module or standalone component then use the component

It Works Fine For Angular v14 and upper and compatible with SSR

for more Info Angular Dynamic Form Builder Repo for more Info Angular Dynamic Form Builder NPM

Note That All Styles Classe must be in styles.css or inside your component style using

:host ::ng-deep {
  // class names
}

Style Inputs

Input.TypeDescription
formClassesstringset a class or more for the form tag
inputContainerstringset class or more for div which include the div holds label and input and shared across all input types
inputFieldClassesstringset a class or more for a div that contains label and input tag and this for all types of inputs except ('checkbox' , 'radio' , 'file' , 'select' , 'select-with-file')
radioFieldClassesstringset a class or more for a div that contains label and input type radio
checkboxFieldClassesstringset a class or more for a div that contains label and input type checkbox
fileFieldClassesstringset a class or more for div that contains label, input file and button that trigger input incase you want to hide input and can by styled using parent class and the tag
selectFieldClassesstringset a class or more for a div that contains label and select tag
selectWithInputClassesstringset a class or more for a div that contains label and a another div contains select tag and input tag
requiredStarClassesstringset a class or more for the required *
errorAndBtnClassesstringset a class or more for a div outside the form that contains div for error messages and submit button
errorMsgClassesstringset a class or more for a div that will contain the error message
buttonClassesstringset a class or more for the submit button
inputTagClassesstringset a class or more for input tag
radioTagClassesstringset a class or more for radio input tag
checkboxTagClassesstringset a class or more for checkbox input tag
selectTagClassesstringset a class or more for select tag
inputTagLabelClassesstringset a class or more for input tag label
radioTagLabelClassesstringset a class or more for radio input tag label
checkboxTagLabelClassesstringset a class or more for checkbox input tag label
selectTagLabelClassesstringset a class or more for select tag label
fileTagLabelClassesstringset a class or more for file input tag label
inputWithSelectTagLabelClassesstringset a class or more for input with select tag label

Text Inputs

Input.TypeDescription
requiredStarContentstringby default a * and can be changed and accept html tags and also accepts html input, ex. <span>**</span>
errorMsgstringerror msg that will be shown, ex. after submit and api return an error should create a variable that holds the error message and put it in this input
buttonTextstringinner text inside the submit button, by default Submit

Features For Form Inputs

Input.TypeDescription
formConfigFormConfig[]this is required to initiate the component and includes all inputs configs
resetAfterSubmitbooleanif true it will reset the form after submit ex. you can set a variable to be true after submitting the form
detectChangebooleanthis is required with formChanges Output event
isDisabledbooleanif true the submit button will be disabled
invalidDisablebooleanif true the submit button will be disabled if the form is invalid

Outputs

Output.Description
getFormDataEventEmitter that gets FormGroup object on submit
formChangesEventEmitter that gets FormGroup object on every change but must detectChange input set to true
fileDataEventEmitter that gets object from uploaded contains file and base64Url for it

FormConfig Interface

General Properties.TypeDescription
namestringrequired for every input
typestringrequired for every input
idstringrequired for every input
labelstringrequire id if using with radio or checkbox
isRequiredbooleanset input required field and automatic display required star
placeholderstringplaceholder for each input
patternstring or RegExpRegex pattern for each input
valuestring or boolean or numberif you want to set a value for the input ex. if you entered edit page that restore the data
minLengthstring or numbermin length of input
maxLengthstring or numbermax length of input
autocompletestringset autocomplete to off
Custom Properties.TypeDescription
isPasswordbooleanrequired if type is password and you'll use show hide for password
eyeShowstringif wanna change img of show password
eyeHidestringif wanna change img of hide password
iconUrlstringif user wanna put icon inside input
optionsoptions[]required if type = radio or select
File Properties.TypeDescription
inputFileAcceptsstringaccept attribute inside input file ex. 'image/*'
imgPickerBtnTextstringinner text inside upload button and also accept html tags
Select-Input Type Properties.TypeDescription
selectNamestringname of select inside select-input-field
selectValuestring or numbervalue of select inside select-input-field
inputNamestringname of input inside select-input-field
inputValuestring or numbervalue of input inside select-input-field
Options Interface.TypeDescription
namestringname of option
valueanyvalue of option
isDisabledbooleanif you want to disable a single option
export interface FormConfig {
  name: string; // required
  type: string; // required
  id: string; // required

  isPassword?: boolean; // required if type is password and you'll use show hide for password
  eyeShow?: string; // if wanna change img of show password
  eyeHide?: string; // if wanna change img of hide password
  iconUrl?: string; // if user wanna put icon inside input

  label?: string; // require id if using with radio or checkbox
  options?: options[]; // required if type = radio
  value?: string | boolean | number;
  isRequired?: boolean;
  placeholder?: string;
  pattern?: string | RegExp;

  inputFileAccepts?: string;
  imgPickerBtnText?: string;

  // select with input custom type
  selectName?: string;
  inputName?: string;
  inputValue?: string | number;
  selectValue?: string | number;

  minLength?: string | number;
  maxLength?: string | number;
  autocomplete?: string | any;
}
export interface options {
  name: string;
  value: any;
  isDisabled?: boolean;
}

Example

First Import DynamicFormBuilderModule and FormConfig Interface In Your Module or Standalone Component
import { DynamicFormBuilderModule, FormConfig } from "dynamic-form-builder";

then use the component with inputs and outputs

<dynamic-form-builder [formConfig]="myInputsConfigArray"
    (getFormData)="getForm($event)"
    [resetAfterSubmit]="true"
    [detectChange]="true"
    (formChanges)="detectChangeInForm($event)"
    (fileData)="getFileData($event)"
    [isDisabled]="false"
    [invalidDisable]="true"
    [formClasses]="'my-form-class'"
    [inputContainer]="'input-container'"
    [inputFieldClasses]="'input-field-class'"
    [radioFieldClasses]="'radio-field-class'"
    [checkboxFieldClasses]="'checkbox-field-class'"
    [fileFieldClasses]="'file-field-class'"
    [selectFieldClasses]="'select-field-class'"
    [selectWithInputClasses]="'select-input-field-class'"
    [errorAndBtnClasses]="'form-footer-class'"
    [errorMsgClasses]="'error-msg-class'"
    [buttonClasses]="'btn-submit-class'"
    [requiredStarClasses]="'required-class'"
    [iconClasses]="'icon-inside-input-class'"
    [requiredStarContent]="'*'"
    [errorMsg]="incomingErrorAfterSubmit"
    [buttonText]="'Signup'">
</dynamic-form-builder>

<!-- Image Preview -->
<img class="img-preview" [src]="imgUrl" alt="" />

then adjust your ts file to fit the component

  email: FormConfig = {
    name: 'email',
    type: 'text',
    id: 'test',
    label: 'Email',
    isRequired: true,
    placeholder: 'Enter Your Email',
    pattern: new RegExp(/^\w+([\.-]?\w+)*@\w+([\.-]?\w+)*(\.\w{2,3})+$/),
  };

  password: FormConfig = {
    name: 'password',
    type: 'password',
    id: 'password',
    label: 'Password',
    isRequired: true,
    placeholder: 'Enter Your Password',
    maxLength: '15',
    isPassword: true, // required to enable show and hide functionalities
    eyeShow: '', // img for password to automatically show password
    eyeHide: '', // img for password to automatically hide password
  };

    description: FormConfig = {
    name: 'description',
    type: 'textarea',
    id: 'description',
    label: 'Description',
    isRequired: true,
    placeholder: 'Enter Your Bio',
  };

  age: FormConfig = {
    name: 'age',
    type: 'number',
    id: 'age',
    label: 'Enter Your Age',
    isRequired: true,
    placeholder: 'Enter Your Age',
  };

  country: FormConfig = {
    name: 'country',
    type: 'select',
    options: [
      { name: 'United Kindom', value: 'UK', isDisabled: true },
      { name: 'Egypt', value: 'EG', isDisabled: true },
      { name: 'Saudi Arabia', value: 'KSA' },
      { name: 'Emirates', value: 'UAE' },
      { name: 'Qatar', value: 'QA' },
    ],
    label: 'Select Your Country',
    id: 'country',
    isRequired: true,
    value: 'EG',
  };

  checkbox: FormConfig = {
    name: 'accept',
    type: 'checkbox',
    isRequired: true,
    label: 'Do You Accept Our Terms & Conditions?',
    id: 'accept',
    value: true,
  };

  work: FormConfig = {
    name: 'work',
    type: 'radio',
    id: 'work',
    label: "What's Your Current Work Type",
    isRequired: true,
    options: [
      { name: 'From Home', value: 'home' },
      { name: 'From Office', value: 'office' },
    ],
    value: 'home',
  };

  color: FormConfig = {
    name: 'color',
    type: 'color',
    id: 'color',
    label: "What's your favorite color?",
  };

  range: FormConfig = {
    name: 'range',
    type: 'range',
    id: 'range',
    label: 'How excited are you?',
    value: '20',
  };

  time: FormConfig = {
    name: 'time',
    type: 'time',
    id: 'time',
    label: 'Select Time',
  };

  // custom type
  PhoneWithSelectCountry: FormConfig = {
    name: 'phone-with-country',
    type: 'select-with-input',
    id: 'select-with-input',
    selectName: 'phone-select',
    inputName: 'phone-input',
    label: 'Phone Number',
    options: [
      { name: '<span>Code with flag</span>', value: '02' },
      { name: '991', value: '991' },
      { name: '996', value: '996' },
    ],
    selectValue: '991',
    inputValue: '123123123',
  };

  ImgUploader: FormConfig = {
    name: 'img',
    type: 'file',
    label: 'Upload Your Img',
    id: 'img',
    imgPickerBtnText: 'Upload',
    inputFileAccepts: 'image/*',
  };

  // with this format you can easily set the value for each input in edit mode for example
  myInputsConfigArray: FormConfig[] = [
    this.email,
    this.password,
    this.age,
    this.country,
    this.checkbox,
    this.work,
    this.color,
    this.range,
    this.time,
    this.PhoneWithSelectCountry,
    this.ImgUploader,
  ];

  incomingErrorAfterSubmit = '';
  imgUrl = '';

  getForm(form: FormGroup) {
    console.log(form.value);
    // Api calls for data
    // if error
    this.incomingErrorAfterSubmit = 'Invalid Data';
  }

  detectChangeInForm(form: FormGroup) {
    // any change in the form it will be log here
    console.log(form.value);
  }

  getFileData(event: any) {
    // if user upload a file (ex. image) it will be converted into a file and base64 Url
    // and it will be logged {file:File , base64Url: ''}
    console.log(event);
    this.imgUrl = event.base64Url;
  }

Created By Shady Noor LinkedIn Shady Noor shadynoor9@gmail.com If you can improve it just pull it and do push a PR

1.0.5

4 months ago

1.0.4

4 months ago

1.0.3

5 months ago

1.0.2

5 months ago

1.0.1

5 months ago

1.0.0

5 months ago

0.0.1

5 months ago