[SalesForce] How to show fields based on a condition for other field

I want to show 4 custom fields (W__c, X__c, Y__c, Z__c) when other custom field have the following condition:

If RealNumber__c < TargetNumber__c
then show this field:
W__c, X__c, Y__c, Z__c
else
hide this field:
W__c, X__c, Y__c, Z__c

I am using the following APEX code in Visualforce Page, but it doesn't work for me:

<apex:page standardController="CustomObject__c">

<apex:form id="theForm">

  <apex:inputfield value="{!CustomObject__c.RealNumber__c}">
    <apex:actionSupport event="onchange" reRender="theForm" />
</apex:inputField>

  <apex:inputField value="{!CustomObject__c.W__c}" rendered="{!CustomObject__c.RealNumber__c < !CustomObject__c.TargetNumber__c}" />
  <apex:inputField value="{!CustomObject__c.X__c}" rendered="{!CustomObject__c.RealNumber__c < !CustomObject__c.TargetNumber__c}" />
  <apex:inputField value="{!CustomObject__c.Y__c}" rendered="{!CustomObject__c.RealNumber__c < !CustomObject__c.TargetNumber__c}" />
  <apex:inputField value="{!CustomObject__c.Z__c}" rendered="{!CustomObject__c.RealNumber__c < !CustomObject__c.TargetNumber__c}" />


</apex:form>

</apex:page>

David helped me and finally the code is:

<apex:page standardController="CustomObject__c">
<apex:form id="theForm">
 <apex:outputPanel rendered="{!CustomObject__c.RealNumber__c < CustomObject__c.TargetNumber__c}"> 
<apex:inputField value="{!CustomObject__c.W__c}"/> 
<apex:inputField value="{!CustomObject__c.X__c}"/> 
<apex:inputField value="{!CustomObject__c.Y__c}"/> 
<apex:inputField value="{!CustomObject__c.Z__c}"/>
</apex:outputPanel>
</apex:form>
</apex:page>

But when I press the button "Preview" the screen shows me the following error:
The value 'null' is not valid for operator '<'
Error is in expression '{!CustomObject__c.RealNumber__c < CustomObject__c.TargetNumber__c}' in component in page CustomObject__c

What could be the problem ?

Can you help me with this please ?

Best Answer

You've got a syntax error in there:

<apex:inputField value="{!CustomObject__c.W__c}" rendered="{!CustomObject__c.RealNumber__c < !CustomObject__c.TargetNumber__c}" />

should be

<apex:inputField value="{!CustomObject__c.W__c}" rendered="{!CustomObject__c.RealNumber__c < CustomObject__c.TargetNumber__c}" />

Once you're in the expression context, the ! becomes a negation operation. You don't need to and shouldn't prefix each variable reference with that character; you just need it once to mark the beginning of the expression.

There's also a way you can simplify this: use an <apex:outputPanel> (a <div>, essentially) to group the elements, and conditionally render it:

<apex:outputPanel rendered="{!CustomObject__c.RealNumber__c < CustomObject__c.TargetNumber__c}">
    <apex:inputField value="{!CustomObject__c.W__c}" />
    <apex:inputField value="{!CustomObject__c.X__c}" />
    <apex:inputField value="{!CustomObject__c.Y__c}" />
    <apex:inputField value="{!CustomObject__c.Z__c}" />
</apex:outputPanel>

Please also be aware, just for clarity's sake, that none of this is Apex code - it's Visualforce markup. Your controller is written in Apex, if you have a controller.

null Issue

Your Visualforce expression is not valid because one of the fields CustomObject__c.RealNumber__c < CustomObject__c.TargetNumber__c is null. You cannot compare null to an integer value.

You'll need to either make sure the data is valid by populating fields, or enhance your logic to take null into account. You'd do this, for example, by wrapping each field in the BLANKVALUE() formula function, which allows you to substitute a value for null. (See the linked reference for usage details).