[SalesForce] Colored Picklist Values in VF Page

Got scenario where I need to display picklist values coming from a text field values (0,3,5,10…) and when the picklist values are displayed, it should be colored out based on less than 12 would be in green otherwise color it red.

enter image description here

The problem is…

  1. Cannot use the Schema.DescribeFieldResult due to the source of the values is not a picklist value. Is it okay to split it in for-loop? What would be the problem and/or best to do this?
  2. With the split, I’m able to get the values and colored it BUT when displayed I’m getting a blank space. What could be wrong in the code?
  3. The color should retain when the value was picked. Help with the missing code.

CONTROLLER

public List getDiscountList()
{
List discountList = new List();

    List<Product__c> familyDiscount = [SELECT Discount__c FROM Product__c where name =: businessInteraction.TH_Product_Family_Name__c];

    SelectOption option = new SelectOption('0', '<optgroup style="background:#FFFFFF;"></optgroup>');
    option.setEscapeItem(false);
    discountList.add(option);

    for(Product__c p: familyDiscount)
    {
        if(p.Discount__c != NULL)
        {
            string color;
            for(string discounts: pf.Discount__c.split(',',-1))
            {
                if(discounts <='12')
                {
                    color = 'Green';
                }else{
                    color = 'Red';
                }

                SelectOption entry = new SelectOption(discounts,'<option value="' + discounts + '" style="font-weight:bold;color:' + color + ';">' + discounts + '</option>');
                entry.setEscapeItem(false);
                discountList.add(entry);
            }
        }
    } 
    return discountList;
}
VISUALFORCE PAGE

<apex:column>
      <apex:facet name="header">Discount %</apex:facet>    
      <apex:selectList id="Disc" size="1" multiselect="false" value="{!results.Discount}" }">
      <apex:selectOptions rendered="{!allowDiscretionaryDiscountFlag}" value="{!DiscountList}"/>
      </apex:selectList
                                <script>
                                    var entries = document.getElementById("{!$Component.j_id0:form:discDetail:discSection:discountTabTable:1:Disc}").value;
                                    for(var i = entries.length - 1; i>=0; i--){
                                        if(entries.discountList[i].text == ""){
                                           entries.remove(i);
                                        }
                                    }
                                </script>

</apex:column>

Best Answer

Do not use inline styles for this. Instead use CSS.

And don't use JS to remove Options from the Select. Use Apex code.

So the way to do it would be something along these lines:

Page:

<style type="text/css">
.low-discount {
  color: green;
}

.high-discount {
  color: red;
}
</style>

.....

<apex:selectList id="Disc" size="1" multiselect="false" value="{!results.Discount}" }">
  <apex:repeat value="{!discounts}" var="discount">
    <option class="{!discount < 12 ? 'low-discount' : 'high-discount'}">
      {!discount}
    </option>
  </apex:repeat>
</apex:selectList>

And write a controller method getDiscounts that returns a list of numbers that are the discount values. Something like this:

public List<Integer> getDiscounts() {
  //  get data somehow into familyDiscount

  // use a set to make each value unique
  Set<Integer> retVal = new Set<Integer>();
  for (Product__c p: familyDiscount) {
    if (p.Discount__c != null) {
      for (String discount: pf.Discount__c.split(',')) {
        // I guess this is a check you need?
        if (discount != '') {
          // turn the String into an Integer and add it to the set
          retVal.add(Integer.valueOf(discount));
        }
      }
    }
  }
  return new List<Integer>(retVal);
 }
Related Topic