1

I need to change the row color depending on the values of a picklist field in a column:

 <apex:pageBlockTable value="{!pagoList}" var="pg">
                <apex:column headerValue="Name">
                    <apex:inputField value="{!pg.Name}" />
                </apex:column>
                <apex:column headerValue="Tipo">
                    <apex:inputField value="{!pg.Tipo__c}" />
                </apex:column>
                  <apex:column headerValue="Otros tipos">
                    <apex:inputField value="{!pg.OtrosTipos__c }" />
                </apex:column>
                <apex:column headerValue="Importe">
                    <apex:inputField value="{!pg.Importe__c}" />
                </apex:column>
                <apex:column headerValue="Forma de Pago">
                    <apex:inputField value="{!pg.FormaPago__c}" />
                </apex:column>
            </apex:pageBlockTable>

This code is rendering this:

enter image description here

being the field 'Tipo__c' the 'type' of object ....

My requirement is to highlight the rows with a color where Tipo__c equals some values in the picklist. Tipo__c is the picklist field.

I've been reading and trying diferent things like this one but nothing seems to work.

This new code:

    <style>
          .greenColour {background-color:green;}
      .redColour {background-color:red;}
      .greyColour {background-color:grey;}  
    </style>
    
    <script>
    var redRow = document.getElementsByClassName("redColour");
    var greenRow = document.getElementsByClassName("greenColour");
    var greyRow = document.getElementsByClassName("greyColour");
    for(var i=0;i<redRow.length;i++){
        redRow[i].parentNode.className = "redColour";
    }
    for(var i=0;i<greenRow.length;i++){
        greenRow[i].parentNode.className = "greenColour";
    } 
    for(var i=0;i<greyRow.length;i++){
        greyRow[i].parentNode.className = "greyColour";
    }        
</script>
    
    <apex:form >
        <apex:pageBlock >
            <apex:pageBlockButtons >
                <apex:commandButton action="{!QuikSave}" value="Guardado rapido"/>
                <apex:commandButton action="{!Save}" value="Guardar"/>
                <apex:commandButton action="{!Cancel}" value="Cancelar"/>                
            </apex:pageBlockButtons>
            <apex:pageBlockSection title="Cuadre">
                <apex:outputField value="{!Cuadre__c.Name}"/>
                <apex:outputField value="{!Cuadre__c.Diferencia__c}"/>
                <apex:outputField value="{!Cuadre__c.ImporteCompra__c}"/>
                <apex:outputField value="{!Cuadre__c.PendienteCobro__c}"/>
            </apex:pageBlockSection>
            
            <apex:pageBlockTable value="{!pagoList}" var="pg">
                <apex:column headerValue="Name">
                    <apex:inputField value="{!pg.Name}" />
                </apex:column>
                
                
                <apex:column value="{!pg.Tipo__c }" 
                             styleClass = "{! If(pg.Tipo__c=='Transferencia' ,'redColour',
                                           If(pg.Tipo__c=='Cheque Bancario Nominativo','greenColour', 'greyColour')) }" />
                
                
                
                <apex:column headerValue="Tipo">
                    <apex:inputField value="{!pg.Tipo__c}" />
                </apex:column>
                  <apex:column headerValue="Otros tipos">
                    <apex:inputField value="{!pg.OtrosTipos__c }" />
                </apex:column>
                <apex:column headerValue="Importe">
                    <apex:inputField value="{!pg.Importe__c}" />
                </apex:column>
                <apex:column headerValue="Forma de Pago">
                    <apex:inputField value="{!pg.FormaPago__c}" />
                </apex:column>
            </apex:pageBlockTable>

is rendering this page:

enter image description here

but the Tipo field is not rendering as it should (a picklist) and also the row is not hightlighting, only the field.

Any idea on how to achieve this ?

1 Answer 1

2

There is no good way to apply CSS to an entire row in a datatable or pageblocktable other than when you want to alternate the CSS class every X rows (for which we have the rowClasses attribute).

You could use the style attribute in every column to achieve the effect you're looking for, but doing that via a merge expression (for each column) does mean that your page takes longer to render. That might not be noticible until you have hundreds of rows, but it is something to keep in mind.

If you have a custom controller or controller extension, having the logic to determine what CSS class to apply be handled in Apex (I'm thinking you'd create a wrapper class to hold your record as well as which css class to apply") may help performance.

Honestly though, the least cumbersome (and most dynamic) approach here would probably be to take care of row coloring through Javascript.

If you use an html passthrough attribute (i.e. an attribute in your <apex:column> tag that's prefixed with html- like html-pickval) you can fairly easily find the element with that attribute (a <td>), and navigate up to the parent (a <tr>, table row). Something like the following:

// This selector finds all td elements with the "pickval" attribute
// Visualforce _should_ strip out the 'html-' part when it renders to html
document.querySelectorAll("td[pickval]").foreach(
    function(element){
        let targetClass;
        switch(element.value){
            case "Transferencia" :
                targetClass = "redColour";
                break;
            case "Cheque Bancario Nominativo" :
                targetClass = "greenColour";
                break;
            default:
                targetClass = "greyColour";
            }
        }

        element.parentNode.classList.add(targetClass);
    }
);

+edit:

Forgot to mention that in your example, the first "Tipo" column (your final example has 2 "Tipo" columns) didn't appear as a picklist because you referenced the field directly in the <apex:column> as opposed to referencing it via <apex:inputField> nested inbetween <apex:column> and </apex:column>.

2
  • 1
    Eventually, it should be possible to do this via CSS alone using the :has() pseudo-class of CSS 4 like tr:has(> td[pickval-red]){ background-color: red;}, but no browsers appear to support that (yet) at time of writing, and it wouldn't work if you want to render as a pdf (flying saucer only supports up to CSS 2.1)
    – Derek F
    Dec 28, 2020 at 16:34
  • Beautiful and complete answer to my question. Thank you very much and very apreciated !!! BEST regards Derek Dec 29, 2020 at 0:28

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .