Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angular 2 - Input mask: Input box display formatted value, while model retains unformatted value

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>
like image 510
Steve Avatar asked Jun 08 '16 19:06

Steve


2 Answers

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

like image 65
yurzui Avatar answered Nov 19 '22 03:11

yurzui


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

like image 34
Ed Morales Avatar answered Nov 19 '22 03:11

Ed Morales