Passing localized javascript messages from resource bundles using JSF
Asked Answered
C

3

4

I have built an application with JSF and all messages issued by the server are localized with resource bundles.

My question is: how to get messages issued in the client browser with javascipt localized with the messages stored in the resource bundles?

Do I have to generate javascript dynamically and if so how can this be done?

For example, how can I have the server localize the «alert» javascript message in the following form validation method:

function valider() {
    typeActionRadio = document.getElementById("membres_editer_creer:typeActionAdr");
    if (typeActionRadio.style.display == "block") {
        var boutonsRadio = document.forms["membres_editer_creer"]["membres_editer_creer:typeActionAdr"];
        for ( var i = 0; i < boutonsRadio.length; i++)
             if (boutonsRadio.item(i).checked) return true;
    }
     alert ("Vous devez indiquer la raison du changement d'adresse (bouton radio à sélectionner).");
    return false;
}
Centennial answered 29/1, 2013 at 3:20 Comment(0)
Y
10

Just let JSF print the desired JS code. E.g.

<script>
    var message = "#{bundle['some.key']}";
</script>

You only need to take JS special characters such as singlequotes and newlines into account. For that, you could register a custom EL function which delegates to Apache Commons Lang StringEscapeUtils, or use OmniFaces of:escapeJS() function.

Yehudit answered 29/1, 2013 at 3:25 Comment(5)
Thank you very much Balus! I have followed your suggestion and used of:escapeJS and everything is working well. For my personnal knowledge, instead of embedding the JS code in my xhtml page, would it be possible to generate a separate js file?Centennial
You're welcome. Yes, it would be possible. This is easily achieved with a simple servlet.Yehudit
There's no possibility that it could be used in resources loaded via 'h:outputScript library'?Subpoena
@Yehudit I think you forgot to put the key in quotes. It should be var message = "#{bundle['some.key']}";. At least it doesn't work in my case without the quotes.Rosenarosenbaum
Worked like charm. Thank you :)Jimmie
C
3

if you want to provide all keys use something like that in yout main-template etc.

<script type="text/javascript">
    var msg = new Object();
    <c:forEach items="#{msg.keySet()}" var="key">
        msg.#{key} = "#{msg[key]}";
    </c:forEach>
</script>
Catnap answered 22/7, 2013 at 12:39 Comment(0)
E
0

the wutzebaer answer is right but it has a problem when then the variables of a literal has any dot, like "person.name"

<script type="text/javascript">
    var msg = new Object();
    <c:forEach items="#{msg.keySet()}" var="key">
    try{ 
        //msgTempl.#{key} = "#{msg[key]}";
        msg['#{key}'] = "#{msg[key]}";  //works better than msgTempl.#{key} = "#{msg[key]}"; when the key contains dots like 'fields.name'
    }catch(e){ 
        console.log("error fullfilling the msgForms resource from bundle " +e);
    }
    </c:forEach>
</script>  

that worked for me, but the netbeans shows this error:

Error: The prefix "c" for the "c: forEach" element is not linked.

cause it had put a JSTL tag insida a script, but it works fine, however

also there is another way to do it

@ManagedBean(name = "ResouceBundle")
@ApplicationScoped
public class ResouceBundle implements Serializable {

    private static final long serialVersionUID = 1L; //needed because the bean is application|session|view and it needs to be Serializable
    public String msg;

    @PostConstruct
    public void init() {
        this.msg = createResourceBundleJSON("resourceName");
    }

    public String createResourceBundleJSON(String resourceName) {

        FacesContext context = FacesContext.getCurrentInstance();
        ResourceBundle bundle = context.getApplication().getResourceBundle(context, resourceName);
        JSONObject jsonObj = new JSONObject();
        Set<String> keys = bundle.keySet();
        for (String key : keys) {
            jsonObj.put(key, JSONObject.wrap(bundle.getString(key)));
        }
        return jsonObj.toString(); 
    }

    public String getMsg() {
        return msg;
    }

    public static long getSerialVersionUID() {
        return serialVersionUID;
    }

}

and then, in the XHTML, just write:

<script type="text/javascript">   
    var msg =  #{ResouceBundle.msg}
</script>
Ezaria answered 27/8, 2017 at 11:36 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.