Dynamically increase the input width to the length of the line.

I am trying to create a field input

that dynamically expands at least in width with the length of the line entered by the user, possibly even multi-line. Is this possible with an element input

in Angular Material 2?

In a box textarea

from Angular Material 2, I was able to expand the text box in height rather than width with the following code:

<mat-form-field (keydown.enter)="onEnter()" 
                floatPlaceholder="never">
  <textarea matInput 
            placeholder="Autosize textarea" 
            matTextareaAutosize
            matAutosizeMinRows="1" 
            matAutosizeMaxRows="8">
  </textarea>
</mat-form-field>

      

also on StackBlitz .

The case textarea

scrollbar

should be invisible or replaced with a smaller one. And the most important click Entershould not create a new line, but only trigger an action.

+2


source to share


2 answers


You can use ngStyle to bind the mat-form field width and height to the computed value and use the keyup event on the input to set this value. For example, here's an input whose width follows the number of characters over 8:

<mat-form-field style="min-width: 8ch;" [ngStyle]="{'width.ch': width}">
    <input matInput (keyup)="width = $event.srcElement.value.length">
</mat-form-field>

      



Obviously, this is pretty rude. The tricky part is correctly calculating the width or height you need based on the content.

+1


source


Now I have created a more suitable solution for this problem. After I found the perfect solution in jQuery and @Obsidian added the appropriate JS code . I tried to adapt it for Angular input

and came up with the following. I've also added some scripts that support cutting and pasting lines.

Here's a demo on StackBlitz and related code:

Template:



<style>
    #invisibleTextID {
      white-space: pre;
    }

    // prevents flickering:
    ::ng-deep .mat-form-field-flex {
      width: 102% !important;
    }
</style>

<mat-form-field
  #formFieldInput
  [ngStyle]="{'width.px': width}">

  <input
    #inputText
    id="inputTextID"
    matInput
    [(ngModel)]="inString"
    (paste)="resizeInput()"
    (cut)="resizeInput()"
    (input)="resizeInput()">

</mat-form-field>

<span #invisibleText id="invisibleTextID">{{ inString }}</span>

      

Resizing method:

@ViewChild('invisibleText') invTextER: ElementRef;

inString: string = '';
width: number = 64;

resizeInput() {

    // without setTimeout the width gets updated to the previous length
    setTimeout ( () =>{

      const minWidth = 64;

      if (this.invTextER.nativeElement.offsetWidth > minWidth) {
        this.width = this.invTextER.nativeElement.offsetWidth + 2;
      } else {
        this.width = minWidth;
      }

    }, 0)
}

      

+1


source







All Articles