@hirehq/ngx-screening-form-template
v1.0.4
Published
A reusable Angular component for previewing form templates exactly as candidates would see them on the candidate web side
Readme
@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
npm install @hirehq/ngx-screening-form-templateUsage
Standalone Component (Recommended)
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
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 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:
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:
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:
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:
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:
ng build hirehq-screening-form-templateLicense
MIT
