ngx-checkbox-list

2.0.2 • Public • Published

ngx-checkbox-list

Checkbox list form control for Angular X

import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms';
import { Input, Component, forwardRef } from '@angular/core';
import { Option } from './option';
 
@Component({
    selector: 'ngx-checkbox-list',
    // eslint-disable-next-line @typescript-eslint/no-use-before-define
    providers: [{ provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => CheckboxListComponent), multi: true }],
    template: `
        <div [ngClass]="classList">
            <div [class]="itemClassName" *ngFor="let o of options; let i = index">
                <input
                    type="checkbox"
                    [value]="o.value"
                    [checked]="checked(o.value)"
                    [attr.id]="name + i"
                    (change)="change($event)"
                />
                <label [attr.for]="name + i">{{ o.label }}</label>
            </div>
        </div>
    `,
})
export class CheckboxListComponent implements ControlValueAccessor {
    /**
     * Used as prefix to generate unique label/id
     */
    @Input() name = '';
    /**
     * Key/value pairs to produce ui option label and value
     */
    @Input() options: Option[];
    /**
     * Used to format returning value as object of ids
     */
    @Input() objectId?: string;
    @Input() classList: string[] | string = 'checkbox-list';
    /**
     * Name of propery for case when need return object with ids
     */
    @Input() objectKey?: string;
 
    /**
     * Input/label will be wrapped into div with this class name
     */
    @Input() itemClassName = '';
 
    private value?: string[];
    private onTouched: (_: unknown) => void;
    private onChange: (_: unknown) => void;
 
    /**
     * Checks if value is selected (checkbox will be mark as checked)
     */
    checked(value: unknown): boolean {
        if (!this.value) {
            return false;
        }
        return this.value.includes(String(value));
    }
 
    /**
     * Called when one of checkbox value changed
     */
    change(event: Event) {
        const input = event.target as HTMLInputElement;
        const inputValue = String(input.value);
        if (!Array.isArray(this.value)) {
            this.value = [];
        }
        this.value = input.checked ? [...this.value, inputValue] : this.value.filter(v => v !== inputValue);
        let formValue: unknown[] = this.value;
        if (this.objectId && this.objectKey) {
            // If objectId and objectKey are defined, we return {[objectId]: value, [objectKey]: label }[]
            const id = this.objectId;
            const name = this.objectKey;
            // Converts array of values to array of objects.
            formValue = this.options
                .filter(o => (this.value as string[]).includes(String(o.value)))
                .map(o => ({ [id]: o.value, [name]: o.label }));
        } else if (this.objectId) {
            // If objectId is defined, we return { [id]: o.value  }[]
            const id = this.objectId;
            formValue = this.options
                .filter(o => (this.value as string[]).includes(String(o.value)))
                .map(o => ({ [id]: o.value }));
        } else {
            formValue = formValue.filter((value, index, self) => index === self.findIndex(other => other === value));
        }
        this.onChange(formValue);
    }
 
    // Form ControlValueAccessor interface
 
    /**
     * Write a new value to the element
     */
    // eslint-disable-next-line @typescript-eslint/no-explicit-any
    writeValue(value: any) {
        if (!Array.isArray(value)) {
            value = value ? [] : null; // eslint-disable-line @typescript-eslint/tslint/config
            // eslint-disable-next-line wix-editor/prefer-ternary
        } else if (this.objectId) {
            value = value.map(v => String(v[this.objectId as string]));
        } else {
            value = value.map(v => String(v)); // eslint-disable-line @typescript-eslint/tslint/config
        }
        this.value = value;
    }
 
    /**
     * Set the function to be called when the control receives a change event
     */
    registerOnChange(fn: (_: unknown) => void) {
        this.onChange = fn;
    }
 
    /**
     * Set the function to be called when the control receives a touch event
     */
    registerOnTouched(fn: (_: unknown) => void) {
        this.onTouched = fn;
    }
}

Package Sidebar

Install

npm i ngx-checkbox-list

Weekly Downloads

2

Version

2.0.2

License

ISC

Unpacked Size

16.1 kB

Total Files

7

Last publish

Collaborators

  • iamthes