function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
momorganmomorgan 

Issue with AJAX-based page updates and fields

I'm passing details from one VF page to another. If you've read "Creating a Wizard with Visualforce Pages" in the Cookbook, you'll be familar with this.

 

I'm also showing and hiding certain fields based on user actions. If you've read "Dynamically Updating a Page" in the Cookbook, you'll know this too.

 

However, I'm finding a problem when the two techniques are combined. To illustrate this, I've prepared a simple example using two pages that share a standalone controller.

 

Here's the Apex:

 

 

public class listdemo {

public List<selectOption> getFoodstuffOptions() {
List<SelectOption> options = new List<SelectOption>();
options.add(new SelectOption('A Fish', 'A Fish'));
options.add(new SelectOption('Some Chips', 'Some Chips'));
return options;
}

public class tempList{
public String foodstuff {get; set;}
public Integer quantity {get; set;}
public tempList(string inFoodstuff, integer inQuantity){
foodstuff = inFoodstuff;
quantity = inQuantity;
}
}

private List<tempList> ListOne {get; set;}
public List<tempList> getListOne(){
if(ListOne == null){
ListOne = new List<tempList>();
for (Integer c = 0; c < 5; c++){
ListOne.add(new tempList(null,null));
}
}
return ListOne;
}

private List<tempList> ListTwo {get; set;}
public List<tempList> getListTwo(){
if(ListTwo == null){
ListTwo = new List<tempList>();
for (Integer c = 0; c < ListOne.Size(); c++){
ListTwo.add(new tempList(ListOne.Get(c).foodstuff,ListOne.Get(c).quantity));
}
}
return ListTwo;
}

public PageReference feedme(){
return Page.ListDemo2;
}

}

 

 

Here's the first VF page:

 

 

<apex:page Controller="listdemo">
<apex:form >
<apex:pageblock mode="edit">
<apex:pageBlockButtons location="bottom">
<apex:commandButton action="{!feedme}" value="Next" />
</apex:pageBlockButtons>
<apex:pageblockTable value="{!ListOne}" var="l" width="100%">
<apex:column headervalue="Foodstuff" width="50%">
<apex:actionRegion >
<apex:selectlist value="{!l.foodstuff}" multiselect="false" size="1" required="true">
<apex:selectOptions value="{!foodstuffoptions}" />
<apex:actionSupport event="onchange" rerender="quantitycolumn" />
</apex:selectlist>
</apex:actionRegion>
</apex:column>
<apex:column headervalue="Quantity" id="quantitycolumn" width="50%">
<apex:inputText required="true" value="{!l.quantity}" rendered="{!l.foodstuff == 'Some Chips'}" />
</apex:column>
</apex:pageblockTable>
</apex:pageBlock>
</apex:form>
</apex:page>

 

Here's the second VF page:

 

 

<apex:page Controller="listdemo">
<apex:form >
<apex:pageblock>
<apex:pageblockTable value="{!ListTwo}" var="l" width="100%">
<apex:column value="{!l.foodstuff}" headervalue="Foodstuff" width="50%" />
<apex:column value="{!l.quantity}" headervalue="Quantity" />
</apex:pageblockTable>
</apex:pageBlock>
</apex:form>
</apex:page>

 

On the first page is an editable table with two columns (Foodstuff and Quantity) and five rows. For each row you can choose the value of Foodstuff from a drop-down list. There are two possible values: A Fish and Some Chips. The adjacent box to accept an value in the Quantity column appears only if you choose Some Chips.

 

So, on one or more rows, choose Some Chips and enter a quantity, then click Next to take this to the second page.

 

Screenshot of first page

 

The second page shows an even simpler table. The table on the first page reflects the contents of a list (ListOne). This list is then copied to another list (ListTwo) for the table on the second page.

 

However, while the values for Foodstuff make it through, the values for Quantity do not.

 

Screenshot of second page

 

Can anyone suggest why?

 

Thanks.

 

Rajesh ShahRajesh Shah

As per your code, there is no action attached to the inputText. Hence when the value changes, it doesn't gets binded with the controller. And hence page 2 shows them as blank. What you will have to do is attach something to the quantity text box so that as soon as somone enters anything in the text box .. its calls a controller function and the binding takes place. For e.g., you can something of the following kind in the first page.

 

 

<apex:inputText required="true" value="{!l.quantity}" rendered="{!l.foodstuff == 'Some Chips'}"> <apex:actionSupport event="onchange" rerender="quantitycolumn" call a controller function /></apex:inputText>

 

 

 

momorganmomorgan

I've tried what I think you're suggesting, but with the same result. It's likely that I don't follow what you mean - could you be more specific about what the inputText behaviour should be?

 

Another thing I've noticed - the inputText fields are marked as required="true". My understanding is that this should apply if they're visible, and yet it's possible to submit the form with them blank.

momorganmomorgan

Something else - if the following line in Apex:

 

 

ListOne.add(new tempList(null,null));

 ...is changed to:

 

 

ListOne.add(new tempList('Some Chips',null));

 (i.e. effectively setting a default value for Foodstuff that matches the rendered condition of Quantity), it works fine. In other words, if the rendered condition is true when the initial page loads:

 

<apex:inputText required="true" value="{!l.quantity}" rendered="{!l.foodstuff == 'Some Chips'}" />

 ...then all is well. But, if the inputText is not rendered at page load (i.e. the rendered condition is false until something else happens), then value of the inputText doesn't carry through and the required="true" condition is ignored.

 

Can anyone advise why that would be?

 

 

 

 

momorganmomorgan
Anyone?