2

I'm struggling to get @Directive to work as intended.

I would like the Attr Directive to be able to access the model.password in the directive constructor and set variable varpassword with the current password.

I would also like to be able to retrieve all other inputs within the form field, how would i go about this?

The documentation for a lot of this is not complete since being in Beta i know.

I've been trying to figure this out for days with limited success. I've removed the imports that i have tried to get it working on because i think I'm confused how to use them properly within the directive i have tried "NgModel, NgControl, ControlGroup, NgFormModel, FormBuilder...".

My test example code below.

login-form.html

<form #testForm="ngForm">
    Email Address: 
    <input type="text" name="username" size="50" required="required" [(ngModel)]="model.username" ngControl="username" #username="ngForm" />

    Password: 
    <input type="password" name="password" size="20" required="required" [(ngModel)]="model.password" ngControl="password" #password="ngForm" testdir />

    <input type="submit" value="Login" />
</form>

app.ts

import {Component} from 'angular2/core';

import {TestDirective} from '../../directives/test.directive';

@Component({
    selector: 'test-app',
    templateUrl: 'login-form.html',
    directives: [TestDirective]
})
export class TestApp {}

test.directive.ts

import {Directive} from 'angular2/core';

@Directive({
    selector: '[testdir]',
    host: {
        '(keydown)': 'run()'
    }
})
export class TestDirective {

    varpassword: string;

    constructor() {
        this.varpassword = [******]
    }

    run() {
        console.log( this.varpassword );
    }

}

If anyone can point me in the right direction would be much appreciated.

2 Answers 2

6

You need to inject NgControl into your directive:

@Directive({
  (...)
})
export class TestDirective {
  varpassword: string;

  constructor(private ctrl:NgControl) {
  }

  ngOnInit() {
    this.varpassword = this.ctrl.value;
  }
}

Se this plunkr: https://plnkr.co/edit/3y4Qf7M4hb3zDIEJ773Q?p=preview.

Sign up to request clarification or add additional context in comments.

4 Comments

Thank you thats perfect. I was trying to set the variable in the constructor in my tests no wonder why it wasn't working. I've now worked how to also access the ngForm so when using console( this.form.controls ); I can see the object it returns, do you know of a way to check the input type for example password, input etc? Thanks Again.
You need to leverage lifecycle hooks of component. It's too early in the constructor... To have access to the input type, you need to inject the ElementRef. You can reach this hints though nativeElement.type on it. I updated the plunkr ;-)
Ok i see that is for attr directive input but what about all other inputs within the form object. What i'm trying to achive is to watch all inputs within the form for changes to the ngModel, the form can contain any amount of inputs so not just username and password. For example name, address1, address2, postcode, email, username, password, verifyPassword. I would loop through the ngForm.controls object and any input that is not type password i would push into a new array within the directive and use them values within a custom password validator. Thanks for the help :)
To be notified of changes for input, you could leverage the valueChanges property of controls. It's an observable so you can subscribe on them to be notified. See this article in section "Linking with a form element": restlet.com/blog/2016/04/12/….
1

Example of input directive with commas when focus out.

import {Directive, ElementRef} from '@angular/core';
    @Directive({
      selector: '[numberInput]',
      host: {
        '(focus)': '_onFocus()',
        '(blur)': '_onBlur()',
        '(keydown)': '_onKeypress($event)'
      }
    })
    export class InputNumberDirective {
      inputElement: ElementRef;

      constructor(el: ElementRef) {
        this.inputElement = el;
      }

      _onBlur() {
         this.inputElement.nativeElement.value = this.inputElement.nativeElement.value.length > 0 ? parseInt(this.inputElement.nativeElement.value).toString().replace(/(\d)(?=(\d\d\d)+(?!\d))/g, "$1,") : '';
      }

      _onKeypress(event: KeyboardEvent) {
          if((event.which>= 58 && event.which<=126) || (event.keyCode >= 33  && event.which<= 47)){
            event.preventDefault();
       }
          return event;
      }
    }

1 Comment

keyCode is deprecated and should not be used. developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/keyCode

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.