tinymce-blazor
tinymce-blazor copied to clipboard
Set dynamically height of editor acording to content for read only mode.
I have integrated TinyMCE editor 6 to .NET 7 blazor web assembly app according to official doc. https://www.tiny.cloud/docs/tinymce/6/blazor-ref/ https://www.tiny.cloud/docs/tinymce/6/blazor-cloud/
Nuget packages:
<PackageReference Include="TinyMCE" Version="6.4.2" />
<PackageReference Include="TinyMCE.Blazor" Version="1.0.4" />
I'm using TinyMCE Editor component also for 'read only' mode and I have issue with setting dynamically height of editor acording to content.
I'm using currently autoresize
plugin, but it has some bug and it not always resize editor correctly. Sometimes I can see just first 3 lines of text. This bug happens totally randomly.
This is how it looks like if it will not resize correctly.
This is how it looks like if it will resize correctly.
<MudCard>
<MudCardContent>
<Editor
Value="@_html"
Conf="@_editorReadOnlyConfig"
Disable=true
ScriptSrc="/lib/tinymce/tinymce.min.js"
/>
</MudCardContent>
</MudCard>
private readonly Dictionary<string, object> _editorReadOnlyConfig = new()
{
{ "plugins", new string[] { "autoresize" } }, // https://www.tiny.cloud/docs/plugins/opensource/autoresize/
{ "toolbar", false },
{ "menubar", false },
{ "statusbar", false },
};
Any ideas how to deal with this? Can i do the same thing just with css? I'm using Editor component in readonly mode to view html because the blazor app will break all css if i would render the html as MarkupString.
Thank you!
Ref: INT-3183
I hacked it by invoking tiny mce command 'autoResizeCommand' 500ms after blazor component with editor is initialized. Which is really nasty fix. See code below.
Can you add to <Editor> component event which will fire after content is loaded or something like that? I think calling StateHasChanged() after content is loaded is sufficient.
@using TinyMCE.Blazor
<Editor Value="@HtmlString"
Conf="@_editorReadOnlyConfig"
Disable=true
ScriptSrc="/lib/tinymce/tinymce.min.js" />
public partial class ReadonlyEditor
{
private readonly Dictionary<string, object> _editorReadOnlyConfig = new()
{
{ "plugins", new string[] { "autoresize" } }, // https://www.tiny.cloud/docs/plugins/opensource/autoresize/
{ "toolbar", false },
{ "menubar", false },
{ "statusbar", false },
};
[Inject]
public IJSRuntime JSRuntime { get; set; } = default!;
[Parameter, EditorRequired]
public string HtmlString { get; set; } = default!;
protected async override Task OnInitializedAsync()
{
await Task.Delay(500);
await JSRuntime.InvokeVoidAsync("autoResizeCommand");
await base.OnInitializedAsync();
}
}
window.autoResizeCommand = () => {
const global = typeof window !== 'undefined' ? window : global;
try {
global.tinymce.activeEditor.execCommand('mceAutoResize');
} catch (e) {
console.log(e);
}
}
Okey, Can you add to component event which will fire after content is loaded or something like that? I think calling StateHasChanged() after content is loaded is sufficient.
this was too abcisious claim :D this is not true. It works just with executing autoResizeCommand
command after 500MS. Can I do this with some tiny mce event?
I have tried this but it did not worked:
window.editorEventsConfiguration = {
setup: (editor) => {
editor.on('LoadContent', (e) => {
console.log('The Editor has load content.');
try {
editor.activeEditor.execCommand('mceAutoResize');
} catch (e) {
console.log(e)
}
});
},
init_instance_callback: (editor) => {
editor.on('ExecCommand', (e) => {
console.log(`The ${e.command} command was fired.`);
});
editor.on('LoadContent', (e) => {
console.log('AAAAAAAAAThe Editor has initialized.');
editor.activeEditor.execCommand('mceAutoResize');
});
}]
}
@using TinyMCE.Blazor
<Editor Id="@_editorId"
Value="@HtmlString"
Conf="@_editorReadOnlyConfig"
JsConfSrc="editorEventsConfiguration"
Disable=true
ScriptSrc="/lib/tinymce/tinymce.min.js" />
This code throws
window.editorEventsConfiguration = {
setup: (editor, tinyEventHandler) => {
tinyEventHandler.bindEvent(editor, 'Load', (e) => {
try {
editor.execCommand('mceAutoResize');
} catch (e) {
console.log(e);
console.log('Load');
}
});
tinyEventHandler.bindEvent(editor, 'LoadContent', (e) => {
try {
console.log(editor)
editor.execCommand('mceAutoResize');
} catch (e) {
console.log(e);
console.log('LoadContent');
}
});
tinyEventHandler.bindEvent(editor, 'ScriptsLoaded', (e) => {
try {
console.log('ScriptsLoaded Enter');
console.log(editor)
editor.execCommand('mceAutoResize');
} catch (e) {
console.log(e);
console.log('ScriptsLoaded');
}
const global = typeof window !== 'undefined' ? window : global;
try {
global.tinymce.activeEditor.execCommand('mceAutoResize');
console.log("global done");
} catch (e) {
console.log(e);
console.log("global");
}
});
},
}
this error:
ScriptsLoaded Enter
main.min.js:1 kT {plugins: {…}, contentCSS: Array(0), contentStyles: Array(0), loadedCSS: {…}, isNotDirty: true, …}
main.min.js:1 TypeError: Cannot read properties of undefined (reading 'getRng')
at tinymce.min.js:4:382988
at tinymce.min.js:4:383369
at mceFocus (tinymce.min.js:4:383375)
at $O.execCommand (tinymce.min.js:4:383961)
at kT.execCommand (tinymce.min.js:4:411066)
at kT.focus (tinymce.min.js:4:410376)
at $O.execCommand (tinymce.min.js:4:383820)
at kT.execCommand (tinymce.min.js:4:411066)
at kT.<anonymous> (main.min.js:1:543)
at JO.dispatch (tinymce.min.js:4:386989)
main.min.js:1 ScriptsLoaded
main.min.js:1 TypeError: Cannot read properties of undefined (reading 'getRng')
at tinymce.min.js:4:382988
at tinymce.min.js:4:383369
at mceFocus (tinymce.min.js:4:383375)
at $O.execCommand (tinymce.min.js:4:383961)
at kT.execCommand (tinymce.min.js:4:411066)
at kT.focus (tinymce.min.js:4:410376)
at $O.execCommand (tinymce.min.js:4:383820)
at kT.execCommand (tinymce.min.js:4:411066)
at kT.<anonymous> (main.min.js:1:696)
at JO.dispatch (tinymce.min.js:4:386989)
main.min.js:1 global
main.min.js:1 TypeError: Cannot read properties of undefined (reading 'getRng')
at tinymce.min.js:4:382988
at tinymce.min.js:4:383369
at mceFocus (tinymce.min.js:4:383375)
at $O.execCommand (tinymce.min.js:4:383961)
at kT.execCommand (tinymce.min.js:4:411066)
at kT.focus (tinymce.min.js:4:410376)
at $O.execCommand (tinymce.min.js:4:383820)
at kT.execCommand (tinymce.min.js:4:411066)
at kT.<anonymous> (main.min.js:1:237)
at JO.dispatch (tinymce.min.js:4:386989)
main.min.js:1 Load
main.min.js:1 kT {plugins: {…}, contentCSS: Array(2), contentStyles: Array(0), loadedCSS: {…}, isNotDirty: true, …}
Any ideas how to force editor resize? How is possible that https://github.com/tinymce/tinymce-blazor/issues/69#issuecomment-1591996388 this works, but this events does not works?
Okey I hacked this bug with better solution. I try to execute every 100 ms autoResizeCommand
command until it succeeds.
protected async override Task OnInitializedAsync()
{
bool success;
do
{
await Task.Delay(100);
success = await JSRuntime.InvokeAsync<bool>("");
}
while (!success);
await base.OnInitializedAsync();
}
window.autoResizeCommand = () => {
try {
const global = typeof window !== 'undefined' ? window : global;
if (global.tinymce && global.tinymce.activeEditor) {
global.tinymce.activeEditor.execCommand('mceAutoResize');
return true;
}
return false;
} catch (e) {
return false;
}
}