- 

Available since OmniFaces 3.6

The <o:scriptParam> is a component that extends the standard <f:viewParam> with support for setting results of client-side evaluated JavaScript code in bean.

Usage

It's similar to the <f:viewParam>.

<f:metadata>
    <o:scriptParam script="new Date().getTimezoneOffset()" value="#{bean.clientTimeZoneOffset}" />
    <o:scriptParam script="window.screen.width" value="#{bean.clientScreenWidth}" />
    <o:scriptParam script="someFunctionName()" value="#{bean.resultOfSomeFunctionName}" />
</f:metadata>

You can use the render attribute to declare which components should be updated when a script parameter has been set.

<f:metadata>
    <o:scriptParam script="foo()" value="#{bean.resultOfFoo}" render="fooResult" />
</f:metadata>
...
<h:body>
    ...
    <h:panelGroup id="fooResult">
        <ui:fragment rendered="#{not empty bean.resultOfFoo}">
            The result of foo() script is: #{bean.resultOfFoo}
        </ui:fragment>
    </h:panelGroup>
    ...
</h:body>

Note that as it extends from the standard <f:viewParam>, its built-in conversion and validation functionality is also supported on this component. So, the following is also possible:

<f:metadata>
    <o:scriptParam script="window.navigator" value="#{bean.clientNavigator}" />
</f:metadata>
With a clientNavigator being an instance of jakarta.json.JsonObject:
private JsonObject clientNavigator;
And this converter:
package com.example;

import java.io.StringReader;
import jakarta.faces.component.UIComponent;
import jakarta.faces.context.FacesContext;
import jakarta.faces.convert.Converter;
import jakarta.faces.convert.ConverterException;
import jakarta.faces.convert.FacesConverter;
import jakarta.json.Json;
import jakarta.json.JsonObject;

@FacesConverter(forClass = JsonObject.class)
public class JsobObjectConverter implements Converter<JsonObject> {

    @Override
    public String getAsString(FacesContext context, UIComponent component, JsonObject modelValue) {
        if (modelValue == null) {
            return "";
        }

        return modelValue.toString();
    }

    @Override
    public JsonObject getAsObject(FacesContext context, UIComponent component, String submittedValue) {
        if (submittedValue == null || submittedValue.isEmpty()) {
            return null;
        }

        try {
            return Json.createReader(new StringReader(submittedValue)).readObject();
        }
        catch (Exception e) {
            throw new ConverterException("Not a valid JSON object", e);
        }
    }
}

Events

When the script params have been set, then any method with the PostScriptParam annotation will be fired:

@PostScriptParam
public void initScriptParams() {
    // ...
}

This is useful in case you want to preload the model for whatever is rendered by <o:scriptParam render>.

Demo

The below information from JavaScript context is obtained in managed bean via <o:scriptParam>.

    Demo source code
    <f:metadata>
        <o:scriptParam script="new Date().getTimezoneOffset()" value="#{scriptParamBean.clientTimeZoneOffset}" />
        <o:scriptParam script="window.navigator" value="#{scriptParamBean.navigator}" render="scriptParams" />
    </f:metadata>
    
    <p>
        The below information from JavaScript context is obtained in managed bean via <code>&lt;o:scriptParam&gt;</code>.
    </p>
    <ul faces:id="scriptParams">
        <ui:fragment rendered="#{scriptParamBean.postScriptParamInvoked}">
            <li><code>new Date().getTimeZoneOffset()</code> = #{scriptParamBean.clientTimeZoneOffset}</li>
            <li><code>window.navigator</code> = #{scriptParamBean.navigator}</li>
        </ui:fragment>
    </ul>