1.0.6 • Published 10 months ago

@angoraforms/angora-loader v1.0.6

Weekly downloads
-
License
ISC
Repository
-
Last release
10 months ago

AngoraForms

AngoraForms is a custom form component abstraction library designed for Angular that streamlines and simplifies the process of creating reactive custom form components in Angular.

Custom form components in Angular come with a bit of boilerplate code; AngoraForms' components abstract away ~90% of that boilerplate code.

See https://www.angoraforms.com/ or below for example code comparison.

Version 1.0.6

Minor readme, branding update.

Documentation

The official documentation website is https://www.angoraforms.com/docs.

AngoraForms version 1.0.6 was released on 7/02/23. You can find more details on https://www.npmjs.com/package/@angoraforms/angora-loader/v/1.0.3?activeTab=versions

Key Features

  • Ease of Use: Getting started with AngoraForms is simple. Visit our documentation for a quick start up guide.
  • Static Typing: Custom components created with our abstraction library accomodate for TypeScript to adhere to the philosophy of the Angular framework and improve overall deveoper experience.
  • Customizable Components: AngoraForms does not come with component styling. Developers are free to style any components to their own tastes.
  • Maintainability: Custom components are aggregated in a single location with minimal boilerplate code normally required by the Angular framework, aiding maintainability and improving reviewability.

Getting Started

  1. Install Node.js.

  2. Install AngoraForms npm library link.

npm i @angoraforms/angora-loader
  1. Configure webpack.config.ts:
const path = require("path");
const customComponents = require('./src/app/customComponents.ts')

module.exports = {
  mode: "development",
  entry: ["./src/app/app.module.ts"],
  output: {},
  devtool: false,
  module: {
    rules: [
      {
        test: /\.ts$/, 
        use: [
          {
            loader: "@angoraforms/angora-loader",

            options: {
              customComponents: customComponents
            }
          },
        ],
      },
    ],
  },
  resolve: {
    extensions: ['.tsx', '.ts', '.js'],
  },
};
  1. Create Custom Component File:
class customComponent1 {

    template = '/* html template */'
  
    onChange = (value: any) => {};
  
    onTouched = () => {};
  
    value: any = 0;
  
    disabled = false
  }

Each custom component class will require a template, onChange, onTouched, value and disabled property.

  1. Insert html into value of template within backticks.

Example:

  template = `
        <h1>{{value}}</h1>
        <button (click)='increment()'>Increment</button>
        <button (click)='decrement()'>Decrement</button>
    `;
  1. Customise value and/or disabled if/as required.

  2. Add custom methods to component if/as required. Example:

  increment() {
    this.value++;
    this.onChange(this.value);
    this.onTouched();
  }

  decrement() {
    this.value--;
    this.onChange(this.value);
    this.onTouched();
  }
  1. Additional custom components are added following the first custom component class.

Example:

class customComponent1 {
  template = `
        <h1>{{value}}</h1>
        <button (click)='increment()'>Increment</button>
        <button (click)='decrement()'>Decrement</button>
    `;

  onChange = (value: any) => {};

  onTouched = () => {};

  value = 0;

  disabled = false

  increment() {
    this.value++;
    this.onChange(this.value);
    this.onTouched();
  }

  decrement() {
    this.value--;
    this.onChange(this.value);
    this.onTouched();
  }
}

class customComponent2 {
  template = `
        <input type="file" class="file-input" (change)="onFileSelected($event)" #fileUpload>

        <div>
            <input class="form-control" [disabled]="true" [value]="value">
            <button class="btn btn-primary" (click)="onClick(fileUpload)" [disabled]="disabled">Attach File</button>
        </div>
    `;

  onChange = (value: any) => {};

  onTouched = () => {};

  value = '';

  disabled = false;

  onFileSelected(event: any) {
    const file = event.target.files[0];
    if (file) {
      this.value = file.name;
      console.log(this.value);
      this.onChange(this.value);
    }
  }

  onClick(fileUpload: any) {
    this.onTouched();
    fileUpload.click();
  }
}
  1. Export custom component classes within an array.

Example:

module.exports = [customComponent1, customComponent2]
  1. Run npx webpack in terminal before running ng serve.

Custom component files will be generated and required modifications to the app.modules file will be made.

Example Comparison

Without AngoraForms:

customComponent1.ts

import { Component } from '@angular/core';
import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms';

@Component({
  selector: 'custom-comp1',
  template: `
    
        <h1>{{value}}</h1>
        <button (click)='increment()'>Increment</button>
        <button (click)='decrement()'>Decrement</button>
    
  `,
  providers: [
    {
      provide: NG_VALUE_ACCESSOR,
      multi: true,
      useExisting: customComp1
    }
  ]
})
export class customComp1 implements ControlValueAccessor {

onChange = (value: any) => { }
onTouched = () => { }
value = 0
disabled = false 

increment() {
        this.value++;
        this.onChange(this.value);
        this.onTouched();
    }
decrement() {
        this.value--;
        this.onChange(this.value);
        this.onTouched();
    }

writeValue(value: any) {
    this.value = value
  }
  
  registerOnChange(onChange: any) {
    this.onChange = onChange
  }
  
  registerOnTouched(onTouched: any){
    this.onTouched = onTouched
  }
  
  setDisabledState(disabled: boolean): void {
    this.disabled = disabled
  }
}

customComponent2.ts

import { Component } from '@angular/core';
import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms';

@Component({
  selector: 'custom-comp2',
  template: `
    
        <input type="file" class="file-input" (change)="onFileSelected($event)" #fileUpload>

        <div>
            <input class="form-control" [disabled]="true" [value]="value">
            <button class="btn btn-primary" (click)="onClick(fileUpload)" [disabled]="disabled">Attach File</button>
        </div>
    
  `,
  providers: [
    {
      provide: NG_VALUE_ACCESSOR,
      multi: true,
      useExisting: customComp2
    }
  ]
})
export class customComp2 implements ControlValueAccessor {

onChange = (value: any) => { }
onTouched = () => { }
value = ''
disabled = false 

onFileSelected(event: any) {
        const file = event.target.files[0];
        if (file) {
            this.value = file.name;
            console.log(this.value);
            this.onChange(this.value);
        }
    }
onClick(fileUpload: any) {
        this.onTouched();
        fileUpload.click();
    }

writeValue(value: any) {
    this.value = value
  }
  
  registerOnChange(onChange: any) {
    this.onChange = onChange
  }
  
  registerOnTouched(onTouched: any){
    this.onTouched = onTouched
  }
  
  setDisabledState(disabled: boolean): void {
    this.disabled = disabled
  }
}

With Angora Forms:

class customComp1 {
  template = `
        <h1>{{value}}</h1>
        <button (click)='increment()'>Increment</button>
        <button (click)='decrement()'>Decrement</button>
    `;

  onChange = (value: any) => {};

  onTouched = () => {};

  value = 0;

  disabled = false

  increment() {
    this.value++;
    this.onChange(this.value);
    this.onTouched();
  }

  decrement() {
    this.value--;
    this.onChange(this.value);
    this.onTouched();
  }
}

class customComp2 {
  template = `
        <input type="file" class="file-input" (change)="onFileSelected($event)" #fileUpload>

        <div>
            <input class="form-control" [disabled]="true" [value]="value">
            <button class="btn btn-primary" (click)="onClick(fileUpload)" [disabled]="disabled">Attach File</button>
        </div>
    `;

  onChange = (value: any) => {};

  onTouched = () => {};

  value = '';

  disabled = false;

  onFileSelected(event: any) {
    const file = event.target.files[0];
    if (file) {
      this.value = file.name;
      console.log(this.value);
      this.onChange(this.value);
    }
  }

  onClick(fileUpload: any) {
    this.onTouched();
    fileUpload.click();
  }
}

module.exports = [customComp1, customComp2]

Other Information

AngoraForms is in beta and will be updated in the future.

https://medium.com/@wayneleung_2900/making-angular-custom-form-components-easier-to-work-with-e2f7ace48cb2

Check out the companion Form Builder web application and its github repo: https://www.angoraforms.com/FormBuilder (https://github.com/AngoraForms/AngoraFormApp)

Contributors

License

This project is licensed under the MIT License.