5
  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

Anjana
  • 366
  • 5
  • 21
  • Is this helpful? https://stackoverflow.com/questions/18679576/counting-words-in-string –  Apr 23 '20 at 07:38
  • Thanks @MikeS. ,but I need to display the wordcount as the user types on the screen to let him know how many words he has already typed. Can I achieve this with ngonchanges(). I don't no how to do that. I'm new to angular – Anjana Apr 23 '20 at 07:43
  • You can bind to `this.wordCount` anywhere in your template to display the word count. E.g. `
    {{ wordCount }}
    `. Same with `this.words`, whatever you need to display.
    –  Apr 23 '20 at 07:45
  • Words: {{ wordCount }} Yes did that, but wordcount is not incremented, it stays at 0 – Anjana Apr 23 '20 at 07:55
  • Then that's a problem with your function, read the link I posted. –  Apr 23 '20 at 08:46

3 Answers3

5

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

Hien Nguyen
  • 24,551
  • 7
  • 52
  • 62
  • Works perfectly. Thanks, @Hien Nguyen, but how can I limit the word count. User should be restricted from typing if he/she crosses 100 words. Is there any textarea property like Max length() (which limits character), to limit word count – Anjana Apr 23 '20 at 08:49
  • One more thing, here if I type more than 100 words, text area is disabled from typing as well as editing. If I want to change some content, I cant do it. How to disable from typing alone?? @Hien Nguyen – Anjana May 06 '20 at 07:49
3

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

ruth
  • 29,535
  • 4
  • 30
  • 57
  • Thank you so much @Michael D. Working perfectly. But how to take word count, instead of character count? – Anjana Apr 23 '20 at 08:19
  • 1
    I mistook words for characters. I've updated the code. Please check if it works for you. – ruth Apr 23 '20 at 09:09
2

check my answer in :- https://codesandbox.io/s/damp-mountain-0vpe3

you just have to do the followig :-

In app.module.ts :-

  1. import { FormsModule } from "@angular/forms"
  2. put FormsModule in imports array like this - imports: [BrowserModule, FormsModule]

Now use ngModel binding in app.component.html

<div>
  <div>
    <h2>Type below</h2>
    <input type="text" [(ngModel)]="myText" placeholder=" type here..." />
  </div>
  <br /><br />
  <div class="wordCount">
    <div>
      Your Text : <span><b> {{myText}} </b></span> <br />
      <br />
      Count: <span><b> {{myText.length}} </b></span>
    </div>
  </div>
</div>

Scrrenshot:-

Just check it out

Arnab_Datta
  • 602
  • 7
  • 8