7

I'm trying to have an input field format/mask values as they are typed, while having the actual model retain the raw (or differently formatted) value. I'm thinking phone numbers etc, but for simplicity am using uppercase for testing.

I've tried a bunch of stuff, hoping its as simple as a directive. But can't seem to get the display value to depart from the form value.

plunk: http://plnkr.co/edit/VH5zn4S8q28CBpFutBlx?p=preview

Here's the directive:

@Directive({
  selector: '[uppercase]',
  host: {
    '(input)': 'onInputChange()',
  }
})

export class UppercaseDirective {

  constructor(private model: NgFormControl) { }

  onInputChange() {
    let newValue = this.model.value.toUpperCase();
    this.model.viewToModelUpdate(newValue);
    this.model.valueAccessor.writeValue(newValue);
  }

}

and the form:

<form [ngFormModel]='myForm'>
  <input [ngFormControl]='myForm.controls.field' uppercase>
  <div>
    {{ myForm.value.field }}
  </div>
</form>
2
  • why not Pipes? Sounds like you just want a different way of displaying the text. Commented Jun 8, 2016 at 19:22
  • I want the formatting to happen in the input box - an input mask. I'm only displaying the value in the view for testing purposes. Commented Jun 8, 2016 at 19:28

2 Answers 2

2

Try to update control reference directly like this:

onInputChange() {
  let newValue = this.model.value.toUpperCase();
  this.model.control.updateValue(newValue);
}

See also plunker http://plnkr.co/edit/XYPWYgA8lbg2EdxPqzWj?p=preview

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

1 Comment

Makes sense. Thanks. I was trying to have the model value and display value different, but your answer gave me the answer: plnkr.co/edit/VH5zn4S8q28CBpFutBlx?p=preview
1

To be honest, i am still learning angular2 and the tech is still really immature to say this is the best way of doing it but after playing around with it:

import {Directive, ElementRef, Output, EventEmitter} from '@angular/core';
import {NgFormControl} from '@angular/common';

@Directive({
  selector: '[uppercase]',
  host: {
    '(input)': 'onInputChange()',
  }
})

export class UppercaseDirective {

  @Output() onChange = new EventEmitter();
  rawValue: string = '';

  constructor(private model: NgFormControl, private elementRef: ElementRef) { }

  onInputChange() {
    let str = this.model.value;
    this.rawValue = this.rawValue.substring(0, str.length) + str.substring(this.rawValue.length, str.length);
    let newValue = this.rawValue.toUpperCase();
    this.model.viewToModelUpdate(newValue);
    this.model.valueAccessor.writeValue(newValue);
    this.onChange.emit(this.rawValue);
  }

}

then you can get it like this:

<input [ngFormControl]='myForm.controls.field' uppercase (onChange)="raw = $event">
<div>
   {{ raw }}
</div>

Since whenever you update the model, the variable will change. You have to do is separate. Tried it in your plnkr and it worked.

EDIT: Might need some work for different scenarios though haha

2 Comments

Thanks Ed. What I'm trying to achieve though, is have the form model contain the raw value.
@Steve This might interest you stackoverflow.com/questions/37800841/…

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.