# AvDualListBox Component (AvoraUI)

A customizable Angular dual list box component that allows users to move items between two lists with search functionality. This component implements Angular's `ControlValueAccessor` interface, making it fully compatible with reactive forms.

## Features

- ✅ **Dual List Support**: Move items between source and destination lists
- ✅ **Search Functionality**: Filter items in both source and destination lists
- ✅ **Reactive Forms Integration**: Full support for Angular reactive forms
- ✅ **Material Design**: Built with Angular Material components
- ✅ **Dynamic Display**: Customizable display property for list items
- ✅ **Selection Management**: Supports multi-selection and bulk move operations
- ✅ **Memory Management**: Maintains original lists for filtering and resets

## Dependencies

This component requires the following Angular Material modules:

```typescript
import { MatCard } from "@angular/material/card";
import { MatButton } from "@angular/material/button";
import { MatIcon } from '@angular/material/icon';
import { MatListOption, MatSelectionList } from "@angular/material/list";
import { MatFormField, MatLabel } from "@angular/material/form-field";
import { MatInput } from "@angular/material/input";
```

## Installation

1. Ensure you have Angular Material installed in your project
2. Import the component in your module or use it directly (standalone component)

## Usage

### Basic Usage

```html
<av-dual-list-box 
  [sourceList]="sourceItems"
  [displayProperty]="'name'">
</av-dual-list-box>
```

### With Reactive Forms

```typescript
// Component
export class MyComponent {
  listForm = this.fb.group({
    selectedItems: [[]]
  });

  sourceItems = [{ id: 1, name: 'Item 1' }, { id: 2, name: 'Item 2' }];

  constructor(private fb: FormBuilder) {}
}
```

```html
<!-- Template -->
<form [formGroup]="listForm">
  <av-dual-list-box 
    formControlName="selectedItems"
    [sourceList]="sourceItems"
    [displayProperty]="'name'">
  </av-dual-list-box>
</form>
```

## Input Properties

| Property | Type | Required | Default | Description |
|----------|------|----------|---------|-------------|
| `sourceList` | `T[]` | Yes | `[]` | Array of items for the source list |
| `destinationObjectReference` | `string[]` | No | `[]` | Reference path for nested object properties |
| `displayProperty` | `keyof T | ''` | No | Property to display for each item |

## Component Behavior

### Item Selection
- Select items in either list using the Material selection list
- Move selected items between source and destination lists with arrow buttons

### Search Functionality
- Filter source and destination lists using the search inputs
- Dynamic filtering based on the `displayProperty`

### Item Management
- **Move**: Transfer selected items between lists
- **Move All**: Transfer all items between lists
- **Reset**: Maintains original lists for filtering purposes

### Form Integration
The component outputs an array of selected items, making it easy to:
- Store in databases
- Send via API calls
- Integrate with form validation

## Data Format

The component handles data as an array of objects:

**Output**: Array of selected items from the destination list
**Input**: Array of items to initialize the destination list

### Item Type Detection
The component uses the `displayProperty` to determine how to display items.

## Error Handling

The component includes basic error handling for:
- Invalid `displayProperty` (falls back to 'No Such Property')
- Empty source list (displays no items)

## Memory Management

The component automatically:
- Maintains original lists for filtering
- Updates lists dynamically without memory leaks

## Styling

The component uses CSS classes that can be customized:

- `.listbox-container` - Main container
- `.source-list` - Source list container
- `.destination-list` - Destination list container
- `.button-panel` - Button panel container

## Browser Compatibility

This component uses modern browser APIs:
- Angular Material components
- Reactive Forms API

Ensure your target browsers support these features or include appropriate polyfills.

## Example Implementation

```typescript
// app.component.ts
import { Component } from '@angular/core';
import { FormBuilder, FormGroup } from '@angular/forms';

@Component({
  selector: 'app-root',
  template: `
    <form [formGroup]="listForm">
      <av-dual-list-box 
        formControlName="selectedItems"
        [sourceList]="sourceItems"
        [displayProperty]="'name'">
      </av-dual-list-box>
      
      <button (click)="onSubmit()" [disabled]="!listForm.valid">
        Submit
      </button>
    </form>
  `
})
export class AppComponent {
  sourceItems = [
    { id: 1, name: 'Item 1' },
    { id: 2, name: 'Item 2' },
    { id: 3, name: 'Item 3' }
  ];
  
  listForm: FormGroup = this.fb.group({
    selectedItems: [[]]
  });

  constructor(private fb: FormBuilder) {}

  onSubmit() {
    const selectedItems = this.listForm.get('selectedItems')?.value;
    console.log('Selected items:', selectedItems);
  }
}
```

## Requirements

- Angular 20+
- Angular Material
- Lodash (for `isEqual` utility)

## Browser Support

- Chrome/Edge 17+
- Firefox 52+
- Safari 10.1+

## License

This project is licensed under the MIT License - see the LICENSE file for details.

## Changelog

### v0.0.5
- Initial release
- Basic dual list functionality
- Search and filter support
- Reactive forms integration
- Material design implementation
