Inline CKEditor integration with knockoutjs

ckeditor, jquery, knockout.js

Solution

You have to write your custom binding handler in order for your observable property to be linked with an instance of CKEditor.

First, you could start from the custom binding found here. One of the posts contains a custom binding, though I'm not sure it works. You have to check. I copied it down here, credits do not go to me of course:

ko.bindingHandlers.ckEditor = {

    init: function (element, valueAccessor, allBindingsAccessor, viewModel) {
        var txtBoxID = $(element).attr("id");
        var options = allBindingsAccessor().richTextOptions || {};
        options.toolbar_Full = [
            ['Source', '-', 'Format', 'Font', 'FontSize', 'TextColor', 'BGColor', '-', 'Bold', 'Italic', 'Underline', 'SpellChecker'],
            ['NumberedList', 'BulletedList', '-', 'Outdent', 'Indent', '-', 'Blockquote', 'CreateDiv', '-', 'JustifyLeft', 'JustifyCenter', 'JustifyRight', 'JustifyBlock', '-', 'BidiLtr', 'BidiRtl'],
            ['Link', 'Unlink', 'Image', 'Table']
        ];

        // handle disposal (if KO removes by the template binding)
        ko.utils.domNodeDisposal.addDisposeCallback(element, function () {
            if (CKEDITOR.instances[txtBoxID]){ 
                CKEDITOR.remove(CKEDITOR.instances[txtBoxID]); 
            }
        });

        $(element).ckeditor(options);

        // wire up the blur event to ensure our observable is properly updated
        CKEDITOR.instances[txtBoxID].focusManager.blur = function () {
            var observable = valueAccessor();
            observable($(element).val());
        };
    },
    update: function (element, valueAccessor, allBindingsAccessor, viewModel) {
        var val = ko.utils.unwrapObservable(valueAccessor());
        $(element).val(val);
    }
} 

A typical use then would be in the HTML:

<textarea id="txt_viewModelVariableName" 
          data-bind="ckEditor: viewModelVariableName"></textarea>

Secondly, you could check out the custom binding handler for TinyMCE initially written by Ryan Niemeyer and updated by other talented people. Maybe TinyMCE could work out for you instead of CKEditor ?

Problem

So I am trying to integrate Inline Editing from CKEditor with Knockout.js. I am able to successfully load the CKEditor and knockout.js. I just can't seem to get the ko.observable update the property: ``` <script type="text/javascript"> var viewModel = function () { var self = this; self.editorText = ko.observable('ABC'); self.testNewValue = function () { console.log(this.editorText()); }; } ko.applyBindings(new viewModel()); </script> ``` Here is the html: ``` <div id="editable" contenteditable="true" data-bind="html: editorText"> </div> <div> <input type="button" data-bind="click: testNewValue" value="test" /> </div> ``` The console.log result always shows "ABC" regardless if you updated it or not. Note: I also tried `data-bind="text: editorText"`

Original source

Related problems