If it makes a difference, here is my renderer's code for this component: public class HelpIconRenderer extends CommandLinkRenderer { public final static String RENDERER_TYPE = "com.christws.HelpIcon";
private PropertyKey messageIdKey; private PropertyKey forKey; public HelpIconRenderer() { super(UIHelpIcon.TYPE); } /** * @see org.apache.myfaces.trinidadinternal.renderkit.core.xhtml.CommandLinkRenderer#findTypeConstants(org.apache.myfaces.trinidad.bean.FacesBean.Type) */ @Override protected void findTypeConstants(Type type) { super.findTypeConstants(type); messageIdKey = type.findKey("messageId"); forKey = type.findKey("for"); } /** * @see org.apache.myfaces.trinidadinternal.renderkit.core.xhtml.XhtmlRenderer#getStyleClass(org.apache.myfaces.trinidad.bean.FacesBean) */ @Override protected String getStyleClass(FacesBean bean) { return "helpButton"; } /** * @see org.apache.myfaces.trinidadinternal.renderkit.core.xhtml.CommandLinkRenderer#getPartialSubmit(org.apache.myfaces.trinidad.bean.FacesBean) */ @Override protected boolean getPartialSubmit(FacesBean bean) { return true; } protected String getFor(FacesBean bean) { return toString(bean.getProperty(forKey)); } protected String getMessageId(FacesBean bean) { return toString(bean.getProperty(messageIdKey)); } /** * @see org.apache.myfaces.trinidadinternal.renderkit.core.xhtml.CommandLinkRenderer#getImmediate(org.apache.myfaces.trinidad.bean.FacesBean) */ @Override protected boolean getImmediate(FacesBean bean) { return true; } /** * @see org.apache.myfaces.trinidadinternal.renderkit.core.xhtml.XhtmlRenderer#shouldRenderId(javax.faces.context.FacesContext, javax.faces.component.UIComponent) */ @Override protected boolean shouldRenderId(FacesContext context, UIComponent component) { return true; } /** * @see org.apache.myfaces.trinidadinternal.renderkit.core.xhtml.CommandLinkRenderer#encodeEnd(javax.faces.context.FacesContext, org.apache.myfaces.trinidad.context.RenderingContext, javax.faces.component.UIComponent, org.apache.myfaces.trinidad.bean.FacesBean) */ @Override public void encodeEnd(FacesContext context, RenderingContext arc, UIComponent comp, FacesBean bean) throws IOException { CoreIcon icon = FacesUtils.createComponent(CoreIcon.class); icon.setTransient(true); icon.setId(context.getViewRoot().createUniqueId()); icon.setName("help"); icon.setParent(comp); org.apache.myfaces.trinidad.render.RenderUtils.encodeRecursive(context, icon); super.encodeEnd(context, arc, comp, bean); ResponseWriter writer = context.getResponseWriter(); String forValue = getFor(bean); UIComponent forComp = ComponentUtils.findRelativeComponent(comp, forValue); StringBuilder js = new StringBuilder( "Help.register('").append(forComp.getClientId(context)) .append("', '").append(comp.getClientId(context)) .append("');"); RenderUtils.renderScript(context, js); } } On 9/5/07, Andrew Robinson <[EMAIL PROTECTED]> wrote: > I am wondering if this is a bug or planned with UIXComponentBase: > > I was noticing that my custom component that extended CoreCommandLink > stopped working after a partial update. When trying to figure out why, > I noticed that the ID of the link changed between rendering and > therefore the decode no longer worked. > > On first page rendering, the link ID was _id44. During decode, it was > still _id44. During encode, it was _id108. It failed partial update > because the ID changed, and therefore all further decodes failed since > the client was now out of sync from the server. > > In UIComponentBase.getClientId, if the getId() returns null, a new ID > is created and then setId is called. UIXComponentBase never calls > setId, but instead caches it in a "_genId" property using the > FacesBean. > > Therefore, anything extending UIComponentBase and has a generated ID > will never have its ID change between requests on the same view. > However, it seems that UIXComponentBase does not guarantee that a > component with a generated ID will have a consistent ID. > > Here is my code: > > <tr:panelLabelAndMessage > label="Test help"> > <tr:inputText id="testHelp" value="#{testHelpText}" > simple="true" /> > <f:facet name="end"> > <cw:helpIcon for="testHelp" > messageId="test_help" /> > </f:facet> > </tr:panelLabelAndMessage> > > The cw:helpIcon extends CoreCommandLink > > If I give the helpIcon a hard coded ID, it works fine. > > Is this a bug, a shortcoming, or just not supported with UIXComponentBase? > > I seems like it could be a very big source of problems if IDs change > between requests, as decodes will have a lot of problems. Should > UIXComponentBase be calling setId after generating an ID in the > getClientId function? > > This was found on 1.0.3-SNAPSHOT > > Any ideas? > > Thanks, > Andrew >