Search code examples
javascripthtmltemplatesjsrenderjsviews

Is it syntactically wrong to use the html converter in jsView like so: data-link="html{:property}" instead of data-link="{html:property}"?


We are using the html converter on a lot of our templates that render in jsViews/jsRender. We came across an issue, where jsViews was fumbling on a "Mismatch" error when a
tag was in the text it was rendering. We did not notice this, until recently updating to the latest versions. Her is the snippet we were originally using, that is now causing an error:

    <div id="Resizable" data-link="html{:Text}"></div>

Now, I noticed on the jsRender APi, it says to handle the tag like the following, and when doing so, it renders the data correctly, encoding the html content as wanted.

        <div id="Resizable" data-link="{html:Text}"></div>

My question is this: Was it not setup properly before, and we just never noticed the error, did this change on the latest version, and is the latter way the only correct way to use the html encoder? Any help is greatly appreciated. Thanks!


Solution

  • Here is the documentation topic which explains the syntax for data-linked elements: http://www.jsviews.com/#linked-elem-syntax

    See especially the section on Full syntax - multiple targets, multiple tags, multiple bindings... where it says:

    The full syntax allows you to bind multiple expressions each to a different target 'attrib', and is written like this: data-link="attrib1{linkExpression1} attrib2{linkExpression2} ..."

    And note what it says lower down:

    The default target for most elements is innerText, but for inputs and select it is value.

    And it gives some examples:

    • <div data-link="{:name}"></div> (one-way binding to innerText - default target attrib - so automatically HTML encodes).
    • <div data-link="html{:name}"></div> (one-way binding to innerHTML)

    So what this is saying is that the default target for a data-linked div is innerText - which means that if you inject HTML markup it will in effect HTML encode that markup 'for free'. It won't insert HTML tags as inner HTML.

    If you did add the HTML converter, you would write it like this <div data-link="{>name}"></div> - but adding HTML encoding when you are inserting as innerText won't change what the user sees. (An alternative syntax for the same thing would be what you wrote above <div data-link="{html:name}"></div>). See the documentation here on the HTML converter: http://www.jsviews.com/#html.

    If you WANT to insert as inner HTML, then you use the HTML target, which the second example above: <div data-link="html{:name}"></div>.

    And you could then add encoding as in <div data-link="html{>name}"></div>.

    But more likely using the default innerText target and no explicit converter is what you need.

    See also this SO response to a similar question How to keep helper function generated HTML tags for JsViews

    BTW - no, this should not have changed behavior in the latest version. If you saw a change in behavior, can you add an issue on JsViews GitHub project, ideally with a jsfiddle showing something which rendered differently between the two versions?