I am trying to use CKeditor with Blazor. I used Online builder to create a custom build, with ImageUpload and Base64UploadAdapter, and it is integrated in BlazorApp.
I can successfully show it on the page, and put / get HTML content from it. Source of the working version for Blazor app is here https://gitlab.com/dn-misc/BlazorCKEditor1/
But as I would like to inser image as Base64 encoded string directly in HTML content, when I try to upload image I get following error: Assertion Failed: Input argument is not an HTMLInputElement (from content-script.js)
I have successfully implemented Chris Pratt implementation. Check this out:
IMPORTANT: this works with ClassicEditor ONLY.
Blazor component, I called mine InputCKEditor.razor. Yeah I know, no very original.
@namespace SmartApp.Components
@inherits InputTextArea
@inject IJSRuntime JSRuntime
<textarea @attributes="AdditionalAttributes"
id="@Id"
class="@CssClass"
value="@CurrentValue"></textarea>
@code {
string _id;
[Parameter]
public string Id
{
get => _id ?? $"CKEditor_{_uid}";
set => _id = value;
}
readonly string _uid = Guid.NewGuid().ToString().ToLower().Replace("-", "");
protected override async Task OnAfterRenderAsync(bool firstRender)
{
if (firstRender)
await JSRuntime.InvokeVoidAsync("CKEditorInterop.init", Id, DotNetObjectReference.Create(this));
await base.OnAfterRenderAsync(firstRender);
}
[JSInvokable]
public Task EditorDataChanged(string data)
{
CurrentValue = data;
StateHasChanged();
return Task.CompletedTask;
}
protected override void Dispose(bool disposing)
{
JSRuntime.InvokeVoidAsync("CKEditorInterop.destroy", Id);
base.Dispose(disposing);
}
}
Then, you have to put this in your interop.js
CKEditorInterop = (() => {
var editors = {};
return {
init(id, dotNetReference) {
window.ClassicEditor
.create(document.getElementById(id))
.then(editor => {
editors[id] = editor;
editor.model.document.on('change:data', () => {
var data = editor.getData();
var el = document.createElement('div');
el.innerHTML = data;
if (el.innerText.trim() === '')
data = null;
dotNetReference.invokeMethodAsync('EditorDataChanged', data);
});
})
.catch(error => console.error(error));
},
destroy(id) {
editors[id].destroy()
.then(() => delete editors[id])
.catch(error => console.log(error));
}
};
})();
Now time to use it:
<form>
<label class="col-xl-3 col-lg-3 col-form-label text-sm-left text-lg-right">Description</label>
<div class="col-lg-9 col-xl-6">
<InputCKEditor @bind-Value="_model.Description" class="form-control form-control-solid form-control-lg"></InputCKEditor>
<ValidationMessage For="@(() => _model.Description)" />
</div>
</form>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With