Tell me more ×
Salesforce Stack Exchange is a question and answer site for Salesforce administrators, implementation experts, developers and anybody in-between. It's 100% free, no registration required.

I've reduced my issue to the following example:

<apex:page >
  <apex:variable var="blank" value="" />
  <p> Contains(blank, 'foo'): <apex:outputText value="'TRUE'" rendered="{!CONTAINS(blank, 'foo')}" /></p>
  <p> Not(Contains(blank, 'foo')): <apex:outputText value="'TRUE'" rendered="{!NOT(CONTAINS(blank, 'foo'))}" /></p>
  <p> NULLVALUE(blank, 'x'): <apex:outputText value="{! NULLVALUE(blank,'XXXXX')}" /></p>
  <p> BLANKVALUE(blank, 'x'): <apex:outputText value="{! BLANKVALUE(blank,'XXXXX')}" /></p>
  <p> ISBLANK(blank, 'x'): <apex:outputText value="{! ISBLANK(blank)}" /></p>
</apex:page>

Which produces:

Contains(blank, 'foo'):'TRUE'
Not(Contains(blank, 'foo')):'TRUE'
NULLVALUE(blank, 'x'):
BLANKVALUE(blank, 'x'):
ISBLANK(blank, 'x'):false

How can Contains(blank, 'foo') and Not(Contains(blank, 'foo')) both return true? Why doesn't BLANKVALUE or ISBLANK recognize the var blank as being blank?

I took this a step further, and created this controller:

public class formulaTestController {
  public string getNullValField() { return null;}
  public string getBlankValField() {return ''; }
}

If I add this controller to the page and change the variable to <apex:variable var="blank" value="{!blankValField}" />, I get the same results as above. If I change it to <apex:variable var="blank" value="{!nullValField}" />, I get this:

Contains(blank, 'foo'):'TRUE'
Not(Contains(blank, 'foo')):'TRUE'
NULLVALUE(blank, 'x'):XXXXX
BLANKVALUE(blank, 'x'):XXXXX
ISBLANK(blank, 'x'):true 

So it appears that BLANKVALUE and ISBLANK really operate on nulls, but not on blanks. Is this expected? Especially w/r/t BLANKVALUE, as NULLVALUE also exists. And why do the Contains() and (Not(Contains()) tests still produce the same result?!

In the end, I need to reliably handle a controller value that may be blank or null, treating these as special cases in my VF logic. How can I do so?

EDIT: Per suggested answer, I tried wrapping Contains test in IF(). Note that I moved the formula into outputText's Value to make the result explicit:

<apex:page >
  <apex:variable var="blank" value="" />
  <p> IF(CONTAINS(blank, 'foo'),true, false): <apex:outputText value="{!IF(CONTAINS(blank, 'foo'),true, false)}" /></p>
  <p> IF(NOT(CONTAINS(blank, 'foo')),true, false): <apex:outputText value="{!IF(NOT(CONTAINS(blank, 'foo')),true, false)}" /></p>
  <p> IF(CONTAINS(blank, 'foo'),'true', 'false'): <apex:outputText value="{!IF(CONTAINS(blank, 'foo'),'true', 'false')}" /></p>
  <p> IF(NOT(CONTAINS(blank, 'foo')),'true', 'false'): <apex:outputText value="{!IF(NOT(CONTAINS(blank, 'foo')),'true', 'false')}" /></p>
</apex:page>

No change:

IF(CONTAINS(blank, 'foo'),true, false):false
IF(NOT(CONTAINS(blank, 'foo')),true, false):false
IF(CONTAINS(blank, 'foo'),'true', 'false'):false
IF(NOT(CONTAINS(blank, 'foo')),'true', 'false'):false
share|improve this question

3 Answers

When I changed the page to be this i.e. 1) change var to be a blank field on Account and 2) AND the output of CONTAINS with TRUE, it seems to work as expected:

  <apex:page standardController="Account">
  <apex:variable var="blank" value="{!Account.Fax}" />
  <p> Contains(blank, 'foo'): <apex:outputText value="'TRUE'" rendered="{! TRUE && CONTAINS(blank, 'foo')}" /></p>
  <p> Not(Contains(blank, 'foo')): <apex:outputText value="'TRUE'" rendered="{! TRUE && NOT(CONTAINS(blank, 'foo'))}" /></p>
  <p> NULLVALUE(blank, 'x'): <apex:outputText value="{! NULLVALUE(blank,'XXXXX')}" /></p>
  <p> BLANKVALUE(blank, 'x'): <apex:outputText value="{! BLANKVALUE(blank,'XXXXX')}" /></p>
  <p> ISBLANK(blank, 'x'): <apex:outputText value="{! ISBLANK(blank)}" /></p>
</apex:page>

I have a feeling that the functions are attuned to working with sObject fields rather than a dynamic variable (or even if a variable, at least initialised to an sObject field) in Visualforce.

Contains(blank, 'foo'):

Not(Contains(blank, 'foo')):

NULLVALUE(blank, 'x'):XXXXX

BLANKVALUE(blank, 'x'):XXXXX

ISBLANK(blank, 'x'):true

So its almost as if the output of CONTAINS is somehow messing up, although it seems to be alright after you AND it with TRUE, which in essence is just transparent and lets the actual value of it pass through.

share|improve this answer
On the use of TRUE && Contains(...): I don't see how this changes anything; in your example both Contains() and Not(Contains()) tests still return the same result. I tried adding it to a number of my test variations; it doesn't appear to change the result. On the use of Account.fax: a quick anonymous Apex test proves that when Account.fax is "blank", it is null. So I still believe that ISBLANK and ISNULL are identical, and only operate on Nulls, not blanks (which to my mind should include empty string). – Jason Clark Nov 19 '12 at 14:14
{!IF(CONTAINS(adjustmentType,'Inventory Count'),'true','false')}

As far as Contains function is concerned ,I usually use with If function with contains here and explicitly assign true and false and it works for me .

share|improve this answer
This doesn't appear to work correctly if (in your example) adjustmentType is blank, that is, empty string. I've appended the original question with the results, using both quoted and unquoted true/false values. No improvement. – Jason Clark Nov 14 '12 at 16:51
1  
The IF function is superfluous, since the condition of the IF already evaluates to either True or False. {!IF(condition, True, False)} isn't any different than just {!condition}. – tomlogic Feb 2 at 5:48

This is actually an issue with your use of <apex:variable>. According to the documentation, the value parameter is supposed to refer to an object. Think of it more as an alias than anything else, to simplify your later references. For example, after <apex:variable var="r" value="{!Custom_Object__c.Related_Object__r}"/>, you can easily refer to fields r.foo, r.bar and r.baz.

So, in your example, the blank alias is failing, so trying to use it in other functions leads to inconsistent results.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.