Pass parameter to p:remoteCommand from JavaScript

JavascriptJsfPrimefacesParametersRemotecommand

Javascript Problem Overview


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?

Javascript Solutions


Solution 1 - Javascript

Yes, it is possible. How to do that depends on the PrimeFaces version. You can see it in PrimeFaces users guide.

PrimeFaces 3.3 or newer

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");

PrimeFaces 3.2 or older

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).


See also:

Solution 2 - Javascript

Page:

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

JavaScript:

command({param: 'value'});

Bean:

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

Solution 3 - Javascript

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

Solution 4 - Javascript

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;
    }
}

Solution 5 - Javascript

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}]);

Solution 6 - Javascript

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}" />

Solution 7 - Javascript

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>

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionRajat GuptaView Question on Stackoverflow
Solution 1 - JavascriptBalusCView Answer on Stackoverflow
Solution 2 - JavascriptJoelView Answer on Stackoverflow
Solution 3 - JavascriptCagatay CiviciView Answer on Stackoverflow
Solution 4 - JavascriptJonathan LView Answer on Stackoverflow
Solution 5 - JavascriptDavid F. Suárez ChacónView Answer on Stackoverflow
Solution 6 - JavascriptjoreliaView Answer on Stackoverflow
Solution 7 - JavascriptVasil ValchevView Answer on Stackoverflow