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
mauricio.ramosmauricio.ramos 

Dynamic visualforce component not rendering on action call

Hello all,

 

I am working in adding a dynamic component to a vf page that loads a field set and some other stuff into a page section at the bottom of the mentioned VF page. The idea is that when the user focuses on a picklist field that is part of a row of records displayed in a pageblock table, the dynamic component should update with the correct set of field sets on a pageblocksection below the table. The thing is that it is not doing this because I cannot ge tthe current record id (the row in the table where the user is focusing) to be passed to the controller and therefore it is getting NULL Since the code in the controller has a validation to return null IF hte current record is null, nothing is happening. Yet if I perform changes to other fields on the row the record id is passed just fine back to the controller. can someone assist! Below is the VF page, the controller nad the debug result, where I highlight the relevant parts.

 

Thanks!

 

Debug log:

15:08:28.452 (452150000)|USER_DEBUG|[317]|DEBUG|#### DETCOMP- CurrSOI: null

 

VF PAGE:

<apex:page controller="VF_SalesDoc_CreateDoc_Controller_MR" tabStyle="SCRB_SalesOrder__c" >
<!--I'VE REMOVED PART OF THE PAGE DUE TO SIZE RESTRICTIONS ON THE POST, BUT IT IS NOT RELEVANT TO THE ISSUE>
<apex:sectionHeader title="Create Sales Document" subtitle="{!Account.Name}"/>
<apex:messages />
<apex:form id="theForm">

<apex:pageblock title="Sales Order Items" tabStyle="SCRB_SalesOrder__c" >
<apex:pageBlockButtons location="top" >
<apex:commandButton action="{!AddSOI}" value="Add New Item" rerender="tablePnl" disabled="{!NOT(SOsaved)}" id="btnAddSOI" />
</apex:pageBlockButtons>

<apex:outputPanel id="tablePnl">
<apex:pageblockTable value="{!SOItems}" var="SOI" id="SOIList" columnsWidth="25px, 50px, 100px, 100px, 25px, 25px, 50px, 50px, 50px, 50px, 50px, 25px" columns="12" >

<apex:column headerValue="Action">
<apex:commandLink value="Del" action="{!del}" rerender="tablePnl" style="font-weight:bold" >&nbsp;|&nbsp;
<apex:param name="delname" value="{!SOI.id}" assignTo="{!currSOIid}"/>
<apex:outputLink title="" value="/{!SOI.id}" style="font-weight:bold" target="_blank" >View</apex:outputLink>
</apex:commandLink>
</apex:column>

<apex:column headerValue="Line type">
<apex:actionRegion id="lnTypeRgn">
<apex:inputField value="{!SOI.Line_Type__c}" id="fLineType">
<apex:actionSupport event="onblur" reRender="detailBlock" action="{!loadSOIDetComponent}">
<apex:param name="currSOIid" value="{!SOI.Id}" assignTo="{!currSOIid}"/>
</apex:actionSupport>
</apex:inputField>
{!SOI.id}
</apex:actionRegion>
</apex:column>


<apex:column headerValue="Product">
<apex:actionRegion id="prodRgn">
<apex:inputField value="{!SOI.ProductId__c}" id="fProd">
<apex:commandLink id="lknProduct" action="{!updateSOIProductData}" value="Refresh" reRender="tablePnl,fDiscAmt,fTotalPrice,fProfit,colProfit">
<apex:param name="currSOI" value="{!SOI.Id}" assignTo="{!currSOIid}"/>
</apex:commandLink>
</apex:inputField>
</apex:actionRegion>
</apex:column>

<apex:column headerValue="Description">
<apex:inputField value="{!SOI.Description__c}" id="fDescr" />
</apex:column>

<apex:column headerValue="Quantity">
<apex:actionRegion >
<apex:inputField value="{!SOI.Quantity__c}" id="fQTY">
<apex:actionSupport event="onchange" rerender="fDiscAmt,fTotalPrice,fProfi,colProfit" action="{!calculateTotalPrice}">
<apex:param name="currSOIQty" value="{!SOI.Id}" assignTo="{!currSOIid}"/>
</apex:actionSupport>
</apex:inputField>
</apex:actionRegion>
</apex:column>
<apex:column headerValue="Unit Cost" >
<apex:inputField value="{!SOI.Unit_Cost__c}" id="fUnitCost" />
</apex:column>
<apex:column headerValue="Sales Price ex VAT">
<apex:inputField value="{!SOI.SalesPrice__c}" id="fSalesPrice" >
<apex:actionSupport event="onchange" rerender="fDiscAmt,fTotalPrice,fProfit,colProfit" action="{!calculateTotalPrice}">
<apex:param name="currSOISlsPr" value="{!SOI.Id}" assignTo="{!currSOIid}"/>
</apex:actionSupport>
</apex:inputField>
</apex:column>
<apex:column headerValue="Line Disc Pct.">
<apex:inputField value="{!SOI.Line_Discount_Pct__c}" id="fDiscPct">
<apex:actionSupport event="onchange" rerender="fDiscAmt,fTotalPrice,fProfit,colProfit" action="{!calculateTotalPrice}">
<apex:param name="currSOIPct" value="{!SOI.Id}" assignTo="{!currSOIid}"/>
</apex:actionSupport>
</apex:inputField>
</apex:column>
<apex:column headerValue="Line Disc Amt.">
<apex:inputField value="{!SOI.Line_Discount_Amount__c}" id="fDiscAmt">
<apex:actionSupport event="onchange" rerender="fDiscAmt,fTotalPrice,fProfit,colProfit" action="{!calculateTotalPrice}">
<apex:param name="currSOIPAmt" value="{!SOI.Id}" assignTo="{!currSOIid}"/>
</apex:actionSupport>
</apex:inputField>
</apex:column>
<apex:column headerValue="Profit" id="colProfit" >
<apex:outputField value="{!SOI.Profit__c}" id="fProfit"/>

</apex:column>
<apex:column headerValue="Total Price">
<apex:inputField value="{!SOI.TotalPrice__c}" id="fTotalPrice">
<apex:actionSupport event="onchange" rerender="fDiscAmt,fTotalPrice,fProfit,colProfit" action="{!calculateTotalPrice}">
<apex:param name="currSOIPct" value="{!SOI.Id}" assignTo="{!currSOIid}"/>
</apex:actionSupport>
</apex:inputField>
</apex:column>
<apex:column headerValue="Line Status" >
<apex:outputField value="{!SOI.Line_Status__c }" id="fLineStatus" />
</apex:column>
</apex:pageBlockTable>
</apex:outputPanel>

<!--Dynamic ajax rerender section that depends on above selected values for the table row. TO COMPLETE-->
<apex:outputPanel id="detailBlock">
<apex:dynamicComponent componentValue="{!SOIDetComponent}" />
</apex:outputPanel>

</apex:pageblock>

</apex:form>
</apex:page>

 

 

CONTROLLER CODE: PART OF THE CODE HAS BEEN REMOVED TO SIZE RESTRICTIONS

public class VF_SalesDoc_CreateDoc_Controller_MR {


//custom exceptions
public class SalesOrderItemsException extends Exception {}
public class SalesOrderItemDetailException extends Exception {}

//class variables
private salesOrderManager som; // TODO: MOVE ALL THE CODE RELEVANT TO THIS CLASS: SOQLs, DMLs and getter/setter methods for SO, SOIs and SOIDetails
private SCRB_SalesOrder__c so;
private List<SCRB_SalesOrderLineItem__c> SOIs = new List<SCRB_SalesOrderLineItem__c>();
public List<SCRB_SalesOrderLineItem__c> forDeletion = new List<SCRB_SalesOrderLineItem__c>();
private SCRB_SalesOrderLineItem__c currSOI;
private PriceBookEntry pbEntry;
public List <Sales_Order_Item_Detail__c> SOIDetails;
public Component.Apex.PageBlockSection SOIdetSection;

//page parameters //
private String PageAction;
private String DocType;
private Id accountId;
private Id contactId;
public String mPricebook;

public Account account {get; private set;}
public Opportunity opportunity {get; private set;}

public String getcurrLineType() {
return currSOI.Line_Type__c;
}

public String currSOIid {
get{
return currSOI.id;}
set {
if(value <> null ){
for(SCRB_SalesOrderLineItem__c soi: SOIs) {
if (soi.id == value) {
currSOI = soi;
}
}
} else {
currSOI = null;}
}
}


public PageReference cancel() {
PageReference sop= new ApexPages.StandardController(so).view();
sop.setRedirect(true);
return sop;
}

//**Controller constructor**///////////////////////////////////
public VF_SalesDoc_CreateDoc_Controller_MR() {
//check if its a new action, if so prepopulate fields:
Id id = ApexPages.currentPage().getParameters().get('id');
PageAction = ApexPages.currentPage().getParameters().get('PageAction');
DocType = ApexPages.currentPage().getParameters().get('DocType');
accountId = ApexPages.currentPage().getParameters().get('aId');
contactId = ApexPages.currentPage().getParameters().get('cId');

//create a Sales Order Manager and load new/existing Sales Order
som = new SalesOrderManager();
try{
so = loadSalesOrder(id);
}catch (Exception e) {
ApexPages.addMessages(e);
}
if (PageAction != null) {
if (PageAction == 'New') {
// we arrived from account so we load this account into the header
account = som.loadAccount(accountid);
this.populateSOwithAccount(account);
so.Pricebook__c = 'Standard Price Book';
}
}else {
//if SO exists then load SOIs
SOIs = som.loadSOIs (this.so.id);
for(SCRB_SalesOrderLineItem__c soi: SOIs){
if(soi.Productid__c <> null ) {
Product2 pProd = [Select id, name, ProductCode,Description, IsActive, Unit_Cost__c, Product_Type__c, License_Type__c From Product2 where id = :soi.Productid__c];
PriceBook2 pb = [SELECT Id,IsStandard,Name FROM Pricebook2 WHERE IsStandard = True Limit 1];
pbEntry = [SELECT Id,Pricebook2Id,Product2Id,ProductCode,UnitPrice FROM PricebookEntry WHERE Product2Id = :pProd.Id AND PriceBook2Id = :pb.id Limit 1];
soi.SalesPrice__c = pbEntry.UnitPrice;
soi.Unit_Cost__c = pProd.Unit_Cost__c;
soi.Description__c = pProd.Description;
}
}
}
}
//**end of controller constructor**////////////////////////////

 




//Sales Order Item Detail Methods://////////////////////////////////////

public component.Apex.PageBlockSection getSOIDetComponent () {
return SOIdetSection;
}
public PageReference loadSOIDetComponent() {
//Create teh dynamic component to populate with other components depending on the selected LineType
Component.Apex.PageBlockSection section = new Component.Apex.PageBlockSection (collapsible = True,title = 'Sales Order Item Details: ',showHeader = True);
List<Sales_Order_Item_Detail__c> SOIdets;
system.debug('#### DETCOMP- CurrSOI: ' + currSOI);

if(currSOI <> null) {
//get curr LineType
String lnType = getcurrLineType();
System.debug('#### currLineType: ' + getcurrLineType());
//validate which line type is selected and create the correct components:
if(lnType == 'Course') {
//load the required fields and also component to add contacts(course registrations)
Component.apex.PageBlockSectionItem pbsi = new Component.apex.PageBlockSectionItem ();
List<Schema.FieldSetMember> fs = SObjectType.SCRB_SalesOrderLineItem__c.FieldSets.Courses.getFields();
for(Schema.FieldSetMember f :fs ){
Component.apex.inputField ff = new Component.apex.inputField(value = f.getFieldPath());
section.childComponents.add(ff);
}
SOIdetSection = section;
}else if (lnType == 'Resource'){
SOIdetSection = section;
}else if (lnType == 'Item'){
SOIdetSection = section;
}
}
//it is a new Sales Order and therefore no SOIs loaded, send back null section
return null;
}
}

DavidK.BostonDavidK.Boston

Hi.  Did you ever resolve this problem?  I'm having a similar issue.  I have an <apex:actionSupport> to trigger some controller code when an HTML button is clicked.  I have an <apex:dynamicComponent> in an <apex:outputPanel>.  When I specify a reRender on the actionSupport for the outputPanel, nothing happens.  When I leave out the reRender, the full page refreshes with the correct content.  I'd like to be able to limit the reRender to the outputPanel, since that is the only part of the page that needs to change.

 

Thanks.

 

- David

mauricio.ramosmauricio.ramos

Hi,

 

I cannot recall if I answered to you or not, BUT, here's my take on your issue:

 

1. Can you not use a command:button and call the controller method from the action parameter? Then you also set the reRender parameter to rerender the output panel. This would be the best option.

 

If you still need to use the HTML button then you would need to define an event on the actionsupport (onclick) and call the method from there. In this case I would suggest you enclose the dynamic component in an action region and rerender the output panel.

 

If you can share some of your code then it would be easier to suggest an approach. If not hope my suggestion above will help.

 

 

michael_hymichael_hy

Hi, So far I have an issue about dynamicComponent.
Hope you can spend time on this. Thanks.

http://boards.developerforce.com/t5/Visualforce-Development/Issue-on-apex-dynamicComponent/td-p/551091