Angular2 on focus event to add class
Solution 1
Update
@Directive({selector: '.md-input', host: {
'(focus)': 'setInputFocus(true)',
'(blur)': 'setInputFocus(false)',
}})
class MaterialDesignDirective {
MaterialDesignDirective(private _elementRef: ElementRef, private _renderer: Renderer) {}
setInputFocus(isSet: boolean): void {
this.renderer.setElementClass(this.elementRef.nativeElement.parentElement, 'md-input-focus', isSet);
}
}
Original
This can easily be done without ElementRef
and Renderer
(what you should strive for in Angular2) by defining host bindings:
import {Directive, ElementRef, Renderer, Input} from 'angular2/core';
@Directive({
selector: '.mdInput',
host: {
'(focus)':'_onFocus()',
'(blur)':'_onBlur()',
'[class.md-input-focus]':'inputFocusClass'
}
})
export class MaterialDesignDirective {
inputFocusClass: bool = false;
_onFocus() {
this.inputFocusClass = true;
}
_onBlur() {
this.inputFocusClass = false;
}
}
or a bit more terse
@Directive({
selector: '.mdInput',
host: {
'(focus)':'_setInputFocus(true)',
'(blur)':'_setInputFocus(false)',
'[class.md-input-focus]':'inputFocusClass'
}
})
export class MaterialDesignDirective {
inputFocusClass: bool = false;
_setInputFocus(isFocus:bool) {
this.inputFocusClass = isFocus;
}
}
I tried it only in Dart where it works fine. I hope I translated it correctly to TS.
Don't forget to add the class to the directives:
of the element where you use the directive.
Solution 2
In addition to previous answers, if you don't want to add a directive, for the specific component (you already have a directive for a parent component, you are using Ionic 2 page or something else), you inject the renderer by adding private _renderer: Renderer
in the page constructor and update the element using the event target like this:
html:
(dragstart)="dragStart($event)"
TS:
dragStart(ev){
this._renderer.setElementClass(ev.target, "myClass", true)
}
Edit: to remove the class just do:
dragEnd(ev){
this._renderer.setElementClass(ev.target, "myClass", false)
}
Mad Eddie
Updated on June 19, 2020Comments
-
Mad Eddie about 4 years
I'm looking to update an Angular 1 app to Angular 2 and am having an issue with one of my old directives.
The idea is simple. When an input field is focused a class should be added (md-input-focus) and another be removed (md-input-wrapper). Then this process should be reversed on "blur" event - i.e. focus lost.
My old directive simply included the lines
.directive('mdInput',[ '$timeout', function ($timeout) { return { restrict: 'A', scope: { ngModel: '=' }, link: function (scope, elem, attrs) { var $elem = $(elem); $elem.on('focus', function() { $elem.closest('.md-input-wrapper').addClass('md-input-focus') }) .on('blur', function() { $(this).closest('.md-input-wrapper').removeClass('md-input-focus'); }) }
etc...
I obviously have the classic start to my directive but have run out of.....skill
import {Directive, ElementRef, Renderer, Input} from 'angular2/core'; @Directive({ selector: '.mdInput', }) export class MaterialDesignDirective { constructor(el: ElementRef, renderer: Renderer) { // Insert inciteful code here to do the above } }
Any help would be appreciated.
UPDATE:
The HTML would look like (before the input element was focused):
<div class="md-input-wrapper"> <input type="text" class="md-input"> </div>
and then
<div class="md-input-wrapper md-input-focus"> <input type="text" class="md-input"> </div>
after.
The input element is the only one which can receive a focus event (and therefore the target for the directive) however the parent
<div>
requires the class addition and removal.Further help
Please see Plunker for help/explanation - would be great if someone could help