+ Start a Discussion
HGSHGS 

Duplicate IDs if component is used in a loop in a VF page

Hello Community,

 

I have a VF page, with a list of objects.

 

I am using DataTable to bring the list of objects on VF Page, and am using a component to display a single object. The component has its own logic of building the view to display that object.

 

Now, in that component, I have a small button, that is supposed to do something in the background, and update the display of an object field on the component itself. And, I am using apex:CommandLink and rerender to do that.

 

But, the issue is, that when a component is rendered repeatedly in a VF page, the IDs inside the component are also duplicated and repeated as-they-are; resulting in duplicate IDs in the VF page.

 

For example, if I have a <apex:outputText id="DisplayName" value="{!DisplayName}"> inside the component; and if this component is repeated in the VF page, all these outputText elements would have the same ID.., not even a single change....., and if I am trying to re-render this outputText, the system doesn't do anything at all.

 

Re-render is not working at all, in this case...

 

To summarize again, if I am using a component repeatedly in a VF page, and doing something inside the component and re-rendering inside the component.. it doesn't work at all !!

 

Any solutions ? I dont want to go the manual way of writing javascript and ajax methods.

 

 

Best Answer chosen by Admin (Salesforce Developers) 
Rajesh ShahRajesh Shah

I would suggest rerendering the whole DataTable. This way you wont require the need for Dynamic Ids.

 

One more thing. When inside the DataTable, each of the outputText will have a uniqueId For e.g. when rerendering, the h code will attach a extra part to the already existing Id making it unique. 

All Answers

wesnoltewesnolte

Hey

 

I would suggest creating the Id dynmically or taking the code out of the component and putting it into the page. If you want to generate the Id dynmically create a method appends sequential numbers ot the end of the id in question e.g.

 

1. pass an id to the component as an attribute e.g. componentId='DisplayName'  

2. create a method that returns ids such as 'DisplayName1', 'DisplayName2', etc. you could set the id of the field using this method as well as the rerender attribute of teh button.

 

Cheers,

Wes 

 

 

HGSHGS

Thanks for replying. Before we proceed, a little more clarification:

 

 

  1. All functionality is being handled inside the component, only product ID is being passed (this is a catalog)
  2. The command-link and the element to be re-rendered are also inside the component. 
  3. I tried that dynamic id creation, and thought I could append the productID with the elementID.., but "rerender" clause expects the exact ID of the component to be re-rendered.., and it didnt work out !!
  4. I cannot bring out code in the page itself, as the component is being used in a lot of other pages

 

 

 

HGSHGS

For dynamic IDs, here is what I tried :

 

 <apex:commandLink value="{!UpdatePreference}" rerender="PreferenceText{!ProductId}"/>

 

And, here is the text to  be updated:

 

<apex:outputText value="{!StatusText}" id="PreferenceText{!ProductId}"/>

 

.... .

 

This didn't work out, I checked the HTML generated, and the re-render was not converted to the long IDs that VF generates.

 

 

Thanks

 

HGS

 

Rajesh ShahRajesh Shah

I would suggest rerendering the whole DataTable. This way you wont require the need for Dynamic Ids.

 

One more thing. When inside the DataTable, each of the outputText will have a uniqueId For e.g. when rerendering, the h code will attach a extra part to the already existing Id making it unique. 

This was selected as the best answer
DevAngelDevAngel

Hello HGS,

 

Here is what I would try, although I haven't actually tested it.  Below is what the component declaration is inside an iteration tag (doesn't have to be repeat).

 

 

<apex:repeat value="{!myDataset}" var="myData"> <c:customComponent rerenderId="cc{!myData.Id}" /></apex:repeat>

 

 And the component definition might look like:

 

 

<apex:component> <apex:attribute name="rerenderId" type="String" required="true" description="" /> <apex:outputPanel id="{!rerenderId}"> <apex:....> </apex:outputPanel> <apex:commandLink action="{!doSomething}" rerender="{!rerenderId}" /></apex:component>

 In this case you are using an id from the iteration to created a unique id.  You are passing that id to the component as an attribute and using the binding expression to set the id for the are to be rerendered as well as the rerender attribute of the commandLink.

 

Cheers,