4

I'm trying to write a custom binding to bind knockout to a froala-editor.

My binding works in the following way:

ko.bindingHandlers.froala = {
    init: function(element, valueAccessor){
        var options = {
            inlineMode: false,
            alwaysBlank: true,
            buttons : ["bold", "italic", "createLink"],
            autosaveInterval: 10,
            contentChangedCallback: function () {
                var html = $(element).editable("getHTML"),
                    observable  = valueAccessor();
                observable( html );
            }
        };
        $(element).editable(options);

        // handle disposal (if KO removed by the template binding)
        ko.utils.domNodeDisposal.addDisposeCallback(element, function () {
            $(element).editable("destroy");
        });
    },
    update: function(element, valueAccessor){
        var value = ko.utils.unwrapObservable(valueAccessor());
        $(element).editable("setHTML", value);
    }
}

Here I am using autosaveInterval, because I was not able to find any more suitable method.

My HTML is really simple:

<div data-bind="froala: txt"></div>

The corresponding JS:

function test() {
    this.txt = ko.observable('Hello');
}

var a = new test();
ko.applyBindings(a);

Everything works, but the only problem is that after each autosaveInterval time, the focus from my editor is lost. After investigating I found that observable( html ); is the culprit. If I comment it out, focus is not lost, but it is understandable that my model is not synchronized.

Can anyone try to help me?

Thanks to @nemesv, I was able to make a jsfiddle with a repro.

Jeroen
  • 60,696
  • 40
  • 206
  • 339
Salvador Dali
  • 214,103
  • 147
  • 703
  • 753
  • 1
    When it try to create a fiddle from your code I always get "Cannot read property 'getHTML' of undefined " from the `contentChangedCallback`... http://jsfiddle.net/3kDbV/ however adding a setTimeout fixes in the fiddle http://jsfiddle.net/3kDbV/1/ and it seems one additional if in the update fixes your problem http://jsfiddle.net/3kDbV/2/. There is also something else which is strage: `editable("getHTML")` is returning an array containing one string instead of a string as described in the documentation, that is why I've added the `[0]` in the last fiddle. – nemesv Apr 27 '14 at 07:47
  • @nemesv thank you very much. The error `getHTML` is due to the fact, that the last commit on their git is not actually the stable version. So I modified your first fiddle to use their latest stable version (I added it to my question). – Salvador Dali Apr 27 '14 at 08:18
  • 1
    @SalvadorDali editable('getHTML') returns Array because there may be multiple instances of the editor for the same selector. String is the element from these arrays. For instance you may have a class ".editor" and 2 divs with this class. When you instantiate the editor with $('.editor') there will be 2 instances. That's why $('.editor').editable('getHTML') will return an Array. – st3fan Apr 27 '14 at 17:39
  • @nemesv can you please post your answer, so that I will be able to acknowledge it? – Salvador Dali Apr 27 '14 at 20:40
  • @SalvadorDali st3fan answers your question: "Testing if the value you get in update is different than the previous one would not loose selection anymore. " and he also explains why you get an array in getHtml so I think creating a new answer won't add anything new so you should accept his answer. I have never seeen froala before that's is why I've only commented and not answered your question in the first place. – nemesv Apr 28 '14 at 04:46

2 Answers2

2

You are loosing focus because of the line $(element).editable("setHTML", value);. When you use var html = $(element).editable("getHTML")[0]; you'll get the HTML but it won't give you the selection from the editor. Testing if the value you get in update is different than the previous one would not loose selection anymore. http://jsfiddle.net/DVHzZ/16/

st3fan
  • 1,630
  • 14
  • 32
1

contentChanged is an event instead of a callback, and the [0] is no longer required on getHTML in more recent versions of froala.

Here is an updated fiddle.

Cendenta
  • 170
  • 2
  • 10