B Hull
B Hull

Reputation: 3223

how to update model only on textarea blur in angular2

Hi I have a textarea which is bound to mymodel. Whenever you change the value in the textarea it autochanges the model.

What i want it to do is update the model only on blur on the textarea instead of live, how would I do this?

I still want the model change to update the textarea when the textarea is not in focus.

@Component({
    selector: 'app',
    template: `<textarea [(ngModel)]="mymodel"></textarea>
<br><br>
{{mymodel}}
`
})
class App {
public mymodel: any = "hello world";
    constructor() {}
}

Upvotes: 3

Views: 10572

Answers (4)

instantaphex
instantaphex

Reputation: 1001

One possible way to accomplish this is to create a Value Accessor for your text area that only updates on blur. Something like this:

import { Directive, Renderer, ElementRef, HostListener, forwardRef, Input } from '@angular/core';
import { NG_VALUE_ACCESSOR, ControlValueAccessor } from '@angular/forms';

@Directive({
  selector: 'textarea',
  providers: [
    {
      provide: NG_VALUE_ACCESSOR,
      useExisting: forwardRef(() => UpdateOnBlurValueAccessorDirective),
      multi: true,
    },
  ],
})
export class UpdateOnBlurValueAccessorDirective implements ControlValueAccessor {
  onChange = (_: any) => {};
  onTouched = () => {};
  constructor(private _renderer: Renderer, private _elementRef: ElementRef) {}

  writeValue(value: any): void {
    const normalizedValue = !value ? '' : value;
    this._renderer.setElementProperty(this._elementRef.nativeElement, 'value', normalizedValue);
  }

  registerOnChange(fn: (_: any) => void): void {
    this.onChange = fn;
  }

  registerOnTouched(fn: () => void): void {
    this.onTouched = fn;
  }

  setDisabledState(isDisabled: boolean): void {
    this._renderer.setElementProperty(this._elementRef.nativeElement, 'disabled', isDisabled);
  }

  @HostListener('blur', [ '$event' ])
  public onBlur(evt: any): void {
    if (evt.target.value) {
      this.onChange(evt.target.value);
    }
  }
}

Upvotes: 1

Pardeep Jain
Pardeep Jain

Reputation: 86740

you can call (change) method on the textarea then it will update your modal only after when your remove focus from the textarea instead of live i.e using [(ngModel)] do like this:

@Component({
    selector: 'app',
    template: `<textarea placeholder="TextArea" #text (change)="mymodel = text.value" [value]='mymodel'></textarea> <br><br>
{{mymodel}}
`
})

class App {
public mymodel: any = "hello world";
    constructor() {}
}

here is working plnkr for the same.

http://plnkr.co/edit/eMkfsjAcSy3kj9MzQvoz?p=preview

Upvotes: 3

Abdulrahman Alsoghayer
Abdulrahman Alsoghayer

Reputation: 16540

You could "one way" bind the model to the textarea and update the model on the blur event only. Keep an eye on "#ta", this is a local variable referencing the textarea element so you can access it's value on the blur event.

Working Plunker and code:

import {Component} from 'angular2/core';
@Component({
    selector: 'my-app',
    template: `<textarea #ta (blur)="mymodel=ta.value" [value]="mymodel"></textarea>
<br><br>
{{mymodel}}
`
})

export class AppComponent {
    public mymodel: any = "hello world";
    constructor() { }
}

Upvotes: 7

Danyal
Danyal

Reputation: 370

You have to bind ng-model to the textarea, it works even if you don't have the "value" variable in your initial json data. I have added a button for demo purpose. Full example on JSFIDDLE

< textarea placeholder="Comments" ng-model="value"></textarea>

continue here

Upvotes: -5

Related Questions