0

I can dynamically add command buttons to the page after the page is loaded, but not before the page is loaded.

In the code below, clicking the command button labeled add buttons works. The view action fails because panelGrid is null when rootview.findcomponent is executed.

<f:metadata>
    <f:viewAction action="#{modStepMBean.updateClientViewAction()}"/>
</f:metadata>
<h:head>
    <title>Start Node Input</title>
    <meta name="viewport" content="width=device-width, initial-scale=1.0"/>
</h:head>
<h:body>

    <h:form id="picNumForm" styleClass="form"  prependId="false">
        <p:panelGrid id="MediaBtnGrid"   columns="7">


        </p:panelGrid>
    </h:form>

    <h:form>
        <p:commandButton value="Add Buttons" action="#{modStepMBean.updateClientViewAction()}">

        </p:commandButton>
    </h:form>

The managed bean

@SessionScoped
@RolesAllowed({"Users"})
@Named
public class ModStepMBean implements Serializable {


private UIComponent buttonGrid;


private void btnCount(Integer mediaCount) {
    FacesContext ctx = FacesContext.getCurrentInstance();
    UIViewRoot rootView = ctx.getViewRoot();
    buttonGrid = (PanelGrid) rootView.findComponent("picNumForm:MediaBtnGrid");
    buttonGrid.getChildren().clear();
    for (int i = 0; i < mediaCount; i++) {
        addMediaBut(i + 1);
    }
}

private void addMediaBut(Integer num) {
    String strNum = Integer.toString(num);
    CommandButton button = new CommandButton();
    button.setValue("Media" + strNum);
    button.setId("MediaBut" + strNum);
    FacesContext facesCtx = FacesContext.getCurrentInstance();
    ELContext elContext = facesCtx.getELContext();
    Application app = facesCtx.getApplication();
    ExpressionFactory elFactory = app.getExpressionFactory();
    MethodExpression methodExpression = null;
    methodExpression = elFactory.createMethodExpression(elContext, "#{modStepMBean.selPic(" + strNum + ")}", null, new Class[]{});
    button.setActionExpression(methodExpression);
    buttonGrid.getChildren().add(button);
}


public void updateClientViewAction()
{
    btnCount(2);
       RequestContext ctx = org.primefaces.context.RequestContext.getCurrentInstance();
            ctx.update("picNumForm");

}

Is this approach wrong? If so, what is the correct approach? Did I miss something? Thanks

  • 1
    The correct approach is to create/declare components in XHTML instead of Java. You will end up with so much better maintainable code. Simply make use of a repeater component like ``. As to your problem, this is a timing error. The answer is in the JSF 2.x approach shown in the duplicate. – BalusC Jun 01 '15 at 20:45
  • OK. Thanks. Sounds like it will be easiest to create the maximum reasonable number of buttons, and then control the rendering of them. – user3555047 Jun 02 '15 at 00:03
  • Nope. Just add an item to the list and update the repeater. – BalusC Jun 02 '15 at 05:13
  • I am new to this so I am not sure how to use the with buttons when I need to somehow identify which button has been pushed. Currently I am using unique parameters in the action method to identify the pushed button. Is there a better way using ? Thanks – user3555047 Jun 03 '15 at 14:52
  • Is this example helpful? http://stackoverflow.com/questions/21290191/how-to-dynamically-add-primefaces-inputfields-with-jquery/21292824#21292824 – BalusC Jun 03 '15 at 14:54
  • Very! Plug and play. On your web site or somewhere else are there solutions to common JSF problems like this? A cook book with tested examples? I can find simple examples and partial solutions that assume more knowledge than I have, but little that covers real life problems with elegant, complete solutions like this one. Thanks! – user3555047 Jun 04 '15 at 01:47

0 Answers0