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.
Page component
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.
My rich text component:
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.
Note:
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.
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:
And I added this action in the code behind of the rich text editor: