Angular 2/4 : How to check length of input's value using directive?
21,990
Solution 1
You can track the input length changes in DoCheck:
Directive
Directive({ selector: '[inputfocus]' })
export class InputFocusedDirective implements DoCheck
{
public valLength;
@Input() inputfocus;
constructor(public el: ElementRef, public renderer: Renderer) {}
ngDoCheck(){
let valLength = this.el.nativeElement.value.length;
console.log("valLength "+ valLength );
if (valLength > 0) {
this.renderer.setElementClass(this.el.nativeElement.parentElement, 'focused', true);
}
else
{
this.renderer.setElementClass(this.el.nativeElement.parentElement, 'focused', false);
}
}
}
HTML
<div>
<input [inputfocus]="fname" name="name" [(ngModel)]="fname" type="text">
</div>
CSS:
input{
background-color:red;
}
.focused input{
background-color:green;
}
Solution 2
If all you are trying to do is apply a class to the containing element when an input has some text inside it, you do not need a directive for this.
<div id="i-contain-the-input" [ngClass]="{'focused': myInputValue && myInputValue.length > 0}">
<input [(ngModel)]="myInputValue" type="text">
</div>
<!-- myInputValue needs to be declared in your component -->
But if you absolutely must make a directive for this, then do the following:
@Directive({
selector: '[inputfocus]',
})
export class InputFocusedDirective {
constructor(private el: ElementRef, private render: Renderer) {
}
@HostListener('change') onChange() {
if (this.el.nativeElement.value.length > 0) {
this.renderer.setElementClass(this.el.nativeElement.parentElement, 'focused', true);
}
}
}
Solution 3
I have created a similar example.
import {Directive, ElementRef} from '@angular/core';
@Directive({
selector: '[inputfocus]'
})
export class DataDirective {
constructor(private el: ElementRef) {
var elem = el.nativeElement.value;
console.log(elem + "==> length = " + elem.length);
}
}
in the html part
<input class="mask-text" value="hello" inputfocus type="text"/>
Demo http://plnkr.co/edit/JX6P1vnqUJEzL94BOFuO?p=preview
Related videos on Youtube
Author by
AmitV
Updated on July 09, 2022Comments
-
AmitV almost 2 years
I've created one custom attribute directive that can validate input, It has value or not. Please refer below code.
I don't know why if condition is not working, in console.log it is showing 0 only. is there anything wrong in my code?
I tried with other angular's app lifecycle event too.
Thanks!
import { Directive, ElementRef, Input, AfterContentInit ,Renderer } from '@angular/core'; @Directive({ selector: '[inputfocus]' }) export class InputFocusedDirective implements AfterContentInit { public valLength; constructor(public el: ElementRef, public renderer: Renderer) {} ngAfterContentInit() { var valLength = this.el.nativeElement.value.length; consol.log("valLength "+ valLength ); if (valLength > 0) { this.renderer.setElementClass(this.el.nativeElement.parentElement, 'focused', true); } } }
-
Aakash Jain over 6 yearsIs your goal only to apply a class to the parent when the input element has something in it? Because that can be achieved in a much simpler manner, and using a custom directive for it is overkill.
-
AmitV over 6 years@Aakash, I'm using floating label type of input controls in my app and want to add focused class in edit mode. when there is value inside input, label should float to top.
-
Aakash Jain over 6 yearsCan you add a snippet from your tempate code to show how your labels and inputs are arranged?
-
AmitV over 6 years@Vega, Your code is working fine on change event as you have shared. I wrapped input text inside div and then typing in input are adding and removing focused class based on if condition. please check stackblitz.com/edit/angular-axnchs?file=app%2Fapp.component.ts. I want to update the same on component load that is when page get load, condition get check and class should remove or add to its parent div. I tried with ngOnInit() and ngAfterViewInit() but didn't work as expected.
-
AmitV over 6 yearsThanks! Vega for your reply and seriously I appreciate your solution, [class.focused]="fname?.length>0" I know about this solution and other too but there are thousands of text and number controls on form and I want achieve the same by adding simple attribute directive(in my case it is inputfocus). this will work same as HTML5 "required" attribute that you just add it and it will do its job. second I will be able to learn how to use attribute directive with its customize power.
-
AmitV over 6 yearswhat is new update dude? I'm not getting it.please help.
-
AmitV over 6 yearsHey dude! I also tried the same added ngAfterViewChecked() and It worked. :-) :-) check here stackblitz.com/edit/angular-axnchs?file=app%2Fapp.component.ts and you too did the same with some red highlight. now will check it inside project. thanks man :-)
-
AmitV over 6 yearsPlease update your answer that you have submitted previously so that I can accept it as right solution.
-
-
AmitV over 6 yearsThanks for your reply. In my app there are N no of input controls present. going for first approach will be lengthy. that is why I thought to create directive. I tried your code it is not working, please share working code on plunker if possible.
-
AmitV over 6 years@ Vega, Thanks, please visit this url stackblitz.com/edit/… are 3 text box two are with inputfocus directive and last one is without it. I created one more directive that is togglefocus.directive.ts that will host listener for focus & blur. try to focus on each text box u will notice in 2nd field focus is not working or I can say class is getting apply & removing instantly plz check DOM. 3rd field is getting focus and changing color based on focus and blur. I'm sure that If condition of DoCheck() is preventing it apply class on focus.
-
Vega over 6 years@AmitV, I am not sure to understand :( Could you please explain me again but is the expected behaviour? What is your goal? To change the class(color) on focus/blur based on the condition?
-
AmitV over 6 yearsOkay, please click on each textbox and check behavior of them. I want to add and remove focused class based some logic please check togglefocus.directive.ts. logic is straight if text box has value and u are focusing out then don't remove focused class and vice versa. my problem is that inputfocus directive & @hostlistener both working fine individually but not together please check 2nd textbox behavior background is not getting green but without inputfocus directive 3rd txtbox is behaving perfectly.
-
Vega over 6 yearsThe second one should be green on focus? It's red because of empty value, but when it's not empty, it's green. Should the second one stay stay green, when empty but focued? The third follows the second directive logic, so it's good also. Please tell me just what you want as behaviour, not what is not working.
-
AmitV over 6 yearsMy input controls are like floating label, on focus label moves to top and the same come down on blur if input don't have value thats why I've created that togglefocus.directive.ts. In edit mode when data come pre-field that time " inputfocus " directive that you shared with ngDoCheck() works and validate the field till this it is working fine. but when I'm removing character from txtbox and making it empty that time my hostlistner is not working properly and unable to add that focused class. in this case inputfocus directive and hostlistener are conflicting with each other as I found.
-
AmitV over 6 yearsPlease do empty txtbox 1 and then focus on it you will see txtbox will not get focused class but in case of txtbox 3 it is working fine. on focus of txtbox 2 you can guess easily what is going wrong.
-
AmitV over 6 yearsdid you understand my problem?
-
Vega over 6 yearsoops, I saw just now this. I am taking a look right now :)
-
AmitV over 6 yearsI got the solution dude. Just added one more if condition.