Reputation: 1960
I have a page component (five-whys) with a number of inputs that the user can choose to finalize the input. When the user clicks finalize, all questions are made to be disabled.
five-whys.hbs:
{{#each this.whys as |why i|}}
<Generic::RichTextInput
@value={{why.content}}
@onChange={{action this.whyChanged i}}
@disabled={{this.isFinalized}} />
{{/each}}
<button {{on "click" this.finalizeWhy}}>Finalize</button>
five-whys.ts
interface AnalyzeFiveWhysArgs {
dataStory: DataStory;
}
export default class AnalyzeFiveWhys extends Component<AnalyzeFiveWhysArgs> {
@alias("args.dataStory.fiveWhysAnalysis") fiveWhysAnalysis
@tracked
isFinalized: boolean = this.fiveWhysAnalysis.isFinalized ?? false;
@tracked
whys: LocalWhy[] = this.fiveWhysAnalysis.whys;
@tracked
isFinalized: boolean = this.fiveWhysAnalysis.isFinalized ?? false;
@action
async finalizeWhy() {
this.isFinalized = true;
}
This works fine when my rich text component is just a regular text area. However, I am trying to implement tinymce which requires me to do stuff outside of Embers little safe space of magic.
Template:
<textarea id={{this.id}} disabled={{this.templatePieceIsDisabled}}>{{@value}}</textarea>
Typescript:
interface GenericRichTextInputArgs {
value?: string;
onChange: (value: string) => void;
name: string;
disabled?: boolean;
}
export default class GenericRichTextInput extends Component<GenericRichTextInputArgs> {
constructor(owner: unknown, args: GenericRichTextInputArgs) {
super(owner, args);
this.initializeTinymce();
}
id = this.args.name;
get editor() {
return tinymce.get(this.id);
}
get settings() {
console.log(this.args.disabled);
const settings: TinyMCESettings = {
selector: `#${this.id}`,
setup: (editor: Editor) => this.setupEditor(this, editor),
readonly: this.args.disabled ? this.args.disabled : false
};
return settings;
}
initializeTinymce() {
Ember.run.schedule('afterRender', () => {
console.log("re-initializing"); // I expect to see this log every time the isFinalized property in the five-whys component changes. But I only see it on page load.
tinymce.init(this.settings);
});
}
setupEditor(self: GenericRichTextInput, editor: Editor) {
... // details of tinymce API
}
}
When I click the finalize button, The effect of the disabled flag in the rich text component does not change.
The tinymce library I'm using sets the text area display to none and the aria-hidden to true. This is because it wraps the textarea in a widget. So I have to use the library's api to set disabled.
Upvotes: 0
Views: 1258
Reputation: 1960
I figured it out. Ember doesn't run the constructor for the update life-cycle event. So I need to tell Ember to re-run the initializer when the template gets re-rendered. I had to use https://github.com/emberjs/ember-render-modifiers to do this.
So my rich text editor template looks like:
<textarea
id={{this.id}}
{{did-update this.updateDisabled @disabled}}>
{{@value}}
</textarea>
And I added this action in the code behind of the rich text editor:
@action
updateDisabled(element: HTMLTextAreaElement, [disabled]: any[]) {
this.disabled = disabled;
this.editor.destroy();
this.initializeTinymce();
}
Upvotes: 1