Controls and Knockout binding handlers

Hey,

I’ve been trying to make a control work with QuillJS instead of CKeditor (available in the community controls). I tried following the CKeditor sample but i’m not able to update the ViewModel value.

My control.cs:

public string HtmlContent
{
    get { return (string)GetValue(HtmlContentProperty); }
    set { SetValue(HtmlContentProperty, value); }
}
public static readonly DotvvmProperty HtmlContentProperty
    = DotvvmProperty.Register<string, TextEditor>(c => c.HtmlContent, null);

protected override void AddAttributesToRender(IHtmlWriter writer, IDotvvmRequestContext context)
{
    this.AddDotvvmUniqueIdAttribute();
    base.AddAttributesToRender(writer, context);

    var group = new KnockoutBindingGroup();
    group.Add("html", this, HtmlContentProperty);

    writer.AddKnockoutDataBind("databind-text-editor", group);
}
protected override void OnPreRender(IDotvvmRequestContext context)
{
    context.ResourceManager.AddRequiredResource("TextEditor");
    base.OnPreRender(context);
}

and my javascript code:

ko.bindingHandlers["databind-text-editor"] = {
    init: function (element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {
        let prop = ko.unwrap(valueAccessor());

        if (!editor) {
            editor = createEditor();

            editor.on('text-change', function () {
                if (ko.isObservable(prop.html)) {
                    var contents = editor.getContents();
                    var rawContent = JSON.stringify(contents, null, 2);
                    prop.html(rawContent);
                    console.log(prop.html)
                }
            });
        }
    },
    update: function (element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {
        var prop = ko.unwrap(valueAccessor());
        console.log(prop.html);
    }
}

On text-change, the value is set to { “ops”: [ { “insert”: “a\n” } ] } but the control breaks up (quill editor disappear)

What am I missing? I tried using viewModel but it’s empty and If I set a default value for “HtmlContent” I can see it on prop.html but I am not able to update it using prop.html(newVAlue);

best regards,

I had the the control wrapped inside a

<dot:Panel DataContext={value: Html}> 
 <Control.... />
</dot:Panel>

I think it was breaking it

Hi, did you manage to get it working? Setting DataContext to null (or undefined) removes the entire subtree from DOM, so I guess you might be accidentally setting null to prop.html?

Also beware that the update function has to unwrap all knockout observable which you want to be notified about. In this case, I think you want to use console.log(ko.unwrap(prop.html))

If it’s still broken, I think I’ll need the entire source in order to replicate it easily (a .NET Core project zip or something). You can send it as a private message, here or as dotvvm-contrib PR, whichever way you prefer

Hi,

Yes it’s working now. I was calling my control like

<dot:Panel DataContext={...}>
  <my.Control Html={value: _this} />
</dot:Panel>

After removing the dot.Panel wrapper and updating the control Html value it started working

1 Like