Skip to content

Custom Value Accessors with ion-input (Ionic 2) #6580

@endoooo

Description

@endoooo

hey guys!

I'm having problem using a custom value accessor with ion-input.
what I'm trying to do is to format an input text field while the user is typing, to enhance the user experience, like this: 12345678900a => 123.456.789-00 (it removes all the non-digit characters and apply the dots and dash).

to achieve this, I've created a custom value accessor as discussed in angular/angular#6174.

the problem is that when I use the custom directive with a "pure" input, the value saved to ngFormControl is correct, but when I use the same directive in a ion-input, the value passed to the ngFormControl is not the one that the user is actually seeing, but the value before the formatting (for instance, if the user types 123a, what he sees in the input is 123, but the value in the model is 123a).

thank you and congrats for the outstanding work with Ionic 2!


the code (excerpts) from the custom value accessor, form component and form template:

custom value accessor

@Directive ({
  selector: '[agl-id-num]',
  host: {
    '(input)': 'doOnChange($event.target)',
    '(blur)': 'doOnBlur($event.target)'
  },
  bindings: [ CUSTOM_VALUE_ACCESSOR ]
})
export class IdNumAccessor extends DefaultValueAccessor {

  constructor(_renderer: Renderer, _elementRef: ElementRef) {
    super(_renderer, _elementRef);
  }

  writeValue(value:any):void {
    if (value!=null) {
      super.writeValue(value);
    }
  }

  doOnChange(elt) {
    // prevent user to input non-digit characters while typing
    // and limit user input to 11 characters
    let val = elt.value
      .replace(/\D/g, '')
      .substring(0,11);

    elt.value = val; // this is what changes the input value as user types

    this.onChange(val); // this is what saves the value to the model
  }

  doOnBlur(elt) {
    // format field on blur only
    let val = elt.value;
    if (val.length === 11) {
      elt.value = val.replace(/^(\d{3})(\d{3})(\d{3})(\d{2})/, '$1.$2.$3-$4');
    }
  }
}

form component

@Component({
  selector: 'agl-client-register-form',
  templateUrl: 'build/components/clients/client-register-form/client-register-form.component.html',
  directives: [ FORM_DIRECTIVES, IdNumAccessor ]
})
export class ClientRegisterFormComponent implements OnInit {
  form: ControlGroup;  

  @Output() onFormSubmit = new EventEmitter();
  @Input() initialValues;

  constructor(
    private fb: FormBuilder) {}

  ngOnInit() {
    console.log(this.initialValues);

    this.form = this.fb.group({  
      'name':               [this.initialValues.name, Validators.required],
      'idNum':              [this.initialValues.idNum, Validators.required],
      'idNumTest':          [this.initialValues.idNum, Validators.required],
      'email':              [this.initialValues.email],
      'celphone':           [this.initialValues.celphone],
      'sendBoletoToMyself': [this.initialValues.sendBoletoToMyself]
    });
  }

  onSubmit():void {
    console.log(this.form.value);
  }
}

form template

<form novalidate
    [ngFormModel]="form"
    (ngSubmit)="onSubmit()">
    <ion-list>
        <!-- using with "pure" input -->
        <input
            agl-id-num
            type="tel"
            [ngFormControl]="form.controls['idNumTest']"
            required />
        <ion-item>
            <ion-label floating>Id Num*</ion-label>
            <!-- using with ion-input (described problem) -->
            <ion-input
                agl-id-num
                type="tel"
                [ngFormControl]="form.controls['idNum']"
                required>
            </ion-input>
        </ion-item>
    </ion-list>
    <div padding>
        <button block type="submit">Register</button>
    </div>
</form>

using Ionic 2.0.0-beta.6

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions