8

The following html snippet of code:

<mat-form-field class='textarea'>
    <textarea #txtarea matInput (change)='txtAreaChange()' [placeholder]="label" [(ngModel)]='text'></textarea>
    <mat-hint [class.red]="txtarea.value.split('\n').length > textAreaLimit[1]" align="start"> {{txtarea.value ? txtarea.value.split('\n').length : 0}}/{{textAreaLimit[1]}} lines</mat-hint>
    <mat-hint [class.red]="txtarea.value && txtarea.value.split('\n').map( len).max() > textAreaLimit[0]" align="end">Longest line: {{txtarea.value ? txtarea.value.split('\n').map( len).max() : 0}}/{{textAreaLimit[0]}}</mat-hint>
</mat-form-field>

Defines a textarea input with two-way binding. It does check for size: total number of lines and max length of a line. If these are greater that some constraints given in textAreaLimit then the hints become red.

I would like to change it so that the user cannot break this constraints, such as if the max number of line is 3 and there a 3 lines the user cannot add a new line. How can this be done without breaking the two-way binding?

Learning is a mess
  • 3,886
  • 3
  • 24
  • 56
  • Not clear what you're asking. Depending on the size of your screen, a text could `appear` on a single line on desktop, and on 4 lines of a mobile device.. So I don't understand what you want to achieve here .. Define clearly what you call a `line` – Jscti Dec 17 '18 at 10:38
  • A line here is defined a substring until hitting the next `\n` character, so as to precisely being independent of resizing the textarea box. In other words, after you collect the input value of this textarea, the number of lines is the number of `\n` + 1. – Learning is a mess Dec 17 '18 at 12:01
  • *rows* and *column* – Prashant Pimpale Dec 17 '18 at 15:24
  • 1
    so ? is my answer helping you ? – Jscti Dec 21 '18 at 09:33

2 Answers2

7

use [maxLength] property

<textarea #txtarea matInput  [maxLength]="maxNo" (change)='txtAreaChange()' [placeholder]="label" [(ngModel)]='text'></textarea>
Sachila Ranawaka
  • 28,742
  • 4
  • 48
  • 69
4

For this specific need/behavior, you need to create a simple custom validator

maxLinesValidator(limit: number): ValidatorFn {
    return (control: AbstractControl): {[key: string]: any} | null => {
        const exceeded = control.value.length && control.value.split('\n').length > limit;
        return exceeded ? {'maxLines': {value: true}} : null;
    };
}

That you'll bind to your FormControl. You can take a look at this working fiddle (src/app/reactive .ts + html) where the text field is validated in real time and displays an error if user exceed the maximum lines limit

Jscti
  • 12,924
  • 4
  • 57
  • 83