开发者

How to add dynamically a component in JSF2 during an Ajax request

开发者 https://www.devze.com 2022-12-27 18:36 出处:网络
I am currently trying to dynamically add a new component to the JSF component tree during an ajax request.

I am currently trying to dynamically add a new component to the JSF component tree during an ajax request.

In fact I add a child to the UIViewRoot component in my AjaxBehaviorList开发者_如何学JAVAener which is fired on server side during the ajax request process.

The issue is that the new component is not rendered. It seems that this component is not taken into account in the render response phase.

Could you help me on this issue ?

Regards,

Guillaume


This solution works in case of you know before the ajax request the component to add. But if you are not able to know which component to add, it does not work.

I maybe found a solution :

My solution is to implement my custom PartialViewContext and use the method startInsertAfter or startInsertBefore of the PartialResponseWriter.

It is working, but you have to put the component added as transient. (uiComponent.setTransient(Boolean.TRUE);)

Regards,

Guillaume


This works for me:

Bean holding binding to UIComponent under which you want to add other UIComponents dynamically should be request scoped otherwise it can throw some nasty exceptions (don't ask me why):

   @ManagedBean
    @RequestScoped
    public class AddressEditorBean {
// session bean reference for holding id number line and model
        @ManagedProperty(value = "#{addressValueBean}")
        private AddressValueBean address;     
        public String addOutputText() {
            HtmlOutputText text = new HtmlOutputText();
            int c = address.getC();
            text.setValue("new text! " + c);
            text.setId("id" + c++);
            address.setC(c);              // hold id number line in sessionbean
            address.getComps().add(text); // hold new uicomponent in session bean to be able to rebuild it
            panel.getChildren().clear();  // need to clear children and add them all again,
            panel.getChildren().addAll(address.getComps()); // otherwise there are problems with duplicate children (bug?)
            return "success";
        }

        public HtmlPanelGroup getPanel() {
            return panel;
        }

        public void setPanel(HtmlPanelGroup pane) {
            if (panel == null) {
                this.panel = pane;
                if (panel != null) {
                    panel.getChildren().addAll(address.getComps());
                }
            } else {
                this.panel = pane;
            }
        }
    }

code snippet from page. I dynnamically add components to <h:panelGroup>

 <h:form>
        <h:panelGroup id="section" binding="#{addressEditorBean.panel}">

        </h:panelGroup>
        <h:commandButton value="add new text" action="#{addressEditorBean.addOutputText}">
            <f:ajax execute="@this" render="section" event="action"/>
        </h:commandButton>
    </h:form>

In Session bean I hold actual dynamic model so that I can rebuild it after page reload:

@ManagedBean
@SessionScoped
public class AddressValueBean extends ValueBean<Address> {

    private int c = 0;
    private List<UIComponent> comps = new ArrayList<UIComponent>();

    public AddressValueBean() {
        setValue(new Address());
    }

    public int getC() {
        return c;
    }

    public void setC(int cn) {
        this.c = cn;
    }

    public List<UIComponent> getComps() {
        return comps;
    }

    public void setComps(List<UIComponent> comps) {
        this.comps = comps;
    }
}


Instead of trying to add the component dynamically during the ajax request, try defining the component upfront, and setting it's rendered tag to false. The contents of the component can then be populated with the ajax request, and the rendered attribute flipped to display the attribute.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号