bkinsey808
bkinsey808

Reputation: 3219

Can a custom directive set the placeholder for an input using Angular Material?

Consider my html:

  <md-input-container>
    <input mdInput myCustomDirective
      formControlName="email"
    >
  </md-input-container>

In my custom directive, I want to set the placeholder.

I tried naive code like this and failed:

@Directive({
  selector: '[myCustomDirective]',
})
export class MyCustomDirective implements OnInit, AfterViewInit {


  constructor(
    private elementRef: ElementRef,
    private renderer2: Renderer2,
  ) {}

  ngAfterViewInit() {
    this.renderer2.setAttribute(
      this.elementRef.nativeElement,
      'placeholder',
      'test',
    );
  }
}

It doesn't seem to matter whether I put the setAttribute code in the constructor or in any of the lifecycle hooks.

Is there another way I haven't thought of?

I'm using reactive forms and OnPush change detection strategy if that makes any difference.

Upvotes: 2

Views: 3651

Answers (1)

dbandstra
dbandstra

Reputation: 1314

This seems to work, although it's pretty hacky (because MdInputDirective's placeholder field is actually an input). Although, any imperative-style solution tastes bad to me.

import {MdInputDirective} from '@angular/forms';

@Directive({
  selector: '[myCustomDirective]'
})
export class MyCustomDirective {
  constructor(@Self() private input: MdInputDirective) {}

  ngAfterViewInit() {
    this.input.placeholder = 'test';
  }
}

An alternate solution could be something like: Put your directive on the md-input-container element instead of the input element, then create a myCustomDirectivePlaceholder component, which injects myCustomDirective to get the needed string, and use them like so:

<md-input-container myCustomDirective>
  <input mdInput>
  <md-placeholder>
    <myCustomDirectivePlaceholder></myCustomDirectivePlaceholder>
  </md-placeholder>
</md-input-container>

Upvotes: 4

Related Questions