eclipse-ee4j / mojarra

Mojarra, a Jakarta Faces implementation
Other
165 stars 112 forks source link

Component id changes when an action modifies component tree #4200

Closed ren-zhijun-oracle closed 1 year ago

ren-zhijun-oracle commented 8 years ago

We use to include our components into a form.

On included components we don't define ids just leverage on autogenerated component id for primefaces command button.

For a simplified example we start with 3 components with a on them. Initially component 1 and 3 is included to the form with second component is not included. As a result commandbutton action on component 1 we update only the container of the second component and includes the component between the existing two components. Commandbutton on component 2 receives the same id as commandbutton on component 3, so there are two buttons in the browser with the same id and the two commandbuttons call the same action.

If we update the whole form after the action instead of the target component we can see the commandbutton 3 receives a new id as well, but partial update riuns the view.

How can we make partial update work with our component structure? I attach our simplified example of the issue. We don't experience this issue on Websphere with myfaces.

Thanks

Environment

Wildfly 10.0.0 Final, Weblogic

Affected Versions

[2.2.8-12, 2.2.8-18, 2.3.0-m06]

ren-zhijun-oracle commented 6 years ago
ren-zhijun-oracle commented 7 years ago

@javaserverfaces Commented Reported by szuni

ren-zhijun-oracle commented 7 years ago

@javaserverfaces Commented szuni said:

**page.xhtml**    <h:form>
        <ui:decorate template="domincluder.xhtml">
            <ui:param name="subBean" value="#{insertDomBean.subBeanList[0]}"/>
        </ui:decorate>
        <p:outputPanel id="hidden">
            <c:choose>
<c:when test="#{insertDomBean.subBeanList[0].buttonPushed}">
    <ui:decorate template="domincluder.xhtml">
        <ui:param name="subBean" value="#{insertDomBean.subBeanList[1]}"/>
    </ui:decorate>
</c:when>
<c:otherwise>
    <p:outputLabel value="Button 1 not pushed"/>
</c:otherwise>
            </c:choose>
        </p:outputPanel>
        <p:outputPanel>
            <ui:decorate template="domincluder.xhtml">
<ui:param name="subBean" value="#{insertDomBean.subBeanList[2]}"/>
            </ui:decorate>
        </p:outputPanel>
    </h:form>
**domincluder.xhtml**<ui:composition xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:c="http://java.sun.com/jstl/core"
xmlns:p="http://primefaces.org/ui"> 
    <p:commandButton value="#{subBean.text}" action="#{subBean.pushed()}" update="hidden"/>

</ui:composition>
**InsertDomBean.java**@Named
@ViewScoped
public class InsertDomBean implements Serializable{
    private List<SubBean> subBeanList;

    public InsertDomBean() {
        subBeanList = Arrays.asList(new SubBean("One"), new SubBean("Two"), new SubBean("Three"));
    }

    public List<SubBean> getSubBeanList() {
        return this.subBeanList;
    }

    public static class SubBean {

        private String text;
        private boolean buttonPushed;

        public SubBean(String text) {
            this.text = text;
        }

        public void pushed() {
            LOG.info(text);
            this.buttonPushed = true;
        }

        public boolean isButtonPushed() {
            return this.buttonPushed;
        }

        public void setButtonPushed(boolean buttonPushed) {
            this.buttonPushed = buttonPushed;
        }

        public String getText() {
            return this.text;
        }
    }
}
ren-zhijun-oracle commented 7 years ago

@javaserverfaces Commented ren.zhijun.oracle said: can you provide me a runnable reproducer?

ren-zhijun-oracle commented 7 years ago

@javaserverfaces Commented szuni said: Please place the provided .java and 2 .xhtmls from the comment above into a war and run it. After you pushed second button and try to push third you can see our problem.

ren-zhijun-oracle commented 7 years ago

@javaserverfaces Commented ren.zhijun.oracle said: I have reproduced your issue:

1. In the first request, the whole page is rendered to client, the button3's clientid is j_idt9, the button2 is not rendered; 2. When Button1 is clicked, an AJAX request was sent, as response, only button 2's dom element was sent to client, and it's id is also j_idt9; so in the client side, Button2 and Button3 has equal client id(under the same form).

I found the root cause and it is really a JSF issue, it is due to basic and complicated algorithm for generating id during the component tree building up. To fix it, we need to change the current mechanism and this will be not a minor work and is very risky. We will consider it and check whether we can find a feasible way to handle.

Can it be fixed in PrimeFaces side? by implementing the class of the wrapped tag( p:outputPanel,) as a class of NamingContainer, so that client id of the button will be composed by FormId + p:outputPanel Id + button Id, this can ensure the id uniqueness of buttons in the client side.

ren-zhijun-oracle commented 7 years ago

@javaserverfaces Commented Was assigned to ren.zhijun.oracle

ren-zhijun-oracle commented 7 years ago

@javaserverfaces Commented This issue was imported from java.net JIRA JAVASERVERFACES-4196

ren-zhijun-oracle commented 7 years ago

@edburns Commented Please see this important message regarding community contributions to Mojarra.

https://javaee.groups.io/g/jsf-spec/message/30

Also, please consider joining that group, as that group has taken the place of the old dev@javaserverfaces.java.net mailing list.

Thanks,

Ed Burns

mnriem commented 1 year ago

For Mojarra 2.3 and earlier please contact your vendor for support (RedHat, IBM, Oracle, Omnifish, Payara, etceteras)