I have found a solution to my problem.
Old problematic code:
HTML:
<div contentEditable="true" attr.placeholder="{{placeholder}}"
[textContent]="model"
(input)="inputed($event)">
</div>
Typescript file:
@Input() model = '';
inputed(event){
this.model = event.target.textContent;
this.propagateChange(this.model.trim());
}
New code, the solution
HTML:
<div contenteditable="true" attr.placeholder="{{placeholder}}"
[textContent]="model"
(input)="inputed($event)" >
</div>
Typescript file
@Input() model = '';
inputed(event){
this.propagateChange(event.target.textContent);
}
There is more code in the typescript file that allows for the component to be used as a form input in a reactive form. Below is the full code for the typescript file.
import { Component, OnInit, forwardRef, Input } from '@angular/core';
import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms';
@Component({
selector: 'custom-textarea',
templateUrl: './custom-textarea.component.html',
styleUrls: ['./custom-textarea.component.scss'],
providers: [
{
provide: NG_VALUE_ACCESSOR,
multi: true,
useExisting: forwardRef(() => CustomTextareaComponent),
}
]
})
export class CustomTextareaComponent implements ControlValueAccessor, OnInit {
@Input() placeholder:string = "";
propagateChange = (_: any) => {};
writeValue(obj: any): void {
if (obj !== undefined) {
this.model = obj;
}
}
registerOnChange(fn: any): void {
this.propagateChange = fn;
}
registerOnTouched(fn: any): void {
// We don’t want to do anything at this event,
// so we can implement the interface with an empty function.
}
setDisabledState?(isDisabled: boolean): void {
// We don’t want to do anything at this event,
// so we can implement the interface with an empty function.
}
constructor() { }
ngOnInit() { }
@Input() model = '';
inputed(event){
this.propagateChange(event.target.textContent);
}
}