Making a RemoteCommand programmatically

What is RemoteCommand

You can find a usage for PrimeFaces RemoteCommand on client side here. RemoteCommand is an implementation of UICommand in PrimeFaces library.

With RemoteCommand you can call a bean method as an ajax call from a client side component callback, for example onChange, onHide, onClick etc.

And in the following it is shown that how you can generate a RemoteCommand and join it to a component programmatically.



Required libraries

import java.util.Map;

import javax.el.MethodExpression;
import javax.faces.application.Application;
import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.event.MethodExpressionActionListener;

import org.primefaces.component.outputlabel.OutputLabel;
import org.primefaces.component.outputpanel.OutputPanel;
import org.primefaces.component.remotecommand.RemoteCommand;
import org.primefaces.component.selectcheckboxmenu.SelectCheckboxMenu;


RemoteCommand example

FacesContext fc = FacesContext.getCurrentInstance();
Application app = FacesContext.getCurrentInstance().getApplication();

// generate a SelectCheckboxMenu
SelectCheckboxMenu scm = (SelectCheckboxMenu) app.createComponent(SelectCheckboxMenu.COMPONENT_TYPE);
String scmId = "scmId";
scm.setId(scmId);
scm.setLabel("a caption..");
// call remote command named populateLabel from callback method 
// send the component id as a parameter to find the component at back-end 
scm.setOnHide("populateLabel([{name:'scmId', value:'" + scmId + "'}]);");

// prepare a remote command
RemoteCommand remoteCommand = new RemoteCommand();
remoteCommand.setName("populateLabel");
MethodExpression methodExpression = app.getExpressionFactory().createMethodExpression(
  fc.getELContext(), "#{myBean.populateLabelOnHide}", null, new Class<?>[]{Object.class});
remoteCommand.addActionListener(new MethodExpressionActionListener(methodExpression));
remoteCommand.setUpdate(":form:" + scmId);
remoteCommand.setProcess("@this form:" + scmId);

// make output label
OutputLabel outputLabel = (OutputLabel) app.createComponent(OutputLabel.COMPONENT_TYPE);
outputLabel.setValue("SCM label");
outputLabel.setFor(scmId);

// make an output panel and add components into it
OutputPanel panel = (OutputPanel) app.createComponent(OutputPanel.COMPONENT_TYPE);
panel.getChildren().add(scm);
panel.getChildren().add(remoteCommand);


Bean method

public void populateLabelOnHide(Object actionEvent) {
 // find select checkbox menu component id parameter
 FacesContext context = FacesContext.getCurrentInstance();
 Map<String, String> params = context.getExternalContext().getRequestParameterMap();
 String selectCheckboxMenuId = params.get("scmId");

 // find SelectCheckboxMenu component
 SelectCheckboxMenu scm = (SelectCheckboxMenu) findComponentRecursivelyById(selectCheckboxMenuId);

 // make an action on it
 scm.setLabel("Change the caption..");
}

You can findComponentRecursivelyById method here

Please check this also

Finding a jsf component in a FacesContext

Finding jsf components recursively by id



public UIComponent findComponentRecursivelyById(String id) {

 UIComponent result = null;
 UIComponent root = FacesContext.getCurrentInstance().getViewRoot();
 if (root != null) {
  result = findComponent(root, id);
 }

 return result;

}

private UIComponent findComponent(UIComponent root, String id) {

 UIComponent result = null;
 if (root.getId().equals(id))
  return root;

 for (UIComponent child : root.getChildren()) {
  if (child.getId().equals(id)) {
   result = child;
   break;
  }

  result = findComponent(child, id);

  if (result != null)
   break;
 }

 return result;
}

Programmatically add ajax behavior to SelectCheckboxMenu

How to add an ajax behavior to PrimeFaces SelectCheckboxMenu programmatically

You can find a simple example for SelectCheckboxMenu here and see how it looks like

Import required libraries

import javax.el.MethodExpression;
import javax.el.ValueExpression;
import javax.faces.application.Application;
import javax.faces.component.UIComponent;
import javax.faces.component.UIViewRoot;
import javax.faces.component.html.HtmlPanelGrid;
import javax.faces.context.FacesContext;
import javax.faces.event.AjaxBehaviorEvent;
import javax.faces.event.BehaviorEvent;

import org.primefaces.component.behavior.ajax.AjaxBehavior;
import org.primefaces.component.behavior.ajax.AjaxBehaviorListenerImpl;
import org.primefaces.component.message.Message;
import org.primefaces.component.outputlabel.OutputLabel;
import org.primefaces.component.outputpanel.OutputPanel;
import org.primefaces.component.selectcheckboxmenu.SelectCheckboxMenu;
import org.primefaces.event.ToggleSelectEvent;

Generate SelectCheckboxMenu and AjaxBehaviors dynamically

in the following code snippet you can find code examples regarding :

  • getting a component from xhtml page 
  • making a new jsf component
  • adding value expression into a component
  • generating method expression and join an ajax behavior to a component
  • adding a new component into the page


..
FacesContext facesContext = FacesContext.getCurrentInstance();
Application app = FacesContext.getCurrentInstance().getApplication();

// find a panel grid in xhtml file  
UIViewRoot root = facesContext.getViewRoot();
HtmlPanelGrid panelGrid = (HtmlPanelGrid) root.findComponent("form:myPanel");

// create HtmlSelectManyCheckbox
// in PrimeFaces there is an implementation for this component, SelectCheckboxMenu
SelectCheckboxMenu scm = (SelectCheckboxMenu) app
  .createComponent(SelectCheckboxMenu.COMPONENT_TYPE);
String scmId = "scmId";
scm.setId(scmId);

// add a value expression into SelectCheckboxMenu
String valueExpressionParamater = "test value";
ValueExpression valueExForScm = app.getExpressionFactory().createValueExpression(
  facesContext.getELContext(), "#{myBean.myMethod('" + valueExpressionParamater + "')}",
  Object.class);
scm.setValueExpression("value", valueExForScm);

// filtered mode
scm.setFilter(true);
scm.setFilterMatchMode("startsWith");
scm.setLabel("You can change label initially");

// prepare and add a method expression for toggleSelect method
MethodExpression methodExpression = app.getExpressionFactory().createMethodExpression(
  facesContext.getELContext(), "#{myBean.populateLabelOnToggleSelect}", null,
  new Class<?>[] { BehaviorEvent.class });
AjaxBehavior ajaxBehavior = (AjaxBehavior) facesContext.getApplication().createBehavior(
  AjaxBehavior.BEHAVIOR_ID);
ajaxBehavior.setUpdate("@this");
ajaxBehavior.setProcess("@this");
ajaxBehavior.addAjaxBehaviorListener(new AjaxBehaviorListenerImpl(methodExpression,
  methodExpression));
scm.addClientBehavior("toggleSelect", ajaxBehavior);

// prepare and add a method expression for change method
methodExpression = app.getExpressionFactory().createMethodExpression(facesContext.getELContext(), "#{myBean.populateLabelOnChange}", null,
  new Class<?>[] { BehaviorEvent.class });
ajaxBehavior = (AjaxBehavior) facesContext.getApplication().createBehavior(
  AjaxBehavior.BEHAVIOR_ID);
ajaxBehavior.setUpdate("@this");
ajaxBehavior.setProcess("@this");
ajaxBehavior.addAjaxBehaviorListener(new AjaxBehaviorListenerImpl(methodExpression,
  methodExpression));
scm.addClientBehavior("toggleSelect", ajaxBehavior);

// make an output label
OutputLabel outputLabel = (OutputLabel) app.createComponent(OutputLabel.COMPONENT_TYPE);
outputLabel.setValue("this caption initially overrides scm caption");
outputLabel.setFor(scmId);

// generate panel add components into it
OutputPanel panel = (OutputPanel) app.createComponent(OutputPanel.COMPONENT_TYPE);
Message message = (Message) app.createComponent(Message.COMPONENT_TYPE);
message.setFor(scmId);
panel.getChildren().add(scm);
panel.getChildren().add(message);

// add components into panel grid
panelGrid.getChildren().add(outputLabel);
panelGrid.getChildren().add(panel);

..

The following are bean methods called from ajax behaviors


public void populateLabelOnChange(AjaxBehaviorEvent event) {
 SelectCheckboxMenu scm = (SelectCheckboxMenu) event.getComponent();
 scm.setLabel("A new label set on change method");
}

public void populateLabelOnToggleSelect(ToggleSelectEvent event) {
 SelectCheckboxMenu scm = (SelectCheckboxMenu) event.getComponent();
 Object[] values = (Object[]) scm.getSubmittedValue();
 scm.setLabel(values.length + " items selected");
}

You can check this also to see making a remote command programmatically