Pass parameter to p:remoteCommand from JavaScript


I want to pass value to remoteCommand from javascript. If this is possible, how can I do that and how can I receive them in the backing bean?

remoteCommandFunctionName({name1:'value1', name2:'value2'});

Yes, it is possible. How to do that depends on the PrimeFaces version. You can see it in PrimeFaces users guide. Before PrimeFaces version 3.3 the syntax is as follows (copypasted from 3.2 users guide):

3.80 RemoteCommand

...

Passing Parameters

Remote command can send dynamic parameters in the following way;

increment({param1:'val1', param2:'val2'});

It's available in the backing bean by usual means. E.g. in a request scoped bean:

@ManagedProperty("#{param.param1}")
private String param1;

@ManagedProperty("#{param.param2}")
private String param2;

or in method of a broader scoped bean:

Map<String, String> params = FacesContext.getCurrentInstance().getExternalContext().getRequestParameterMap();
String param1 = params.get("param1");
String param2 = params.get("param2");

This approach had however the disadvantage that you can't specify a single parameter with multiple values like as possible with normal HTML forms and HTTP request parameters (which is in real world used on e.g. multiple select dropdownlist and multiple select checkboxgroup).


Since PrimeFaces version 3.3 the syntax is as follows (copypasted from 3.3 users guide):

3.81 RemoteCommand

...

Passing Parameters

Remote command can send dynamic parameters in the following way;

increment([{name:'x', value:10}, {name:'y', value:20}]);

This way offers the possibility to specify multiple values on a single parameter name. Parameters with single values like above are available the same way as the old way:

@ManagedProperty("#{param.x}")
private int x;

@ManagedProperty("#{param.y}")
private int y;

(note: you can use Integer in Mojarra, but not in MyFaces, this is further completely unrelated to <p:remoteCommand>)

or in method of a broader scoped bean:

Map<String, String> params = FacesContext.getCurrentInstance().getExternalContext().getRequestParameterMap();
int x = Integer.valueOf(params.get("x"));
int y = Integer.valueOf(params.get("y"));

If you need to specify a parameter with multiple values, then you could do it as follows:

functionName([{name:'foo', value:'one'}, {name:'foo', value:'two'}, {name:'foo', value:'three'}]);`

with in a request scoped bean:

@ManagedProperty("#{paramValues.foo}")
private String[] foos;

or in method of a broader scoped bean:

Map<String, String[]> paramValues = FacesContext.getCurrentInstance().getExternalContext().getRequestParameterValuesMap();
String[] foos = paramValues.get("foo");

Update

Accessing the parameters in modern CDI JSF, can be done in a different way, outline in this Stackoverflow Q/A


Page:

<p:remoteCommand name="command" action="#{bean.method}" />

JavaScript:

command({param: 'value'});

Bean:

public void method() {
    String value = FacesContext.getCurrentInstance().getExternalContext().getRequestParameterMap().get("param");
}

Combine @BalusC @Joel's post for a functional example

<h:form>
    <p:remoteCommand name="rcName" update="msgs" actionListener="#{remoteCommandView.beanMethod}" />
    <p:growl id="msgs" showDetail="true" />

    <p:commandButton type="button" onclick="rcName([{name:'model', value:'Buick Encore'}, {name:'year', value:2015}]);" value="Pass Parameters 1" /><br/>
    <p:commandButton type="button" onclick="clicked();" value="Pass Parameters 2" />
</h:form>

<script type="text/javascript">
    //<![CDATA[
    function clicked(){
        rcName([{name:'model', value: 'Chevy Volt'}, {name:'year', value:2016}]);
    }
    //]]>
</script>
@ManagedBean
public class RemoteCommandView {
    public void beanMethod() {
        // OR - retrieve values inside beanMethod
        String model1 = FacesContext.getCurrentInstance().getExternalContext().getRequestParameterMap().get("model");
        String year1 = FacesContext.getCurrentInstance().getExternalContext().getRequestParameterMap().get("year");
        FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_INFO, "Executed", 
            "Using RemoteCommand with parameters model := " + model + ", year := " + year));
    }

    @ManagedProperty("#{param.model}")
    private String model;

    @ManagedProperty("#{param.year}")
    private int year;

    public void setModel(String model) {
        this.model = model; // value set by JSF
    }

    public void setYear(int year) {
        this.year = year;
    }
}

When you need to pass more than one parameter from javascript, the syntax is:


var param1 = ...;
var param2 = ...;
var param3 = ...;

remoteCommandFunction([{name:'param1', value:param1}, {name:'param2',value:param2}, {name:'param3',value:param3}]);


If you want to call your own function, eg. a confirm dialog, your custom function must be compliant to the passing parameter style. eg:

   <p:commandLink id="myId" onclick="confirmDelete([{name:'Id', value: '#{my.id}'}]);" immediate="true">

The java script function

            function confirmDelete(id) {
            if (confirm('Do you really want to delete?')) {
                remoteDeleteDemand(id);
                return true;
            }

The remoteCommand tag

<p:remoteCommand name="remoteDeleteDemand" actionListener="#{myController.doDelete}" />

PrimeFace 5.0, dynamic array (all table column width will be send by this method)

Beam

public void updateTableColumnsWidth() {
    FacesContext context = FacesContext.getCurrentInstance();
    Map<String, String> map = context.getExternalContext().getRequestParameterMap();
}

p:remoteCommand

<h:form>
     <p:remoteCommand name="remoteCommand" action="#{controller.updateTableColumnsWidth}" />
</h:form>

JS

<script type="text/javascript">
        function updateTableColumnsWidth () {
                var columnsCount = document.getElementById('table').rows[0].cells.length;

                var json = [];

                for (var i = 0; i &lt; columnsCount; i++) {
                    json[i] = { name: i, value: document.getElementById('table').rows[0].cells[i].offsetWidth};

                }

                console.log(json);
                remoteCommand(json);
            };
    </script>