Search code examples
jquerytwitter-bootstrapknockout.jswysihtml5

wysihtml5 and knockout give empty iframe


When implementing wysihtml5 and knockout using Nicholas Jackson's bindingHandler. This sort of works, the css is still a bit messy but nothing I can't fix.

Html of the textarea:

    <!-- ko 'if': choice()=='0' -->
<p>Please define your alternative benchmark:</p>
<textarea id="test" data-bind="wysihtml5: alternative" placeholder="Enter text ..."></textarea>
    <!-- /ko -->

The problem I have is that the iframe is rendered but I can't type in the field anymore, there's no textarea, nothing in there:

disabled area

The HTML of this iframe being rendered by the plugin (using chrome developer tools):

<ul id="test-wysihtml5-toolbar" class="wysihtml5-toolbar" style="">
<li class="dropdown"><a class="btn dropdown-toggle" data-toggle="dropdown" href="#"><i class="icon-font"></i>&nbsp;

<span class="current-font">Normal text
</span>&nbsp;<b class="caret"></b></a>
<ul class="dropdown-menu">
<li><a data-wysihtml5-command="formatBlock" data-wysihtml5-command-value="div" href="javascript:;" unselectable="on">Normal text</a></li>
<li><a data-wysihtml5-command="formatBlock" data-wysihtml5-command-value="h1" href="javascript:;" unselectable="on">Heading 1</a></li>
<li><a data-wysihtml5-command="formatBlock" data-wysihtml5-command-value="h2" href="javascript:;" unselectable="on">Heading 2</a></li>
</ul></li>
<li>

<div class="btn-group"><a class="btn" data-wysihtml5-command="bold" title="CTRL+B" href="javascript:;" unselectable="on">Bold</a><a class="btn" data-wysihtml5-command="italic" title="CTRL+I" href="javascript:;" unselectable="on">Italic</a>
</div></li>
<li>

<div class="btn-group"><a class="btn" data-wysihtml5-command="insertUnorderedList" title="Unordered List" href="javascript:;" unselectable="on"><i class="icon-list"></i></a><a class="btn" data-wysihtml5-command="insertOrderedList" title="Ordered List" href="javascript:;" unselectable="on"><i class="icon-th-list"></i></a><a class="btn" data-wysihtml5-command="Outdent" title="Outdent" href="javascript:;" unselectable="on"><i class="icon-indent-right"></i></a><a class="btn" data-wysihtml5-command="Indent" title="Indent" href="javascript:;" unselectable="on"><i class="icon-indent-left"></i></a>
</div></li>
<li>

<div class="bootstrap-wysihtml5-insert-link-modal modal hide fade">

<div class="modal-header"><a class="close" data-dismiss="modal">×</a><h3>Insert Link</h3>
</div>

<div class="modal-body">
<input value="http://" class="bootstrap-wysihtml5-insert-link-url input-xlarge">
</div>

<div class="modal-footer"><a href="#" class="btn" data-dismiss="modal">Cancel</a><a href="#" class="btn btn-primary" data-dismiss="modal">Insert link</a>
</div>
</div><a class="btn" data-wysihtml5-command="createLink" title="Link" href="javascript:;" unselectable="on"><i class="icon-share"></i></a></li>
<li>

<div class="bootstrap-wysihtml5-insert-image-modal modal hide fade">

<div class="modal-header"><a class="close" data-dismiss="modal">×</a><h3>Insert Image</h3>
</div>

<div class="modal-body">
<input value="http://" class="bootstrap-wysihtml5-insert-image-url input-xlarge">
</div>

<div class="modal-footer"><a href="#" class="btn" data-dismiss="modal">Cancel</a><a href="#" class="btn btn-primary" data-dismiss="modal">Insert image</a>
</div>
</div><a class="btn" data-wysihtml5-command="insertImage" title="Insert image" href="javascript:;" unselectable="on"><i class="icon-picture"></i></a></li>
</ul>
<textarea id="test" data-bind="wysihtml5: alternative" style="display: none;" placeholder="Enter text ...">sdf
</textarea>
<input type="hidden" name="_wysihtml5_mode" value="1"><iframe class="wysihtml5-sandbox" security="restricted" allowtransparency="true" frameborder="0" width="0" height="0" marginwidth="0" marginheight="0" style="background-color: rgb(255, 255, 255); border-collapse: separate; border: 1px solid rgb(226, 226, 226); /* clear: none; */ /* display: inline-block; */ /* float: none; */ margin: 16px; outline: rgb(51, 51, 51) none 0px; outline-offset: 0px; padding: 5px; position: static; top: auto; left: auto; right: auto; bottom: auto; z-index: 99999; vertical-align: top; text-align: justify; box-sizing: border-box; -webkit-box-shadow: none; box-shadow: none; border-top-right-radius: 0px; border-bottom-right-radius: 0px; border-bottom-left-radius: 0px; border-top-left-radius: 0px; width: 80%; height: auto;"></iframe>

The scripts that are being rendered are: enter image description here


Solution

  • If you're looking for an easy integration of a wysiwyg editor with knockout, I can advise you the following libraries:

    ckeditor: When you install this beast, make sure you add everything in the same folder and reference the ckeditor.js (it has its own scriptloader)

    Custom knockout bindingHandler:

    /*
    Usage:  <textarea data-bind="inlineCkeditor: observable"></textarea>
    */
    
    (function (ko, CKEDITOR) {
        ko.bindingHandlers.inlineCkeditor = {
            init: function (element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {
                element.editor = CKEDITOR.inline(element);
    
                element.editor.on('blur', function () {
                    valueAccessor()(element.editor.getData());
                });
    
                //handle destroying
                ko.utils.domNodeDisposal.addDisposeCallback(element, function () {
                    if (element.editor)
                        element.editor.destroy(true);
                });
            },
            update: function (element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {
                //handle programmatic updates to the observable
                var value = ko.utils.unwrapObservable(valueAccessor()),
                    existingEditor = element.editor;
    
                if (existingEditor) {
                    if (value !== existingEditor.getData()) {
                        existingEditor.setData(value);
                    }
                }
    
            }
        };
    
    })(ko, CKEDITOR);
    

    And all that should give you this: enter image description here