Himanshu Yadav
Himanshu Yadav

Reputation: 13585

Freemarker: Calling macro from JavaScript function

I have a freemarker macro like this.

<#assign xmlNode = parseXML("<field name='dropDown' type='select' valueName='COUNTRY'/>")>;
    <#import "utilFields.ftl" as util />
     <div>
      <@util.createDropdown field=xmlNode/>
     </div>

How would I call the same macro from Javascript?
Tried:

<#assign xmlNode = parseXML("<field name='dropDown' type='select' valueName='COUNTRY'/>")>;
<script type="text/javascript">
        var dropdown = "${util.createDropdown(xmlNode)}";
        alert(dropdown);
</script>

Error

FreeMarker template error:
A macro cannot be called in an expression.

Upvotes: 0

Views: 3868

Answers (1)

ddekany
ddekany

Reputation: 31152

I assume you want to insert the HTML generated by @util.createDropdown into the JavaScript string literal. (You can't literally call FreeMarker form JavaScript, since the two run at different times.) The naive approach is just:

<#-- Not safe! -->
var dropdown = "<@util.createDropdown field=xmlNode/>";

The problem is that util.createDropdown writes HTML to the output, and HTML not in general valid as is inside a JavaScript string literal, because you can have " in it and so on. You can do a trick like this though:

<#macro jsStr>
  <#local captured><#nested></#local>
  "${captured?js_string}"<#t>
</#macro>

...

var dropdown = <@jsStr><@util.createDropdown field=xmlNode/></@>;

The jsStr macro converts the content printed inside it (and it need not be a single macro call inside it, it can be anything) to a valid JavaScript string literal.

Upvotes: 2

Related Questions