The TextArea class creates a multi-line text input field designed for capturing longer text content such as descriptions, comments, or messages. It extends the Input class and automatically sets the type to 'textarea'.
Inheritance
ObjectBase → NodeBase → InputBaseNode → Input → TextArea
Constructor
new TextArea(
id: string,
placeholder?: string,
value?: any,
maxCharCount?: number,
singleLine?: boolean,
icon?: string,
errorMessage?: string,
disabled?: boolean,
readOnly?: boolean,
validator?: Validator,
asyncValidator?: AsyncValidator,
action?: Action | Action[]
)
Parameters
The unique identifier for the textarea field in the DOM.
The placeholder text displayed when the textarea is empty.
The initial value of the textarea.
Maximum number of characters allowed in the textarea.
Whether the textarea should be displayed in a single line layout (typically false for textareas).
Material icon name to display alongside the textarea.
Custom error message to display when validation fails.
Whether the textarea is disabled.
Whether the textarea is read-only.
Synchronous validator(s) to apply to the textarea. Can be a single ValidatorFn, an array of ValidatorFn, or null.
Asynchronous validator(s) to apply to the textarea. Can be a single AsyncValidatorFn, an array of AsyncValidatorFn, or null.
Action(s) to execute when specific events occur on the textarea.
Properties
Inherits all properties from Input, with the following override:
| Property | Type | Description |
|---|
type | NodeType | Automatically set to 'textarea' |
Methods
Inherits all methods from Input:
editable() - Makes the textarea editable
readonly() - Makes the textarea read-only
apply() - Applies additional properties to the node
getNativeElement() - Returns the native DOM element
Usage Examples
Basic TextArea
import { TextArea } from 'mat-dynamic-form';
import { Validators } from '@angular/forms';
const descriptionField = new TextArea('description', 'Description').apply({
validator: Validators.required,
icon: 'description'
});
TextArea with Character Limit
const bioField = new TextArea('bio', 'Biography', undefined, 500).apply({
hint: 'Tell us about yourself (max 500 characters)',
icon: 'person',
validator: [Validators.required, Validators.maxLength(500)]
});
const commentsField = new TextArea('comments', 'Additional Comments', undefined, 1000).apply({
hint: 'Share any additional information or questions',
icon: 'comment',
maxCharCount: 1000
});
Message Field with Validation
const messageField = new TextArea('message', 'Your Message', undefined, 2000).apply({
validator: [
Validators.required,
Validators.minLength(10),
Validators.maxLength(2000)
],
hint: 'Enter your message (10-2000 characters)',
errorMessage: 'Message must be between 10 and 2000 characters',
icon: 'mail'
});
Read-Only TextArea
const termsField = new TextArea('terms', 'Terms and Conditions', termsText).apply({
readOnly: true,
hint: 'Please read the terms and conditions',
singleLine: false
});
Address Field
const addressField = new TextArea('address', 'Full Address', undefined, 300).apply({
icon: 'location_on',
validator: Validators.required,
hint: 'Enter your complete mailing address',
maxCharCount: 300
});
import { FormStructure, TextArea, Button } from 'mat-dynamic-form';
import { Validators } from '@angular/forms';
const formStructure = new FormStructure();
formStructure.title = 'Feedback Form';
formStructure.appearance = 'outline';
formStructure.nodes = [
new TextArea('feedback', 'Your Feedback', undefined, 1000).apply({
validator: [Validators.required, Validators.minLength(20)],
hint: 'Please provide detailed feedback (min 20 characters)',
icon: 'feedback',
maxCharCount: 1000
}),
new TextArea('suggestions', 'Suggestions for Improvement', undefined, 500).apply({
hint: 'Optional: Share any suggestions (max 500 characters)',
icon: 'lightbulb',
maxCharCount: 500
})
];
formStructure.validateActions = [
new Button('submit', 'Submit Feedback', {
onEvent: (param) => {
const formValue = param.structure?.getValue();
console.log('Feedback submitted:', formValue);
},
style: 'primary'
}).apply({
validateForm: true,
icon: 'send'
})
];
TextArea with Character Counter Action
const reviewField = new TextArea('review', 'Product Review', undefined, 500).apply({
icon: 'rate_review',
validator: [Validators.required, Validators.minLength(50)],
hint: 'Write a detailed review (min 50 characters)',
maxCharCount: 500,
action: {
type: 'valueChange',
onEvent: (param) => {
const length = param.event?.length || 0;
const remaining = 500 - length;
console.log(`Characters remaining: ${remaining}`);
// You can update a separate node to show character count
if (length >= 50) {
console.log('Minimum character requirement met');
}
}
}
});
Job Description Field
const jobDescriptionField = new TextArea('jobDescription', 'Job Description', undefined, 5000).apply({
validator: Validators.required,
hint: 'Provide a detailed job description including responsibilities and requirements',
icon: 'work',
maxCharCount: 5000
});
Conditional Read-Only
const notesField = new TextArea('notes', 'Notes', 'Initial notes content').apply({
icon: 'note',
hint: 'Add your notes here'
});
// Later in code, toggle read-only state
if (isEditMode) {
notesField.editable();
} else {
notesField.readonly();
}
Multi-Language Support
import { Dropdown, OptionChild, TextArea } from 'mat-dynamic-form';
const languageSelector = new Dropdown('language', 'Language', [
new OptionChild('English', 'en'),
new OptionChild('Spanish', 'es'),
new OptionChild('French', 'fr')
]).apply({
action: {
type: 'valueChange',
onEvent: (param) => {
const placeholders = {
en: 'Enter your message in English',
es: 'Ingrese su mensaje en español',
fr: 'Entrez votre message en français'
};
const messageNode = param.structure.getNodeById('message');
if (messageNode) {
messageNode.placeholder = placeholders[param.event] || placeholders.en;
}
}
}
});
const messageField = new TextArea('message', 'Enter your message in English', undefined, 1000).apply({
validator: Validators.required,
maxCharCount: 1000
});
const draftField = new TextArea('draft', 'Draft', undefined, 10000).apply({
icon: 'edit',
hint: 'Your draft is automatically saved',
maxCharCount: 10000,
action: {
type: 'valueChange',
onEvent: (param) => {
// Debounced auto-save logic
clearTimeout((window as any).autoSaveTimer);
(window as any).autoSaveTimer = setTimeout(() => {
console.log('Auto-saving draft...', param.event);
// Save to localStorage or backend
localStorage.setItem('draft', param.event);
}, 1000);
}
}
});
Validation Examples
Minimum and Maximum Length
import { Validators } from '@angular/forms';
const essayField = new TextArea('essay', 'Essay', undefined, 5000).apply({
validator: [
Validators.required,
Validators.minLength(100),
Validators.maxLength(5000)
],
hint: 'Write an essay between 100 and 5000 characters',
errorMessage: 'Essay must be between 100 and 5000 characters',
maxCharCount: 5000
});
Pattern Validation
import { Validators } from '@angular/forms';
// Ensure no HTML tags
const noHtmlPattern = /^[^<>]*$/;
const plainTextField = new TextArea('plainText', 'Plain Text Only', undefined, 1000).apply({
validator: [
Validators.required,
Validators.pattern(noHtmlPattern)
],
hint: 'No HTML tags allowed',
errorMessage: 'Text cannot contain HTML tags',
maxCharCount: 1000
});
Custom Validator
import { AbstractControl, ValidationErrors, ValidatorFn } from '@angular/forms';
function wordCountValidator(minWords: number, maxWords: number): ValidatorFn {
return (control: AbstractControl): ValidationErrors | null => {
if (!control.value) return null;
const wordCount = control.value.trim().split(/\s+/).length;
if (wordCount < minWords) {
return { minWords: { required: minWords, actual: wordCount } };
}
if (wordCount > maxWords) {
return { maxWords: { required: maxWords, actual: wordCount } };
}
return null;
};
}
const summaryField = new TextArea('summary', 'Summary', undefined, 2000).apply({
validator: [
Validators.required,
wordCountValidator(50, 300)
],
hint: 'Write a summary between 50 and 300 words',
errorMessage: 'Summary must be between 50 and 300 words'
});
Best Practices
-
Character Limits: Always set
maxCharCount for better user experience and validation
-
Clear Hints: Use
hint to explain the purpose and any constraints
-
Minimum Length: Use
Validators.minLength() for fields requiring substantial input
-
Single Line Layout: Keep
singleLine as false (default) for textareas to allow full width
-
Read-Only Display: Use
readOnly: true for displaying long text that shouldn’t be edited
-
Validation Feedback: Combine
maxCharCount with Validators.maxLength() for consistent validation
-
Auto-Save: Consider implementing auto-save for long-form content
-
Accessibility: Ensure proper labeling with
placeholder and hint for screen readers