+ Start a Discussion
willardwillard 

pageBlockTable - change values on only ONE row

Hi.  I have a pageBlockTable with two columns:  Edition Type (picklist) and Edition Code (selectList).  Based on the Edition Type, the Edition Code field will populate with different SelectOptions.  If the editionType changes, the editionCode field will re-populate accordingly.

 

I am currently unsure on how I am supposed to know which row in the table caused the action, i.e., if there are 3 rows, how do I know to change only row #2?  Any ideas on how I would figure that out?

            <apex:pageBlockTable value="{!editions}" var="edn" id="editionTable">
                <apex:column headerValue="Edition Type">
                	<apex:inputField value="{!edn.Edition_Type__c}">
                		<apex:actionSupport event="onchange" rerender="pricingDetails"/>
                    </apex:inputField>
                </apex:column>
                <apex:column headerValue="Edition Code">
                    <apex:pageBlockSectionItem >
		                <apex:selectList value="{!edn.Edition_Code__c}" id="editionCode" size="1">
		                    <apex:selectOptions value="{!editionCodes}"/>
		                </apex:selectList>
		            </apex:pageBlockSectionItem>
                </apex:column>
            </apex:pageBlockTable>

 controller:  In the select statement, I need another clause in the Where portion of the statement, i.e.

WHERE b.publication__c = :pricing.business_unit__c AND b.editionType__c = ?????????

    public List<SelectOption> getEditionCodes() {
        List<BossEdition__c > editions = [Select b.editionCode__c, b.Name from BossEdition__c b 
        			where b.publication__c = :pricing.business_unit__c 
order by b.Name]; List<SelectOption> options = new List<SelectOption>(); for (BossEdition__c edn : editions) { options.add(new SelectOption(edn.editionCode__c, edn.Name + ' (' + edn.editionCode__c + ')')); } return options; }

 

Best Answer chosen by Admin (Salesforce Developers) 
bob_buzzardbob_buzzard

ChosenEdnType doesn't appear to exist in the page, so I wouldn't expect the setter to be called to be honest.  You have backed the input field with edn.Edition_Type__c, so that will be updated for the record in question when the page is submitted.

 

There's a bigger problem though - your dependent picklist, the Edtion Code, only has a single getEditionCodes method to call.  You can't make that getter react to the element of the list that you are processing I'm afraid (not reliably in my experience anyway).  I think you'll need to create a wrapper class that contains the edtion object and its associated list of select options.

 

If you do that I think you can probably do without the apex param.  Once the actionsupport fires, the Edition_Type__c of the record in the list will be updated.  In your action method you can spin through the list and ensure the the associated selectoptions are correct for the edition record.

All Answers

bob_buzzardbob_buzzard

You'd normally use the apex:param component to pass an identifier for the row back to the controller.

 

I wrote a blog post on this a little while ago:

 

http://bobbuzzard.blogspot.com/2011/07/passing-parameters-to-apex-method-from.html

 

if you don't have a unique identifier for the row available, a later blog post shows how to create a wrapper class that combines the data with an id number:

 

http://bobbuzzard.blogspot.com/2011/07/managing-list-of-new-records-in.html

 

Hopefully these should get you started.

willardwillard

Hey Bob,

Thanks for the links.  Unfortunately, those don't seem to be working for me.  Here's my code, but when I put some debug statements into my controller, it seems like the setter isn't even being called.  Here's the VF page it is:

<apex:pageBlockTable value="{!editions}" var="edn" id="editionTable">
                <apex:column headerValue="Edition Type">
                	<apex:inputField value="{!edn.Edition_Type__c}">
                		<apex:actionSupport event="onchange" rerender="pricingDetails">
                			<apex:param value="{!edn.Edition_Type__c}" name="chosenEdnType" assignTo="{!chosenEdnType}"/>
                		</apex:actionSupport>
                    </apex:inputField>
                </apex:column>
                <apex:column headerValue="Edition Code">
                    <apex:pageBlockSectionItem >
		                <apex:selectList value="{!edn.Edition_Code__c}" id="editionCode" size="1">
		                    <apex:selectOptions value="{!editionCodes}"/>
		                </apex:selectList>
		            </apex:pageBlockSectionItem>
                </apex:column>
            </apex:pageBlockTable>

 Here's snippets of code from controller:

// setter
public string chosenEdnType {
    	get;
    	set {
    		chosenEdnType = value;
    		System.debug('set:' + chosenEdnType);
    	}
    }

    public List<SelectOption> getEditionCodes() {
    	
    	System.debug('chosenEdnType: ' + chosenEdnType);
    	
        List<BossEdition__c > editions = [Select b.editionType__c, b.editionCode__c, b.Name from BossEdition__c b 
        			where b.publication__c = :pricing.business_unit__c 
        			and b.editionType__c = :chosenEdnType)
                    order by b.Name];
        List<SelectOption> options = new List<SelectOption>();
       
        for (BossEdition__c edn : editions) {
            options.add(new SelectOption(edn.editionCode__c, edn.Name + ' (' + edn.editionType__c + ')'));
        }

        return options;
    }

the debug log never shows the setter debug and the chosenEdnType debug is always null.  Therefore no selectOptions are displayed.

 

When I try to replace the query with using this:

and b.editionType__c = :ApexPages.currentPage().getParameters().get('chosenEdnType')

 Then it will take the PREVIOUS editionType and populate the selectList.  I.e., if I choose editionType "Custom", and then choose the editionType "Metro", then the selectList will show editions of editionType 'Custom'.  If I change the editionType one more time to 'Custom', then the selectList will show editions of 'Metro'.  Perhaps something is wrong wth my code?

bob_buzzardbob_buzzard

ChosenEdnType doesn't appear to exist in the page, so I wouldn't expect the setter to be called to be honest.  You have backed the input field with edn.Edition_Type__c, so that will be updated for the record in question when the page is submitted.

 

There's a bigger problem though - your dependent picklist, the Edtion Code, only has a single getEditionCodes method to call.  You can't make that getter react to the element of the list that you are processing I'm afraid (not reliably in my experience anyway).  I think you'll need to create a wrapper class that contains the edtion object and its associated list of select options.

 

If you do that I think you can probably do without the apex param.  Once the actionsupport fires, the Edition_Type__c of the record in the list will be updated.  In your action method you can spin through the list and ensure the the associated selectoptions are correct for the edition record.

This was selected as the best answer
willardwillard

not sure what you mean by chosenEdnType not being on the page.  Shouldn't the param tag I have set chosenEdnType with the value of edition_type__c for that row?:

 

    <apex:inputField value="{!edn.Edition_Type__c}">
                        <apex:actionSupport event="onchange" rerender="pricingDetails">
                            <apex:param value="{!edn.Edition_Type__c}" name="chosenEdnType" assignTo="{!chosenEdnType}"/>
                        </apex:actionSupport>
                    </apex:inputField>

 

 

I will try the wrapper class, but I am still unsure why the setter method is not being called in this case.

bob_buzzardbob_buzzard

Doh! That line broke over two lines so I didn't spot the bit below and left :)

 

You are correct, the param should be passed through.  Do you have any required fields elsewhere in the page? If you are rerendering a small section its easy to lose error messages.  Its worth adding an apex:pageMessages component and re-rendering that also, to exclude that from investigation if for no other reason.

willardwillard

Thanks Bob,

I can't figure out why the editionCode is not refreshing correctly with the param tag, but I did try the wrapper class and that works like a charm.  Thanks for all your help!

Rahul SherikarRahul Sherikar
Hi willard,
I'm new to salesforce and having same kind of problem.Can you plz post the code of wrapper class.
Thank you.