Why doesn't PageDown Editor trigger updating the Knockout value when using the Button Bar?

I have a problem updating the knockout model when the user uses the PageDown button bar to make changes to the editor text. Any type of input, paste or cut operation works fine, but the button bar actions are not performed.

I tried adding to the editor hook

for onPreviewRefresh

, but it never works.

Below is the Fiddle . If you type test

in the editor, it test

will appear in the preview section. However, if you type test

into the editor and then use the menu bar to make it test

bold, then the preview section will not see this update until you type another character.

This is the custom binding I use to initialize the PageDown editor:

var ME = {};
ME.MarkdownConverter = Markdown.getSanitizingConverter();
ME.MarkdownCounter = 0;

ko.bindingHandlers.markdownEditor = {
    init: function(element, valueAccessor, allBindings, viewModel, bindingContext) {
        ++ME.MarkdownCounter;
        // Create the elements needed for a new PageDown editor.
        $(element).append($('<div id="wmd-button-bar-' + ME.MarkdownCounter + '" class="wmd-button-bar"></div>'));
        $(element).append($('<textarea id="wmd-input-' + ME.MarkdownCounter + '" class="wmd-input"></textarea>'));

        // Make sure the textarea is properly binded up so that the view model is updated.
        var newBindings = { textInput: valueAccessor };
        ko.applyBindingAccessorsToNode($('#wmd-input-' + ME.MarkdownCounter)[0], newBindings, viewModel);

        // Create the editor and apply to the new elements ensuring that we detect all
        // changes from the wmd-button-bar.
        var editor = new Markdown.Editor(ME.MarkdownConverter, "-" + ME.MarkdownCounter);
        editor.hooks.chain("onPreviewRefresh", function () {
            var value = valueAccessor();
            debugger;
            value($('#wmd-input-' + ME.MarkdownCounter).val());
        });
        editor.run();

        return { controlsDescendantBindings: true }; 
    }
};

      

+3


source to share


1 answer


The value update is not triggered because the value is set programmatically, which does not trigger the textarea change event.

The event onPreviewRefresh

does not fire because there is no preview element. As a workaround, you can add an element and hide it:



var ME = {};
ME.MarkdownConverter = Markdown.getSanitizingConverter();
ME.MarkdownCounter = 0;

ko.bindingHandlers.markdownText = {
    init: function(element, valueAccessor, allBindings, viewModel, bindingContext) {
        $(element).addClass('markdown-text');
    },
    update: function(element, valueAccessor, allBindings) {
        var value = valueAccessor();
        var valueUnwrapped = ko.unwrap(value);
        $(element).html(ME.MarkdownConverter.makeHtml(valueUnwrapped));
    }
};

ko.bindingHandlers.markdownEditor = {
    init: function(element, valueAccessor, allBindings, viewModel, bindingContext) {
        ++ME.MarkdownCounter;
        // Create the elements needed for a new PageDown editor.
        $(element).append($('<div id="wmd-button-bar-' + ME.MarkdownCounter + '" class="wmd-button-bar"></div>'));
        $(element).append($('<textarea id="wmd-input-' + ME.MarkdownCounter + '" class="wmd-input"></textarea>'));        
        // if no preview element is found, onPreviewRefresh is not triggered
        $(element).append('<div style="display: none" class="wmd-panel wmd-preview" id="wmd-preview-' + ME.MarkdownCounter + '"></div>');

        var $input = $('#wmd-input-' + ME.MarkdownCounter);

        // Make sure the textarea is properly binded up so that the view model is updated.
        var newBindings = { textInput: valueAccessor };
        ko.applyBindingAccessorsToNode($input[0], newBindings, viewModel);

        // Create the editor and apply to the new elements ensuring that we detect all
        // changes from the wmd-button-bar.
        var editor = new Markdown.Editor(ME.MarkdownConverter, "-" + ME.MarkdownCounter);
        editor.hooks.chain("onPreviewRefresh", function () {
            $input.change();
        });
        editor.run();

        return { controlsDescendantBindings: true }; 
    }
};

var vm = { noteText: ko.observable('') };
ko.applyBindings(vm);

      

See http://jsfiddle.net/vaako62z/3/

+1


source







All Articles