Reputation: 11
I'm trying to implement a "character countdown" in Angular 2 on an input element, similar to how Twitter enforces the 140 character limit and updates the user in real time. I'd like to show the user how many characters they have left in real-time, so as the user types into the input, the character countdown updates and, ultimately will reach "0" as the user continues to type.
I understand how to enforce the "maxlength" on the input element, but I'm requesting guidance on how to implement the countdown. This is a similar request to the Angular 1 post here: angularjs text area character counter
Is jQuery necessary here, or is there an "Angular 2 way" through binding that would work?
Upvotes: 1
Views: 6550
Reputation: 1061
Hi Try using angular directive as follows:
import { Directive, HostListener, ElementRef, Input, ViewChild, } from '@angular/core';
import { NgControl } from '@angular/forms';
/**
* For Showing the character left.
*/
@Directive({
selector: '[characterLeft]',
})
export class CharacterLeftDirective {
@Input() maxLength: string;
public textValue: string;
constructor(private elRef: ElementRef, private _ngControl: NgControl) {
}
private _showMessage(maxLength, textLength): void {
this.elRef.nativeElement.nextElementSibling.innerHTML = maxLength - textLength + ' Character(s) left'
}
@HostListener('keyup', ['$event']) toDecimal($event: any) {
$event.preventDefault();
const value: any = $event.target.value;
if (value) {
this._showMessage(this.maxLength, value.length);
} else {
this._showMessage(this.maxLength, 0);
}
}
}
In HTML
<textarea formControlName="message_content" class="form-control mb-2" rows="8" placeholder="" [maxLength]="160" characterLeft maxlength="160"></textarea>
<div class="text-danger"></div>
Upvotes: 0
Reputation: 130
<small class="form-text text-muted"><code>{{2000- incidentDescription.value.length}} </code> Remaining characters</small>
<textarea id="incidentDesc" #incidentDescription class="form-control" formControlName="incidentDesc" maxLength="2000"></textarea>
add a Reference to the control #incidentDescription. Then set the maxLenght to the control,Then do the math in the code block
{{2000- incidentDescription.value.length}}
Upvotes: 1
Reputation: 12390
You can create a pipe for it:
import { Pipe, PipeTransform } from '@angular/core';
@Pipe({
name: 'countdown',
pure: true
})
export class CountdownPipe implements PipeTransform {
transform(text: string, args: number) {
let maxLength = args || 0;
let length = text.length;
return (maxLength - length);
}
}
Your HTML
<label> {{myText | countdown}} characters remaining</label>
This is a working plunker: http://plnkr.co/edit/mtGpkhLW77Jimtdtymbh?p=preview
Upvotes: 8
Reputation: 55443
There are many ways to do it. You can also do it using pipe. But here, I'll show you how you can do it within component.
This is angular2 way.
Working Demo : https://plnkr.co/edit/QTn81qKBAi0mD15b94Hs?p=preview
@Component({
selector: 'my-app',
template: `
<label><b>Tweet</b></label>
<bR>
<textarea cols=40 rows=3 (keyup)="count(tweetmsg)"
[(ngModel)]="tweetmsg"
>
</textarea> {{characterleft}} charcter(s) left
`,
})
export class AppComponent {
maxlength=20;
characterleft=this.maxlength;
count(msg){
if(this.maxlength>=msg.length){
this.characterleft=(this.maxlength)-(msg.length);
}
else{
this.tweetmsg = msg.substr(0, msg.length - 1);
console.log(msg);
}
}
}
Upvotes: 3
Reputation: 4524
You can bind [(ngModel)] and (keypress) to the input :
@Component({
selector: 'my-app',
template: `<input [(ngModel)]="currentText" (keypress)="changed()">
chars left : {{ charsLeft }}
`
})
export class AppComponent {
public currentText: string = '';
public charsLeft: string = 140;
changed() {
this.charsLeft = 140 - this.currentText.length;
}
}
Working plunker : http://plnkr.co/edit/ET38TnbDLdKuHEQ9e2cb?p=preview
Upvotes: 4