55

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?

BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
Rajat Gupta
  • 25,853
  • 63
  • 179
  • 294
  • 3
    The first answers here are outdated, please see the answer from @BalusC http://stackoverflow.com/a/18510102/55070 – leo Apr 29 '15 at 13:28

7 Answers7

91

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:

Community
  • 1
  • 1
BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
  • lol, I need to pass string[] array from js and the only way is to set one by one all params? Can you show sample of that? Anyway +1 for this answer :) – Vasil Valchev Mar 24 '17 at 17:42
  • I'm using Primefaces 2.1, but suggested sollution is not working for me. I have written question here https://stackoverflow.com/questions/63819389/passing-parameter-from-xhtml-through-premotecommand-to-java-bean-not-working. Could someone tell me what am I doing wrong? – Patrik Sep 09 '20 at 21:01
63

Page:

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

JavaScript:

command({param: 'value'});

Bean:

public void method() {
    String value = FacesContext.getCurrentInstance().getExternalContext().getRequestParameterMap().get("param");
}
Joel
  • 15,496
  • 7
  • 52
  • 40
  • Thank you for this simple answer! Unfortunately it seems impossible to define `action="#{bean.method(param)}"`, which would avoid the call to `FacesContext.getCurrentInstance().getExternalContext().getRequestParameterMap().get("param")` in the bean? – Grégoire C Mar 06 '15 at 11:36
  • 1
    @geceo I haven't worked with JSF for a while, but I guess it should be possible to implement a utility which allows you to write something like `action="#{bean.method(Utility.getParam("param"))}"`. – Joel Mar 06 '15 at 13:57
  • 3
    @GrégoireColbert and @Joel, it is possible, just write ```action="#{bean.method(param.param)}"```. The map ```param``` is the EL represenation of ```FacesContext.getCurrentInstance().getExternalContext().getRequestParameterMap()‌```. – Stefan Seidel Feb 03 '16 at 14:01
  • 3
    This does not work anymore, see BalusC answer for Primefaces 3.3+. – tak3shi Aug 10 '16 at 09:13
27
remoteCommandFunctionName({name1:'value1', name2:'value2'});
Cagatay Civici
  • 6,406
  • 1
  • 29
  • 34
  • You don't recieve the value in remoteCommand, you just use another component that you can tell remoteCommand to update. You set your field/s in your backing bean with the new values you want using p:remoteCommand, then set the update="component2" attribute of p:remoteCommand to point to a second component, then you set the value of the second component by simply calling the updated fields in the bean by adding value="#{myBean.value}". – Fuzzy Analysis Apr 11 '15 at 08:47
  • 5
    Since 3.3 parameter passing format is your_command( [ {name:'x', value:10}, {name:'y', value:20} ] ); – digital illusion May 06 '15 at 18:06
  • I'm using primefaces 3.3 and above but this fix doesn't work. The parameterMap is null onclick="rc(([{name: 'emailInstance', value:#{notification.emailInstanceId}}]))" – Arvind Jul 15 '20 at 18:15
10

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;
    }
}
Betlista
  • 10,327
  • 13
  • 69
  • 110
Jonathan L
  • 9,552
  • 4
  • 49
  • 38
4

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

  • @BalusC I tried Cagatay's example but with more than one parameter it didn't work (weird, huh?). Passing parameters as foo({name1:'value1', name2:'value2'}); does not send correctly the parameters to RequestParameterMap, so I tried specifying name and value for each parameter and wrapping them in an array foo([{name:'name1', value:'value1'}, {name:'name2', value:'value2'}]); – David F. Suárez Chacón Jun 17 '13 at 14:02
4

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}" />
Micer
  • 8,731
  • 3
  • 79
  • 73
jorelia
  • 41
  • 1
1

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>
Vasil Valchev
  • 5,701
  • 2
  • 34
  • 39