5

Sometimes, I need to render a JavaScript variable using EL in a JSF page.

E.g.

<script>var foo = '#{bean.foo}';</script>

or

<h:xxx ... onclick="foo('#{bean.foo}')" />

This fails with a JS syntax error when the EL expression evaluates to a string containing JS special characters such as apostrophe and newline. How do I escape it?

BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
Ontonomo
  • 527
  • 1
  • 8
  • 12

2 Answers2

14

You can use Apache Commons Lang 3.x StringEscapeUtils#escapeEcmaScript() method for this in EL.

First create a /WEB-INF/functions.taglib.xml which look like this:

<?xml version="1.0" encoding="UTF-8"?>
<facelet-taglib 
    xmlns="http://java.sun.com/xml/ns/javaee"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-facelettaglibrary_2_0.xsd"
    version="2.0">
    <namespace>http://example.com/functions</namespace>

    <function>
        <name>escapeJS</name>
        <function-class>org.apache.commons.lang3.StringEscapeUtils</function-class>
        <function-signature>java.lang.String escapeEcmaScript(java.lang.String)</function-signature>
    </function>
</taglib>

Then register it in /WEB-INF/web.xml as follows:

<context-param>
    <param-name>javax.faces.FACELETS_LIBRARIES</param-name>
    <param-value>/WEB-INF/functions.taglib.xml</param-value>
</context-param>

Then you can use it as follows:

<html ... xmlns:func="http://example.com/functions">
...
<script>var foo = '#{func:escapeJS(bean.foo)}';</script>
...
<h:xxx ... onclick="foo('#{func:escapeJS(bean.foo)}')" />

Alternatively, if you happen to already use the JSF utility library OmniFaces, then you can also just use its builtin of:escapeJS() function:

<html ... xmlns:of="http://omnifaces.org/functions">
...
<script>var foo = '#{of:escapeJS(bean.foo)}';</script>
...
<h:xxx ... onclick="foo('#{of:escapeJS(bean.foo)}')" />
BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
  • I've followed the above, but I'm getting the following exception : javax.servlet.ServletException: com.sun.faces.el.impl.ElException: No function is mapped to the name "util:escapeJS" I'm on JSF 1.1, JSP 2.1... any idea what I should look at? – bendicott Jan 31 '14 at 00:08
  • @bendicott: Above answer uses a Facelet taglib. You're using JSP, not Facelets. You need to create a JSP taglib instead. – BalusC Jun 08 '15 at 15:18
  • Had to correct the taglib-definition but your solution is great... simple and effective! – cljk Aug 19 '16 at 08:00
  • We're using JSF 1 with Facelets (legacy), so we needed to use the version 1 taglib DTD rather than the version 2 schema, and the `web.xml` property is facelets.LIBRARIES rather than javax.faces.FACELETS_LIBRARIES, but the basic idea of this answer was applicable. – ThrawnCA Jan 10 '19 at 01:07
-1

Have you tried \'#{_selectedItem.item.webName}\',?

seasonedgeek
  • 160
  • 6