Question

I have a web page that uses highlight.js in this way:

<link rel="stylesheet" href="http://yandex.st/highlightjs/8.0/styles/vs.min.css">
<script src="http://yandex.st/highlightjs/8.0/highlight.min.js"></script>
<script>hljs.initHighlightingOnLoad();</script>

Using Knockoutjs I need to bind some scripts template like this:

<section>
   <div data-bind="with: selectedTable">
       <div data-bind="template: { name: 'plugin-template' }"></div>
   </div>
</section>

<script type="text/html" id="plugin-template">
   <div id="plugin-view-content" data-bind="with: selectedPlugin, visible: selectedPlugin">
      <pre><code><p data-bind="text: code"></p></code></pre>
   </div>
</script>

My problem is that when the template is rendered, the text is not highlighted. What's wrong?

Was it helpful?

Solution

The documentation on highlight.js states pretty clearly how you need to do if you want to highlight text which is dynamically added. It is stated under the heading Custom Initialization on http://highlightjs.org/usage/.

It states that you should call the hljs.highlightBlock function, passing in the element which contains the code you want highlighted.

In a KnockoutJS world, you should probably create a bindingHandler which changes the text of your field and then calls the highlight.js method which highlights the text properly. A simple version of such a bindingHandler could be something like the following:

ko.bindingHandlers.highlightedCode = {
    update: function(element, valueAccessor){
        var code = ko.unwrap(valueAccessor());
        element.innerText = code;
        hljs.highlightBlock(element);
    }
};

Given the following view model setup:

function ViewModel(code){
    var self = this;

    self.code = ko.observable(code);
}

var viewModel = new ViewModel('public static void Main()\n{\n    var name = Console.ReadLine();\n    Console.WriteLine("Hello " + name + "!");\n}');
ko.applyBindings(viewModel);

You could use the bindingHandler with the following HTML:

<pre>
    <code data-bind="highlightedCode: code"></code>
</pre>
<textarea data-bind="value:code" rows="20" cols="100"></textarea>

I have created a jsfiddle containing this code, in case you want to try it out live. You can find the JSFiddle at http://jsfiddle.net/zY52s/

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top