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
>