• woot
  • NEWBIE
  • 0 Points
  • Member since 2012

  • Chatter
    Feed
  • 0
    Best Answers
  • 0
    Likes Received
  • 0
    Likes Given
  • 1
    Questions
  • 1
    Replies

Work with some of the smartest people in the world while enjoying over 200 different types of snacks, free meals all day, and upgraded Razor Scooters!

Box is a pre-IPO, hypergrowth company - the fastest growing SaaS company of all time - and we need Salesforce admins! 

You'll be a good fit if you...
- LOVE Salesforce!
- Have a good understanding of the Salesforce data structure
- Know a thing or two about getting Salesforce to do what you actually want it to do!
- Are a US citizen (sorry!)

For more information, please visit our careers page:
https://www.box.com/about-us/careers/open-positions/?jvi=oPFtWfwD,Job

Thanks!
David Liu

  • November 27, 2012
  • Like
  • 0
There were a few times I thought I may have been literally losing my mind trying to isolate this issue but I was finally able to nail down the steps to reproduce (and solution). Sometimes the param value is not being assign to the variable in the controller.

Here is the code to reproduce. I tried to make it as short as possible but sorry it is still a little long, see steps below code:
Code:
Page:

<apex:page controller="paramBug" > <apex:form > <apex:pageBlock > <apex:outputPanel id="table"> {!showTable} <apex:pageBlockTable value="{!opps}" var="o" rendered="{!showTable}"> <apex:column headerValue="Status"> <apex:outputPanel id="oppStatus"> <apex:outputText value="Y" rendered="{!IF(o.status = 'modified', true, false)}"/> </apex:outputPanel> </apex:column> <apex:column value="{!o.opp.Name}"/> <apex:column > <apex:facet name="header"> <apex:commandLink value="Stage" rerender="table,debug" action="{!sortTable}" status="sorting"> <apex:param value="StageName" assignTo="{!sortColumn}" /> </apex:commandLink> </apex:facet> <apex:inputField value="{!o.opp.StageName}"> <apex:actionSupport event="onchange" action="{!change}" rerender="oppStatus,buttons"> <apex:param name="oid" value="{!o.opp.id}" assignTo="{!changedOpp}" /> </apex:actionSupport> </apex:inputField> </apex:column> </apex:pageBlockTable> </apex:outputPanel> </apex:pageBlock> </apex:form> </apex:page>

Controller:

public class paramBug {

List<oppWrapper> opps = new List<oppWrapper>();
List<SelectOption> stages;
public ID changedOpp {get; set;}
public string sortColumn {get; set;}
Map<String,String> sortOrder = new Map<String,String>();

//Constructor
public paramBug(){
for(Opportunity opp : [select Id, Name, StageName from Opportunity limit 10]){
opps.add(new oppWrapper(opp));
}
}

public List<oppWrapper> getOpps(){
return opps;
}

public void change(){
for(oppWrapper o : getOpps()){
if(o.opp.Id == changedOpp){
o.status = 'modified';
}
}
}

public Boolean getShowTable(){
Boolean show = true;
if(opps.size() == 0 ){
show = false;
}
return show;
}

public void sortTable(){
transient List<oppWrapper> sortedOpps = new List<oppWrapper>();
transient Map<String, List<oppWrapper>> stringMap = new Map<String, List<oppWrapper>>();

system.debug('--------------This is the debug line to watch--------------------');
system.debug('sColumn: ' + sortColumn);

if(sortColumn == 'StageName'){
for(oppWrapper o : getOpps()){
Object oField = o.opp.get(sortColumn);
String fieldValue = (String)oField;

if(stringMap.get(fieldValue) == null) {
stringMap.put(fieldValue, new List<oppWrapper>());
}
stringMap.get(fieldValue).add(o);
}

transient List<String> keys = new List<String>(stringMap.keySet());
keys.sort();

for(String key:keys){
sortedOpps.addAll(stringMap.get(key));
}

//reverse order
if(sortOrder.get(sortColumn) == 'asc'){
sortedOpps.clear();
for(Integer i = (keys.size()-1);i >= 0; i--) {
sortedOpps.addAll(stringMap.get(keys.get(i)));
}
}

if(sortOrder.get(sortColumn) == 'asc'){
sortOrder.put(sortColumn,'desc');
}else{
sortOrder.put(sortColumn,'asc');
}

}
system.debug('sortedOpps: ' + sortedOpps);
system.debug('Opps: ' + Opps);
opps = sortedOpps;
}

public class oppWrapper{

public Opportunity opp {get; set;}
public String status {get; set;}

//Contructor
public oppWrapper(Opportunity opp){
this.opp = opp;
}
}
}

First let's show it working correctly:
1) Open up this page and open the System Log.
2) Click the Stage Name header. This passes a param to the variable "sortColumn" in the controller and calls the action method sortTable().
3) Monitoring the debug log you can see that this is correctly being passed over: line 41, column 9: sColumn: StageName

Now let's show it not working:
1) Reload the page.
2) Change the Stage of the first opp in the table. This runs the change() method in the controller and rerenders the contents of the Status column. A 'Y' should appear in the row of the edited opp.
3) Click the Stage header to sort. The table will disappear because the sort logic did not execute. If you look at the system log you can see that the param was not passed to the controller and sortColumn is null: line 41, column 9: sColumn: null

Now the fix. I don't know why or how this fixes it but it does. Simply adding the name attribute to the param component does the trick. It doesn't even matter what the name is, just as long as it is there:

Code:
Change this:
<apex:param value="StageName" assignTo="{!sortColumn}" />

to this:
<apex:param name="asdfasd" value="StageName" assignTo="{!sortColumn}" />

and it works.

So there you go. I'm pretty sure this is a bug but if it's not I'll modify the title.

-Jason




Message Edited by TehNrd on 01-16-2009 12:04 PM
  • January 16, 2009
  • Like
  • 1