@avoraui/av-dual-list-box
Version:
A customizable Angular dual list box component for managing item selections.
1 lines • 20.4 kB
Source Map (JSON)
{"version":3,"file":"avoraui-av-dual-list-box.mjs","sources":["../../../projects/av-dual-list-box/src/lib/av-dual-list-box.ts","../../../projects/av-dual-list-box/src/lib/av-dual-list-box.html","../../../projects/av-dual-list-box/src/public-api.ts","../../../projects/av-dual-list-box/src/avoraui-av-dual-list-box.ts"],"sourcesContent":["import {AfterViewInit, Component, forwardRef, Input, OnChanges, OnInit, SimpleChanges, ViewChild} from '@angular/core';\r\nimport {MatListOption, MatSelectionList} from \"@angular/material/list\";\r\nimport {\r\n ControlValueAccessor,\r\n FormBuilder,\r\n FormControl,\r\n FormGroup,\r\n NG_VALUE_ACCESSOR,\r\n ReactiveFormsModule\r\n} from \"@angular/forms\";\r\nimport {MatCard} from \"@angular/material/card\";\r\nimport {MatButton} from \"@angular/material/button\";\r\nimport {MatFormField, MatLabel} from \"@angular/material/form-field\";\r\nimport {MatInput} from \"@angular/material/input\";\r\nimport {isEqual} from 'lodash';\r\nimport {MatIcon} from '@angular/material/icon';\r\n\r\n@Component({\r\n selector: 'av-dual-list-box',\r\n templateUrl: './av-dual-list-box.html',\r\n imports: [\r\n MatCard,\r\n MatSelectionList,\r\n MatListOption,\r\n MatButton,\r\n ReactiveFormsModule,\r\n MatFormField,\r\n MatInput,\r\n MatLabel,\r\n MatIcon\r\n ],\r\n styleUrls: ['./av-dual-list-box.css'],\r\n standalone: true,\r\n providers: [\r\n {\r\n provide: NG_VALUE_ACCESSOR,\r\n useExisting: forwardRef(() => AvDualListBox),\r\n multi: true\r\n }\r\n ]\r\n})\r\nexport class AvDualListBox<T extends Record<string, any>> implements OnInit, OnChanges, AfterViewInit, ControlValueAccessor {\r\n\r\n @Input() sourceList: T[] = [];\r\n @Input() destinationObjectReference: string[] = [];\r\n @Input() displayProperty: keyof T | '' = '';\r\n protected destinationList: T[] = [];\r\n private originalSourceList: T[] = [];\r\n private originalDestinationList: T[] = [];\r\n protected form! : FormGroup;\r\n\r\n @ViewChild('SourceList') SourceList!: MatSelectionList;\r\n @ViewChild('DestinationList') DestinationList!: MatSelectionList;\r\n\r\n private onChange: (value: T[]) => void = () => {};\r\n private onTouched: () => void = () => {};\r\n private disabled = false;\r\n\r\n constructor(private formBuilder : FormBuilder) {\r\n this.form = this.formBuilder.group({\r\n sourceListSearch : new FormControl(),\r\n destinationListSearch : new FormControl(),\r\n })\r\n }\r\n\r\n ngOnInit() {\r\n this.form.controls['destinationListSearch'].disabled;\r\n }\r\n\r\n /**\r\n * Responds to changes in input-bound properties of the component.\r\n * Executes logic whenever the bound properties are updated.\r\n *\r\n * @param {SimpleChanges} changes - An object that contains the changes to the bound properties. Each property corresponds to a component input and contains its current and previous values.\r\n * @return {void} This method does not return a value.\r\n */\r\n ngOnChanges(changes: SimpleChanges): void {\r\n if (changes['sourceList']) {\r\n this.originalSourceList = [...this.sourceList];\r\n this.resetAndFilterSourceList();\r\n }\r\n }\r\n //\r\n // writeValue(value: T[]): void {\r\n // if (value) {\r\n // this.destinationList = this.getMappedDestinationValues(value);\r\n // this.originalDestinationList = [...this.destinationList];\r\n // this.resetAndFilterSourceList();\r\n // this.DestinationList.options.forEach(option => option._setSelected(true));\r\n // } else {\r\n // this.destinationList = [];\r\n // }\r\n // this.onChange(this.destinationList);\r\n // }\r\n\r\n /**\r\n * Writes the provided value to the destination list, processes and maps the values accordingly,\r\n * and updates the source and destination lists.\r\n *\r\n * @param {T[]} value - The array of values to process and write to the destination list. If the value is null or undefined, the destination list is cleared.\r\n * @return {void} This method does not return any value.\r\n */\r\n writeValue(value: T[]): void {\r\n if (value) {\r\n this.destinationList = this.getMappedDestinationValues(value);\r\n this.originalDestinationList = [...this.destinationList];\r\n this.resetAndFilterSourceList();\r\n\r\n // Ensure DestinationList exists before accessing options\r\n setTimeout(() => {\r\n if (this.DestinationList) {\r\n this.DestinationList.options.forEach(option => option._setSelected(true));\r\n }\r\n });\r\n } else {\r\n this.destinationList = [];\r\n }\r\n this.onChange(this.destinationList);\r\n }\r\n\r\n\r\n /**\r\n * Maps and filters the input array based on the `destinationObjectReference`.\r\n * For each item in the `value` array, it retrieves a nested value determined\r\n * by the keys in the `destinationObjectReference`. Only non-null values are returned.\r\n *\r\n * @param {T[]} value - The array of items to be processed and filtered.\r\n * @return {T[]} - A filtered array containing only the mapped and non-null values.\r\n */\r\n private getMappedDestinationValues(value: T[]): T[] {\r\n if (this.destinationObjectReference.length > 0) {\r\n return value.map(item => {\r\n const nestedValue = this.destinationObjectReference.reduce((acc: any, key: string) => acc ? acc[key] : undefined, item);\r\n return nestedValue ? nestedValue : null;\r\n }).filter((item): item is T => item !== null);\r\n }\r\n return value;\r\n }\r\n\r\n private resetAndFilterSourceList(): void {\r\n this.sourceList = this.originalSourceList.filter(item =>\r\n !this.destinationList.some(destItem => isEqual(destItem, item))\r\n );\r\n }\r\n\r\n registerOnChange(fn: (value: T[]) => void): void {\r\n this.onChange = fn;\r\n }\r\n\r\n registerOnTouched(fn: () => void): void {\r\n this.onTouched = fn;\r\n }\r\n\r\n setDisabledState?(isDisabled: boolean): void {\r\n this.disabled = isDisabled;\r\n }\r\n\r\n /**\r\n * Moves selected items between the source list and the destination list based on the provided direction.\r\n *\r\n * @param {boolean} isToDestination - A boolean flag to determine the direction of movement. If true, moves items from source list to destination list. If false, moves items from destination list to source list.\r\n * @return {void} No return value.\r\n */\r\n moveItems(isToDestination: boolean): void {\r\n const selectedItems = (isToDestination ? this.SourceList : this.DestinationList).selectedOptions.selected.map(option => option.value);\r\n if (isToDestination) {\r\n this.sourceList = this.sourceList.filter(item => !selectedItems.includes(item));\r\n this.destinationList.push(...selectedItems);\r\n this.originalDestinationList = [...this.destinationList];\r\n } else {\r\n this.destinationList = this.destinationList.filter(item => !selectedItems.includes(item));\r\n this.sourceList.push(...selectedItems);\r\n this.originalDestinationList = [...this.destinationList];\r\n }\r\n this.onChange(this.destinationList);\r\n this.onTouched();\r\n this.clearSelection(isToDestination);\r\n }\r\n\r\n /**\r\n * Moves all items between source and destination lists based on the specified direction.\r\n *\r\n * @param {boolean} isToDestination - Indicates the direction of the move.\r\n * If true, moves all items from the source list to the destination list.\r\n * If false, moves all items from the destination list back to the source list.\r\n *\r\n * @return {void} This method does not return any value.\r\n */\r\n moveAllItems(isToDestination: boolean): void {\r\n if (isToDestination) {\r\n this.destinationList.push(...this.sourceList);\r\n this.originalDestinationList = [...this.destinationList];\r\n this.sourceList = [];\r\n } else {\r\n this.sourceList.push(...this.destinationList);\r\n this.destinationList = [];\r\n this.originalDestinationList = [...this.destinationList];\r\n }\r\n this.onChange(this.destinationList);\r\n this.onTouched();\r\n }\r\n\r\n /**\r\n * Clears the selection from either the source list or the destination list based on the provided parameter.\r\n *\r\n * @param {boolean} isToDestination - A flag indicating whether to clear the destination list (`true`) or source list (`false`).\r\n * @return {void} This method does not return a value.\r\n */\r\n private clearSelection(isToDestination: boolean): void {\r\n if (isToDestination) {\r\n this.SourceList.selectedOptions.clear();\r\n } else {\r\n this.DestinationList.selectedOptions.clear();\r\n }\r\n }\r\n\r\n /**\r\n * Filters the original list based on the search value from the specified form control.\r\n *\r\n * @param {string} searchControlName - The name of the form control used to retrieve the search input.\r\n * @param {T[]} originalList - The original unfiltered list of items.\r\n * @param {T[]} targetList - The list to store the filtered results. It will reflect the filtered or full contents of the original list.\r\n * @return {T[]} - The filtered list of items matching the search input, or the original list if no input is entered.\r\n */\r\n filterList(searchControlName: string, originalList: T[], targetList: T[]): T[] {\r\n const searchValue = this.form.controls[searchControlName]?.value?.toLowerCase() || '';\r\n\r\n if (searchValue) {\r\n // Filter the original list based on the search value\r\n targetList = originalList.filter(item =>\r\n (item[this.displayProperty] as unknown as string).toLowerCase().includes(searchValue.toLowerCase())\r\n );\r\n } else {\r\n // If search input is empty, show all items again\r\n targetList = [...originalList];\r\n }\r\n\r\n return targetList; // Return the filtered or original list\r\n }\r\n\r\n /**\r\n * Filters the source list based on the provided search criteria and updates the source list.\r\n *\r\n * @return {void} This method does not return a value. It updates the sourceList property with the filtered results.\r\n */\r\n filterSourceList(): void {\r\n this.sourceList = this.filterList('sourceListSearch', this.originalSourceList, this.sourceList);\r\n }\r\n\r\n /**\r\n * Filters the destination list based on the search criteria provided and updates the existing list.\r\n *\r\n * @return {void} Updates the `destinationList` property with the filtered results.\r\n */\r\n filterDestinationList(): void {\r\n this.destinationList = this.filterList('destinationListSearch', this.originalDestinationList, this.destinationList);\r\n }\r\n\r\n /**\r\n * A lifecycle hook that is called after the component's view has been fully initialized.\r\n * This method ensures that all options in the DestinationList are marked as selected.\r\n *\r\n * @return {void} This method does not return a value.\r\n */\r\n ngAfterViewInit(): void {\r\n if (this.DestinationList) {\r\n this.DestinationList.options.forEach(option => option._setSelected(true));\r\n }\r\n }\r\n\r\n}\r\n","<mat-card class=\"listbox-container\">\r\n <mat-card class=\"source-list\">\r\n <mat-selection-list #SourceList>\r\n <form [formGroup]=\"form\">\r\n <mat-form-field appearance=\"outline\" class=\"searchFields\">\r\n <mat-label>Search Here</mat-label>\r\n <input matInput formControlName=\"sourceListSearch\" (keyup)=\"filterSourceList()\">\r\n </mat-form-field>\r\n </form>\r\n @for (item of sourceList; track sourceList) {\r\n <mat-list-option [value]=\"item\">\r\n {{ item[displayProperty] || 'No Such Property' }}\r\n </mat-list-option>\r\n }\r\n </mat-selection-list>\r\n </mat-card>\r\n\r\n <mat-card class=\"button-panel\">\r\n <button mat-raised-button color=\"primary\" (click)=\"moveItems(true)\">\r\n <mat-icon>chevron_right</mat-icon>\r\n </button>\r\n <button mat-raised-button color=\"primary\" (click)=\"moveItems(false)\">\r\n <mat-icon>chevron_left</mat-icon>\r\n </button>\r\n <button mat-raised-button color=\"accent\" (click)=\"moveAllItems(true)\">\r\n <mat-icon>double_arrow</mat-icon> <!-- Use CSS to rotate if needed -->\r\n </button>\r\n <button mat-raised-button color=\"accent\" (click)=\"moveAllItems(false)\">\r\n <mat-icon class=\"flip-horizontal\">double_arrow</mat-icon>\r\n </button>\r\n </mat-card>\r\n\r\n\r\n <mat-card class=\"destination-list\">\r\n <mat-selection-list #DestinationList>\r\n <form [formGroup]=\"form\">\r\n <mat-form-field appearance=\"outline\">\r\n <mat-label>Search Here</mat-label>\r\n <input matInput formControlName=\"destinationListSearch\" (keyup)=\"filterDestinationList()\">\r\n </mat-form-field>\r\n </form>\r\n @for (item of destinationList; track destinationList) {\r\n <mat-list-option [value]=\"item\">\r\n {{ item[displayProperty] || 'No Such Property' }}\r\n </mat-list-option>\r\n }\r\n </mat-selection-list>\r\n </mat-card>\r\n</mat-card>\r\n","/*\r\n * Public API Surface of av-dual-list-box\r\n */\r\n\r\nexport * from './lib/av-dual-list-box';\r\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}