Here is what you are seeing:
- The user types some text into the WYSIWYG editor
- The user stops typing and the timeout hits after 1 second, triggering detectFn
- detectFn grabs the new value from the WYSIWYG editor and updates your observable
- Your observable, being updated, triggers the update method on your custom binder
- The update method on the custom binder gets the value from the observable, and sets it on the WYSIWYG editor
- The WYSIWYG editor, having a new value set to it, moves the cursor to the top line
You can fix this by stopping things in the middle of step 5, and only updating the value in the WYSIWYG editor if it is different from the value in the observable - that is, if the observable was updated from somewhere outside of the WYSIWYG editor.
Change your update method to this:
update: function (element, valueAccessor) {
var newValue = ko.utils.unwrapObservable(valueAccessor());
var oldValue = $(element).wysiwyg("getContent");
if (newValue !== oldValue) {
$(element).wysiwyg("setContent", newValue);
}
// ko.bindingHandlers.value.update(element, valueAccessor);
}
I commented out the last line of that method... it seems extraneous and I'm not really sure why it's there.
Also, these lines of code don't seem to be doing anything either:
$.extend(true, {
initialContent : value
}, options);
I think what you are trying to do is add the initialContent property to the options object. That can be done in this way:
$.extend(options, {initialContent: value});
However, even that is not needed, because the update method is called after the init method, and the value from the observable is loaded into the WYSIWYG editor at that time.
Here is a fiddle with the updated code: http://jsfiddle.net/tlarson/797ZL/2/