File

projects/i-components/src/lib/services/radioGroup.service.ts

Description

Stores a radio button uncheck handler, along with it's given ID.

Index

Properties

Constructor

constructor(id: number, uncheckHandler: () => void)

Creates an instance of RadioUnckeck.

Parameters :
Name Type Optional Description
id number No

The handler's ID.

uncheckHandler function No

The radio button uncheck handler.

Properties

Public id
Type : number
The handler's ID.
Public uncheckHandler
Type : function
The radio button uncheck handler.
import { Injectable } from '@angular/core';

/**
 * Stores a radio button uncheck handler, along with it's given ID.
 *
 * @class RadioUnckeck
 */
class RadioUnckeck {
  /**
   * Creates an instance of RadioUnckeck.
   *
   * @param {number} id The handler's ID.
   * @param {() => void} uncheckHandler The radio button uncheck handler.
   * @memberof RadioUnckeck
   */
  constructor(public id: number, public uncheckHandler: () => void) {}
}

/**
 * Represents a set of radio button uncheck handlers which belong to the
 * same group.
 *
 * @class RadioGroup
 */
class RadioGroup {
  /**
   * Stores all uncheck handlers in this group.
   *
   * @private
   * @type {RadioUnckeck[]}
   * @memberof RadioGroup
   */
  private handlers: RadioUnckeck[] = [];

  /**
   * Stores the ID which will be assigned to the
   * next handler to add into the group.
   *
   * @private
   * @memberof RadioGroup
   */
  private maxId = 0;

  /**
   * Adds a radio button uncheck handler into the group.
   * This functions return an ID which must be used to remove the handler.
   *
   * @param {() => void} handler The handler to add.
   * @return {*}  {number} The ID given to the handler.
   * @memberof RadioGroup
   */
  add(handler: () => void): number {
    const id = this.nextId();
    this.handlers.push(new RadioUnckeck(id, handler));
    return id;
  }

  /**
   * Removes the handler with the given ID from the group.
   *
   * @param {number} id The ID of the handler to remove.
   * @memberof RadioGroup
   */
  remove(id: number) {
    const idx = this.handlers.findIndex((x) => x.id === id);
    if (idx !== -1) {
      this.handlers.splice(idx, 1);
    }
  }

  /**
   * Call all uncheck handlers in the group, except for the handler with the
   * given ID.
   * This should uncheck all radio buttons in the group except for one.
   *
   * @param {number} id The ID of the handler which should not be called.
   * @memberof RadioGroup
   */
  emitUncheck(id: number) {
    this.handlers.forEach((x) => {
      if (x.id !== id) {
        x.uncheckHandler();
      }
    });
  }

  /**
   * Gets the amount of handlers in this group.
   *
   * @readonly
   * @type {number}
   * @memberof RadioGroup
   */
  get length(): number {
    return this.handlers.length;
  }

  /**
   * Return the next ID to assign to a handler.
   *
   * @private
   * @return {*}  {number} The ID.
   * @memberof RadioGroup
   */
  private nextId(): number {
    return this.maxId++;
  }
}

/**
 * Service for the RadioButton group functionality.
 *
 * @export
 * @class RadioGroupService
 */
@Injectable({
  providedIn: 'root',
})
export class RadioGroupService {
  /**
   * Maps group names to groups of uncheck handlers.
   *
   * @private
   * @type {Map<string, RadioGroup>}
   * @memberof RadioGroupService
   */
  private groupMap: Map<string, RadioGroup> = new Map<string, RadioGroup>();

  /**
   * Inserts the given handler into the corresponding group,
   * and returns an ID for the handler.
   *
   * @param {string} groupName The name of the group.
   * @param {() => any} handler The uncheck handler to insert.
   * @return {*}  {number} The ID assigned the handler.
   * @memberof RadioGroupService
   */
  subscribe(groupName: string, handler: () => any): number {
    let group = this.groupMap.get(groupName);
    if (group == null) {
      group = new RadioGroup();
      this.groupMap.set(groupName, group);
    }

    return group.add(handler);
  }

  /**
   * Removes the handler with the given ID from the corresponding group.
   *
   * @param {string} groupName The name of the group.
   * @param {number} id The ID of the handler to remove.
   * @return {*}  {void}
   * @memberof RadioGroupService
   */
  unsubscribe(groupName: string, id: number): void {
    const group = this.groupMap.get(groupName);
    if (group == null) {
      return;
    }

    group.remove(id);
    if (group.length === 0) {
      this.groupMap.delete(groupName);
    }
  }

  /**
   * Call the radio button uncheck handlers in the given group, except for
   * the handler with the given ID.
   * This should uncheck all radio buttons in the group except for one.
   *
   * @param {string} groupName
   * @param {number} id
   * @return {*}  {void}
   * @memberof RadioGroupService
   */
  emitUncheck(groupName: string, id: number): void {
    const group = this.groupMap.get(groupName);
    if (group == null) {
      return;
    }

    group.emitUncheck(id);
  }
}

result-matching ""

    No results matching ""