Hey Tatu,
I just don’t get it to work… The strategy is used but no value change is detected by the binder.
Where is a value change listener registered for the value property?
Could you give me some advise please?
import { html, LitElement } from "lit";
import { customElement, property, state } from "lit/decorators.js";
import { ClassicEditor, Essentials, Bold, Italic, Font, Paragraph, List, Link, Indent, IndentBlock, HorizontalLine, CodeBlock, GeneralHtmlSupport, SourceEditing, SpecialCharactersEssentials, SpecialCharacters, Autosave, EmitterMixin } from 'ckeditor5';
// import MathType from '@wiris/mathtype-ckeditor5/dist/index.js';
import 'ckeditor5/ckeditor5.css';
import type { AbstractModel, DetachedModelConstructor, FieldStrategy } from '@vaadin/hilla-lit-form';
import { Binder, StringModel } from '@vaadin/hilla-lit-form';
import { View } from "Frontend/views/view";
@customElement('ck-editor-field')
export class CKEditorField extends View {
@property({ type: String }) label = '';
@property({ type: String }) value = '';
@property({ type: Boolean }) required = false;
@property({ type: Boolean }) invalid = false;
@property({ type: String }) errorMessage = '';
private editor?: ClassicEditor
constructor() {
super()
}
connectedCallback() {
super.connectedCallback()
setTimeout(async () => {
const newLocal = document.querySelector('#editor');
if (newLocal) {
const editor = await ClassicEditor.create(newLocal as HTMLElement, {
plugins: [Autosave, Essentials, Bold, Italic, Font, Paragraph, List, Link, Indent, IndentBlock, HorizontalLine, CodeBlock, GeneralHtmlSupport, SourceEditing, SpecialCharacters, SpecialCharactersEssentials],
toolbar: [
'undo', 'redo', '|', 'bold', 'italic', 'fontColor', '|',
'numberedList', 'bulletedList', 'outdent', 'indent', '|',
'link', 'horizontalLine', 'codeBlock', 'specialCharacters', '|',
'sourceEditing'
],
autosave: { save: async () => { } }
})
editor.setData(this.value)
editor.model.document.on('change:data', () => {
this.onValueChanged(editor.getData())
})
}
})
}
disconnectedCallback() {
super.disconnectedCallback()
if (this.editor) {
this.editor.destroy()
this.editor = undefined
}
}
render() {
return html`
<div id="editor">
<button @click=${() => this.onValueChanged('button clock')}>Change Value</button>
</div>
`
}
onValueChanged(value: string) {
console.log("inner value change", value);
this.value = value;
}
}
export class CKEditorStrategy implements FieldStrategy {
element: CKEditorField;
constructor(element: CKEditorField) {
this.element = element;
}
set required(required: boolean) {
this.element.required = required;
}
set invalid(invalid: boolean) {
this.element.invalid = invalid;
}
set errorMessage(errorMessage: string) {
this.element.errorMessage = errorMessage;
}
// ...
validate = async () => [];
get value() {
return this.element.value;
}
set value(value) {
this.element.value = value;
}
setAttribute(key: string, val: unknown) {
if (val) {
this.element.setAttribute(key, '');
} else {
this.element.removeAttribute(key);
}
}
get validity() {
return {
badInput: false,
customError: false,
patternMismatch: false,
rangeOverflow: false,
rangeUnderflow: false,
stepMismatch: false,
tooLong: false,
tooShort: false,
typeMismatch: false,
valueMissing: false,
valid: true
};
}
checkValidity() {
return true;
}
removeEventListeners() { }
}
export class CKEditorBinder<M extends AbstractModel> extends Binder<M> {
constructor(context: Element, model: DetachedModelConstructor<M>) {
super(context, model);
}
override getFieldStrategy(element: any, model?: AbstractModel): FieldStrategy {
console.log(element.localName, model);
if (element.localName === 'ck-editor-field' && model instanceof StringModel) {
console.log("Match");
return new CKEditorStrategy(element);
}
return super.getFieldStrategy(element);
}
}