Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angular 2 surrounding an input tag with div via directive

I'm trying to create a directive which takes an input element and surrounds it with a div, so for example, my html would be something like:

<input type="text" class="form-control" inputWrapper />

and the desired outcome:

<div class="input-wrapper">
    <input type="text" class="from-control" />
</div>

Directive:

@Directive({
    selector: '[inputWrapper]'
})
export class InputWrapperDirective {
    constructor(private viewContainerRef: ViewContainerRef, private elementRef: ElementRef) {
        // what goes here?
    }
}
like image 255
PJ Martins Avatar asked Apr 07 '17 15:04

PJ Martins


People also ask

Can a directive have input?

Input data into a DirectiveWe can also extend or modify the behavior or functionality of a directive by inputtting data into the directive.

What is the use of div tag in Angular?

The <div> tag is used as a container for HTML elements - which is then styled with CSS or manipulated with JavaScript. The <div> tag is easily styled by using the class or id attribute.

Can we use two structural directive in a single HTML element?

we cannot use two structural directives on same element. Structural directives like ngfor can do complex things with the host element and its childrens.

What is the naming convention of built in directives in angular 2?

Naming Convention: *[name of directive] — Upper camel case is used for the directive class, while lower camel case is used for the directive's name. What sets them apart from other directives in Angular 2: Reshape DOM structure by adding or removing existing DOM elements and do not have templates.


1 Answers

here is how you do it with a directive. The code uses Renderer2, which I think is Angular 4. Probably the same thing can be achieved with Renderer (which is marked deprecated now)

I did all the work in the ngAfterViewInit method. You may probably use the constructor instead.

import { Directive, Renderer2, ElementRef, AfterViewInit } from '@angular/core'

@Directive({
    selector: '[inputWrapper]'
})
export class InputWrapperDirective implements AfterViewInit {
    constructor(private _renderer:Renderer2, private _el: ElementRef) {

    }

    ngAfterViewInit() {
        // Get parent of the original input element
        var parent = this._el.nativeElement.parentNode;

        // Create a div
        var divElement = this._renderer.createElement("div");

        // Add class "input-wrapper"
        this._renderer.addClass(divElement, "input-wrapper");

        // Add the div, just before the input
        this._renderer.insertBefore(parent, divElement, this._el.nativeElement);

        // Remove the input
        this._renderer.removeChild(parent, this._el.nativeElement);

        // Remove the directive attribute (not really necessary, but just to be clean)
        this._renderer.removeAttribute(this._el.nativeElement, "inputWrapper"); 

        // Re-add it inside the div
        this._renderer.appendChild(divElement, this._el.nativeElement);

    }

}
like image 128
kontiki Avatar answered Oct 05 '22 19:10

kontiki