npm package: @hirehq/ngx-screening-form-template
Description: A reusable Angular component for previewing form templates exactly as candidates would see them on the candidate web side
Author: HireHQ
Latest version: 1.0.4

# @hirehq/ngx-screening-form-template

A reusable Angular component for previewing form templates exactly as candidates would see them on the candidate web side.

## Installation

```bash
npm install @hirehq/ngx-screening-form-template
```

## Usage

### Standalone Component (Recommended)

```typescript
import { FormTemplatePreviewComponent } from '@hirehq/ngx-screening-form-template';
import { Template } from '@hirehq/ngx-screening-form-template';

@Component({
  selector: 'app-template-editor',
  standalone: true,
  imports: [FormTemplatePreviewComponent],
  template: `
    <hq-screening-form-template
      [template]="template"
      [metadata]="metadata"
      [previewMode]="true"
    ></hq-screening-form-template>
  `
})
export class TemplateEditorComponent {
  template: Template = {
    id: '1',
    name: 'Software Engineer Screening',
    description: 'Screening form for software engineers',
    type: 1, // 1 = Screening Form, 2 = Other
    status: 1,
    profileEssentials: [
      { id: '1', isRequired: true }, // Date of Birth
      { id: '2', isRequired: false }, // Military Status
      { id: '3', isRequired: true }, // Ethnicity
      { id: '4', isRequired: false }, // Gender
    ],
    questions: [
      {
        id: 'q1',
        name: 'How many years of professional software development experience do you have?',
        type: 3, // Single choice (radio)
        position: 1,
        required: true,
        options: [
          { name: 'Less than 1 year', isStopCriteria: false, position: 1 },
          { name: '1-2 years', isStopCriteria: false, position: 2 },
          { name: '3-5 years', isStopCriteria: false, position: 3 },
          { name: '6-10 years', isStopCriteria: false, position: 4 },
          { name: 'More than 10 years', isStopCriteria: false, position: 5 },
        ],
      },
    ],
  };

  metadata = {
    forms_profile_essentials: [
      { code: 1, status: 'Date of Birth' },
      { code: 2, status: 'Military Status' },
      { code: 3, status: 'Ethnicity' },
      { code: 4, status: 'Gender' },
    ],
  };
}
```

### Module-based Usage

```typescript
import { FormTemplatePreviewModule } from '@hirehq/ngx-screening-form-template';

@NgModule({
  imports: [FormTemplatePreviewModule],
})
export class AppModule {}
```

## Inputs

| Input | Type | Required | Description |
|-------|------|----------|-------------|
| `template` | `Template` | Yes | The template object containing questions, profile essentials, etc. |
| `metadata` | `ProfileEssentialMetadata` | No | Metadata for profile essentials (labels, options, etc.) |
| `previewMode` | `boolean` | No | Whether the form is in preview mode (read-only). Default: `true` |
| `hideHeader` | `boolean` | No | Whether to hide the header section. Default: `false` |
| `formData` | `FormTemplateData` | No | Prefill the form with existing data. See [Data Prefilling](#data-prefilling) section |

## Outputs

| Output | Type | Description |
|-------|------|-------------|
| `formDataChange` | `EventEmitter<FormTemplateData>` | Emits form data whenever form values change (debounced by 300ms) |
| `formValid` | `EventEmitter<boolean>` | Emits form validity status whenever it changes |

## Question Types

The component supports the following question types:

- **Type 1**: Single Select (Radio buttons)
- **Type 2**: Multi Select (Checkboxes)
- **Type 3**: Yes/No (Radio buttons)
- **Type 4**: Text Input (Short Answer)
- **Type 5**: Text Area (Long Answer)
- **Type 6**: Date Field
- **Type 7**: Acknowledgement (with link)

## Features

- ✅ Profile Essentials section (for type 1 templates)
- ✅ All question types support
- ✅ Required field indicators
- ✅ Conditional questions support (child questions)
- ✅ Preview mode (read-only)
- ✅ Responsive design
- ✅ Clean, modern UI matching candidate web design
- ✅ **Data collection** - Get form data programmatically or via events
- ✅ **Data prefilling** - Prefill form with existing data

## Data Collection

The component provides multiple ways to collect form data:

### Method 1: Using Event Emitter (Reactive)

Subscribe to `formDataChange` event to get form data whenever it changes:

```typescript
import { FormTemplatePreviewComponent, FormTemplateData } from '@hirehq/ngx-screening-form-template';

@Component({
  selector: 'app-form-collector',
  standalone: true,
  imports: [FormTemplatePreviewComponent],
  template: `
    <hq-screening-form-template
      [template]="template"
      [metadata]="metadata"
      [previewMode]="false"
      (formDataChange)="onFormDataChange($event)"
      (formValid)="onFormValidChange($event)"
    ></hq-screening-form-template>
    
    <button (click)="onSubmit()" [disabled]="!isFormValid">Submit</button>
  `
})
export class FormCollectorComponent {
  template: Template = { /* ... */ };
  metadata = { /* ... */ };
  isFormValid = false;
  currentFormData: FormTemplateData | null = null;

  onFormDataChange(data: FormTemplateData) {
    this.currentFormData = data;
    console.log('Form data:', data);
    // {
    //   questions: {
    //     'q1': 'Option 1',
    //     'q2': ['Option A', 'Option B'],
    //     'q3': '2024-01-15T00:00:00.000Z',
    //     'q4': true
    //   },
    //   profileEssentials: {
    //     '1': '1990-01-01',
    //     '2': 'Veteran'
    //   }
    // }
  }

  onFormValidChange(isValid: boolean) {
    this.isFormValid = isValid;
  }

  onSubmit() {
    if (this.currentFormData) {
      // Send data to your API
      this.apiService.submitForm(this.currentFormData).subscribe();
    }
  }
}
```

### Method 2: Using ViewChild (Imperative)

Use `ViewChild` to access the component and call `getFormData()` method:

```typescript
import { ViewChild } from '@angular/core';
import { FormTemplatePreviewComponent, FormTemplateData } from '@hirehq/ngx-screening-form-template';

@Component({
  selector: 'app-form-collector',
  standalone: true,
  imports: [FormTemplatePreviewComponent],
  template: `
    <hq-screening-form-template
      #formPreview
      [template]="template"
      [metadata]="metadata"
      [previewMode]="false"
    ></hq-screening-form-template>
    
    <button (click)="onSubmit()">Submit</button>
  `
})
export class FormCollectorComponent {
  @ViewChild('formPreview') formPreview!: FormTemplatePreviewComponent;
  template: Template = { /* ... */ };
  metadata = { /* ... */ };

  onSubmit() {
    const formData = this.formPreview.getFormData();
    const isValid = this.formPreview.isFormValid();
    
    if (isValid) {
      // Send data to your API
      this.apiService.submitForm(formData).subscribe();
    } else {
      console.error('Form is invalid');
    }
  }
}
```

## Data Prefilling

You can prefill the form with existing data by passing `formData` input:

```typescript
import { FormTemplateData } from '@hirehq/ngx-screening-form-template';

@Component({
  selector: 'app-form-editor',
  standalone: true,
  imports: [FormTemplatePreviewComponent],
  template: `
    <hq-screening-form-template
      [template]="template"
      [metadata]="metadata"
      [previewMode]="false"
      [formData]="existingFormData"
      (formDataChange)="onFormDataChange($event)"
    ></hq-screening-form-template>
  `
})
export class FormEditorComponent {
  template: Template = { /* ... */ };
  metadata = { /* ... */ };
  
  // Prefill form with existing data
  existingFormData: FormTemplateData = {
    questions: {
      'q1': 'Option 1',                    // Single select
      'q2': ['Option A', 'Option B'],      // Multi-select (array)
      'q3': 'Yes',                          // Yes/No
      'q4': 'Some text answer',            // Text input
      'q5': 'Long text answer...',          // Textarea
      'q6': '2024-01-15T00:00:00.000Z',    // Date (ISO string)
      'q7': true                            // Acknowledgement (boolean)
    },
    profileEssentials: {
      '1': '1990-01-01',                    // Date of Birth
      '2': 'Veteran',                       // Military Status
      '3': 'Asian',                          // Ethnicity
      '4': 'Male'                            // Gender
    }
  };

  onFormDataChange(data: FormTemplateData) {
    // Handle form data changes
  }
}
```

### Form Data Structure

The `FormTemplateData` interface structure:

```typescript
interface FormTemplateData {
  questions: {
    [questionId: string]: 
      | string              // Single select, Yes/No, Text, Textarea
      | string[]            // Multi-select (checkboxes)
      | boolean            // Acknowledgement
      | Date               // Date field (converted to ISO string when emitted)
      | null;              // Unanswered questions
  };
  profileEssentials?: {
    [profileEssentialId: string]: any;  // Profile essential values
  };
}
```

### Public Methods

The component exposes the following public methods:

| Method | Returns | Description |
|--------|---------|-------------|
| `getFormData()` | `FormTemplateData` | Get current form data |
| `isFormValid()` | `boolean` | Check if form is valid |
| `resetForm()` | `void` | Reset the form to initial state |

## Building

To build the package from the monorepo:

```bash
ng build hirehq-screening-form-template
```

## License

MIT