Reputation:

Using JSP code in JavaScript

I want to use JSTL's fmt tag in JavaScript to localize my alert messages. My JavaScript file is a standalone file and when I include fmt tag in js, the file browser gives JavaScript errors. Is it possible to treat .js file as .jsp files using web.xml configuration? Can anyone please suggest how can I do that?

Upvotes: 12

Views: 59372

Answers (7)

user3400486
user3400486

Reputation: 1

If you are going for only alert messages just use this tag in your javascript

Suppose you have following in your Javascript:

alert("Confirm Deletion"); 

This can be internationalized by adding bean:message tag in your javascript

alert('<bean:message key="msg.confirm"/>');

and add key value in property file

msg.delete=Confirm Deletion

Upvotes: 0

BeWarned
BeWarned

Reputation: 2338

I would suggest you write a servlet that generates an array or javascript object that contains all the localized information you desire. You can use Java resource bundles which can be shared by both the client and server sides, then you don't have to intermix JSP code and Javascript code, and the servlet response will be cached by the browser.

Create a servlet, map it to a path, have it read the locale from a request parameter then generate the Javascript code.

Use a line like <script src="/mydict?lang=en"></script> then load you script afterwards <script src="/myscript.js"></script>

Upvotes: 5

belugabob
belugabob

Reputation: 4460

If your javascript is 'inline' with the rest of your JSP page, then simply use the technique suggested by Kees de Kooter.

If your javascript needs to be in an external file (For sharing across pages, for example) then simply put it in its own JSP file.

<%@page contentType="text/javascript" %>
<fmt:message key="some.message" var="someMessage"/>"
<fmt:message key="another.message" var="anotherMessage"/>"
var someMessage = "${someMessage}"
var anotherMessage = "${anotherMessage}"/>"

And include it like this...

        <script src="yourScript.jsp" language="JavaScript" type="text/javascript"></script>

You can then refer to 'someMessage' and 'anotherMessage' from within the file that includes the JSP, or from any javascript file that is included after 'yourScript.jsp.

Note the use of the contentType attribute - 'text/javascript' prevents the JSP parser from complaining that the output isn't well formed XML - and that the tage refers to a JSP file.

A combination of this technique and that suggested by @Magner should bring you to a sensible solution.

EDIT: Changed the example to use 'text/javascript' insetad of 'text/plain' - thanks to @bobince for making me realise this error (Even though 'text/plain' works, it's more correct to use 'text/javascript'). Also, if the number of strings that need to be internationalised is small, and/or you can justify having your 'resources' in more than one place - one for the server side stuff and another for the client side stuff - @bobince's technique of using dynamic includes is a good one.

Upvotes: 6

bobince
bobince

Reputation: 536715

is it possible to treat .js file as .jsp file using web.xml configuration?

Yes:

<servlet>
    <servlet-name>scriptjsp</servlet-name>
    <jsp-file>/script.jsp</jsp-file> 
</servlet>
<servlet-mapping>
    <servlet-name>scriptjsp</servlet-name>
    <url-pattern>/script.js</url-pattern>
</servlet-mapping>

But, there is no actual advantage in doing this, because JavaScript files do not have to have URLs ending in ‘.js’. What determines whether a file is a JavaScript file is what MIME media type it is served as. You can set this from JSP using:

<%@ page contentType="text/javascript" %>

at the top. Then you can link directly to:

<script type="text/javascript" src="/script.jsp"></script>

(Aside: in current browsers, scripts linked to with the <script> tag will work even without having the Content-Type properly set, but that's probably not something to rely on.)

I want to use JSTL's fmt tag in javascript

This is probably not a good idea. The fmt tag deals with HTML-escaping for characters, but what you want is JavaScript string literal escaping, for example to backslash-escape quote characters. JSTL doesn't provide this capability. You'll get unexpectedly-escaped ‘&amp;’ characters showing up in your JavaScript strings, and use of apostrophe or double quote in messages will break the whole script.

Also, serving commonly-included scripts from JSP risks poor performance and cacheing.

I'd suggest an independent language lookup system in JavaScript. For example, include a per-language external script:

<script type="text/javascript" src="/script/lang/en.js"></script>

(changing 'en' to match whichever language you want), and in that file define a lookup like:

var msg= {
    messageName: 'Message in English',
    ...
};

Then look up msg.messageName for each localisable string in the script.

Upvotes: 20

Magnar
Magnar

Reputation: 28830

You should strive to keep your javascript code in a separate file from the jsp-code. This is to get browser caching, easier maintenance, reuse across pages, and to allow compression.

I suggest that you create a global object for text in the jsp, to be used by your javascript files. Like this:

<script>
    var text = text || {}; // play well with other jsps on the page
    text.this_page_name = {
        required_field_error: "<fmt:message key="required.field.error"/>",
        system_error: "<fmt:message key="system.error"/>"
    };
</script>

Later you use it in your javascript:

alert(text.this_page_name.required_field_error);

Upvotes: 4

Aaron Digulla
Aaron Digulla

Reputation: 328810

You can't use tags in JavaScript but there is a workaround: Put the tag into an hidden DIV (<div style="display: none;" id="msg"><fmt:...>

Now you can use JS to look up the DIV by its ID and get the innerHTML.

That said, fmt is just a wrapper for Java's i18n functions which you can use directly between <% %>.

Upvotes: 1

Kees de Kooter
Kees de Kooter

Reputation: 7195

You could do the following. You store the translated message in a variable that can be resolved later on in the JSP.

<fmt:message key="your.alert" var="theAlert"/>

<script type="text/javascript">
alert("${theAlert}");
</script>

Upvotes: 3

Related Questions