719-286-0751 [email protected]

How to disable CKEditor with Knockoutjs

How to disable CKEditor with Knockoutjs

Here at Cadence Labs, we love Knockoutjs.

One of the applications we use it on has a robust admin panel where some of the input fields become WYSIWYG editors. We use CKEditor for this.

In the process of building this application, we discovered the amazing CKEditor binding by Leaping Gorilla. However, it has one drawback, being that the CKEditor doesn’t attach to Knockout’s disable binding.

The problem

Let’s say you’re developing a form where the user input fields are disabled based on certain criteria (a fairly common scenario). You can easily accomplish this for text inputs, select drop-downs, and radio buttons using the native disable binding provided by knockout:


<input type="text" data-bind="disable: status() !== 'enable'" />

Works great! However, let’s say you have this binding on a text area that’s attached to a CKEditor. Here’s what will happen:

  1. CKEditor will bind to the textarea on the page load.
  2. If the textarea is disabled at the initial page load the CKEditor will remain permanently disabled.
  3. IF the textarea is enabled at the initial page load the CKEditor will remain permanently enabled.

This defeats the whole point of Knockout JS – your elements are bound to a view model that can easily update them to make the page easy to interact with.

The Solution: Override the disable binding

We can make a binding override to disable CKEditor with Knockoutjs: Note this example requires jQuery be installed

(function(){
    var oldDisabled = ko.bindingHandlers.disable.update;
    ko.bindingHandlers.disable.update = function (element, valueAccessor) {

        oldDisabled(element, valueAccessor);
        var el = jQuery(element);
        if (el.data("bind").search(/richText/) !== -1) {
            var existingEditor = CKEDITOR.instances && CKEDITOR.instances[element.id];
            try {
                if (existingEditor && typeof(existingEditor) !== "undefined" && typeof(existingEditor.setReadOnly) !== "undefined") {
                    if (el.prop("disabled")) {
                        existingEditor.setReadOnly(true);
                    } else {
                        existingEditor.setReadOnly(false);
                    }
                }
            } catch (ex) {
                //do nothing
            }
        }
    };
})();

Note that you should replace richText with whatever binding you are using to tie the CKEditor with the TextArea element (Leaping Gorilla used richText so we’ve used it here in this demo).

You can see that we’re making a new function to handle disable: bindings that checks for the existence of a CKEditor tied to the bound element. If it binds a CKEditor, it uses the setReadOnly method to either enable or disable the CKEditor.

 

Alan Barber is the Lead Web Developer at Cadence Labs and a Magento Certified developer.

Submit a Comment

Your email address will not be published. Required fields are marked *

Install our webapp on your iPhone! Tap and then Add to homescreen.
Share This