+ Start a Discussion
philbophilbo 

Does <apex:actionSupport> work inside <apex:repeat> ?

Hey,

 

This is related to an earlier post:

http://community.salesforce.com/sforce/board/message?board.id=Visualforce&thread.id=10588

 

I am trying to make a VF data grid without knowing at compile time how many columns the grid is going to have.  Using straight HTML combined with VF markup, I have managed to do so, via the <apex:repeat> component.  Now I'm trying to take it one step further - I want to hook an actionSupport to each cell in my (one-row) grid so I can write its contents back to the controller and re-render the page (or a part of it).  A mock-up VF page and controller are as follows:

 

Page:

 

<apex:page id="mainPage" controller="testCtrlr" > <apex:form id="mainForm"> <apex:outputPanel id="clickedCell"> <apex:outputText value="Clicked : {!clickedCell}"/> <apex:actionSupport event="onclick" rerender="clickedCell"> <apex:param assignTo="{!clickedCell}" value="TEXT CLICKED {!NOW()}"/> </apex:actionSupport> </apex:outputPanel> <table> <tr> <apex:repeat value="{!rowData}" var="cell"> <td> <apex:outputPanel > <apex:outputText id="rowCell" value="{!cell}"/> <apex:actionSupport event="onclick" rerender="mainPage:mainForm:clickedCell"> <apex:param assignTo="{!clickedCell}" value="{!cell} {!NOW()}"/> </apex:actionSupport> </apex:outputPanel> </td> </apex:repeat> </tr> </table> </apex:form> </apex:page>

 

...and Controller:

 

public class testCtrlr { public String[] rowData { get { return new String[] { 'CELL 0' , 'CELL 1' , 'CELL 2' , 'CELL 3' }; } set; } public String clickedCell { get; set {
System.debug ( 'SETTING clickedCell to [' + value + ']' );
clickedCell = value;
}
} }

 

A couple of things about this don't seem to work.

  1. The resulting one-row table has four cells, containing the contents of the 'rowData' array ('CELL 0', etc.).  I would expect to be able to click on any of these cells and have its contents written into the 'clickedCell' property - and then displayed on the page thanks to the 'rerender' attribute of the 'actionSupport' component.  But what actually happens is - it only works for the right-most cell, the one containing 'CELL 3', and then only if it is the very first cell I click.  The AJAX refresh always seems to take place, according to my System Log window, but the only time the 'clickedCell's setter method is invoked is if the right-most cell is clicked the FIRST TIME, and never after for any cell.  It's as if the <apex:param> component ceases to work after the first time (and never does at all if any other cell is clicked).  I took a look at the page source and, though I don't really know what I'm looking at, it seems like all the cells have the same or similar 'onclick' directive.
  2. Notice the actionSupport attached to the 'clickedCell' outputPanel, updating the 'clickedCell' property to 'TEXT CLICKED' when you click on it.  I put that in there to demonstrate that THIS component does not have the same problem - you can click on it repeatedly and the 'clickedCell' property always gets set like it's supposed to.

Is there something I'm missing, here?  I feel like I'm <THIS> close, but not quite there.

 

Thanks, anybody who can comment on this.

 

 

Best Answer chosen by Admin (Salesforce Developers) 
Ron HessRon Hess

i think this is working to do what you are looking for, i made minor changes to your page and class

 

page changes:

 

<table> <tr> <apex:repeat value="{!rowData}" var="cell"> <td> <apex:outputPanel > <apex:outputText value="{!cell}"/> <apex:actionSupport event="onclick" action="{!myAction}" rerender="clickedCell"> <apex:param name="clickedCell" value="{!cell} {!NOW()}"/> </apex:actionSupport> </apex:outputPanel> </td> </apex:repeat> </tr> </table>

 

Note, i'm using myAction to be called on each click, and sending a parameter of name clickedCell

 

in the controller i set that value for the next time the page is rendered

 

 

public PageReference myAction() { clickedCell = ApexPages.CurrentPage().getParameters().get('clickedCell'); return null; }

 

 the rest of the code is the same

 

why does this work, and assignTo does not ? i think it has to do with the fact that there was no action called in your action support component.  cannot say for sure on this.

 

 

 

 

 

 

All Answers

Ron HessRon Hess

i think this is working to do what you are looking for, i made minor changes to your page and class

 

page changes:

 

<table> <tr> <apex:repeat value="{!rowData}" var="cell"> <td> <apex:outputPanel > <apex:outputText value="{!cell}"/> <apex:actionSupport event="onclick" action="{!myAction}" rerender="clickedCell"> <apex:param name="clickedCell" value="{!cell} {!NOW()}"/> </apex:actionSupport> </apex:outputPanel> </td> </apex:repeat> </tr> </table>

 

Note, i'm using myAction to be called on each click, and sending a parameter of name clickedCell

 

in the controller i set that value for the next time the page is rendered

 

 

public PageReference myAction() { clickedCell = ApexPages.CurrentPage().getParameters().get('clickedCell'); return null; }

 

 the rest of the code is the same

 

why does this work, and assignTo does not ? i think it has to do with the fact that there was no action called in your action support component.  cannot say for sure on this.

 

 

 

 

 

 

This was selected as the best answer
philbophilbo

Ron - this is exactly what I needed!  Like you, I am not sure why my original formulation was behaving the way it was - but I'm happy to pass my "state" (what cell I just clicked) back to the controller via a page parameter. 

 

Thanks very much.  

 

I am having some trouble getting the whole thing to display when I wrap it in the 'stop' facet of an actionStatus, but I'll take a good crack at that myself first before bringin' it back to the dev boards.

 

Thanks again -

Message Edited by philbo on 03-08-2009 09:34 PM
d3developerd3developer

Somewhat bizarrely, the assignment of the param for the actionsupport also does not work if there is no rerender specified.

raj123raj123

Thanks for sharing above information i was having lot of problem without having the rerender in the actionsupport , its wasnt working , now after adding is it working fine.