Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Count words dynamically as users types in angular

  1. I want to take count of words, as user types in the textarea
  2. If he/she crosses more than 100 words he/she should not be allowed to type.
  3. I need to dynamically display word count as he/she types

sample.component.ts

 wordCounter(){
    this.wordCount = this.text ? this.text.split(/\s+/)  : 0;
    this.words=this.wordCount ? this.wordCount.length:0;

  }

This is my function to count words

sample.component.html

<textarea [(ngModel)]="text" ng-change="wordCounter()" id="wmd-input" name="post-text" class="wmd-input s-input bar0 js-post-body-field processed" data-post-type-id="2" cols="92" rows="15" tabindex="101" data-min-length="" oncopy="return false;" onpaste="return false;" oncut="return false;"></textarea>

<div>Words:<span id="wordCount">{{ words }}</span></div>

This is my html code Please guide me in doing this. Thanks in advance

like image 354
Anjana Avatar asked Dec 31 '22 03:12

Anjana


2 Answers

You should use keydown event and use ViewChild to get text in text area

Updated: if you want to restrict only 100 words, you can add [attr.disabled]="words >100 ? '' : null" to disable textarea

HTML

 <textarea [attr.disabled]="words >100 ? '' : null" (keydown)="wordCounter()" #text id="wmd-input" name="post-text" 
class="wmd-input s-input bar0 js-post-body-field processed" data-post-type-id="2" cols="92" rows="15" tabindex="101" data-min-length="" oncopy="return false;" onpaste="return false;" oncut="return false;"></textarea>

    <div>Words:<span id="wordCount">{{ words }}</span></div>

TS

export class AppComponent {
  wordCount: any;

  @ViewChild("text") text: ElementRef;
  words: any;
  wordCounter() {
    //alert(this.text.nativeElement.value)
    this.wordCount = this.text ? this.text.nativeElement.value.split(/\s+/) : 0;
    this.words = this.wordCount ? this.wordCount.length : 0;
  }
}

Demo https://stackblitz.com/edit/angular-word-count

like image 108
Hien Nguyen Avatar answered Jan 05 '23 00:01

Hien Nguyen


You could use Angular Reactive Form control and use it's disable() function to achieve your requirement. Try the following

Controller

import { Component, OnInit } from '@angular/core';
import { FormControl, FormGroup } from '@angular/forms';

@Component({
  selector: 'input-autosize-textarea-example',
  templateUrl: './input-autosize-textarea-example.html',
  styleUrls: ['./input-autosize-textarea-example.css'],
})
export class InputAutosizeTextareaExample implements OnInit {
  public remainingWords = 100;

  public textareaForm = new FormGroup ({
    textinput: new FormControl()
  });

  ngOnInit() {
  }

  wordCounter() {
    this.remainingWords = this.textareaForm.value ? 100 - this.textareaForm.value.textinput.split(/\s+/).length : 100;
    if (this.remainingWords <= 0) {
      this.textareaForm.controls['textinput'].disable();
    }
  }
}

Template

<form [formGroup]="textareaForm">
  <textarea 
    formControlName="textinput"
    (keyup)="wordCounter()" 
    id="wmd-input" 
    name="post-text" 
    class="wmd-input s-input bar0 js-post-body-field processed" 
    data-post-type-id="2" 
    cols="92" rows="15" 
    tabindex="101" 
    data-min-length="" 
    oncopy="return false;" 
    onpaste="return false;" 
    oncut="return false;"></textarea>
</form>
<div style="font-style: italic;">
  {{ remainingWords }} words remaining...
</div>
<br>
{{textareaForm?.value | json}}

The ?. operator is called safe navigation operator and it is used to make sure the objects are defined before trying to access it's properties.

Working example: Stackblitz

like image 38
ruth Avatar answered Jan 04 '23 23:01

ruth