+ Start a Discussion
LAMCORPLAMCORP 

VForce pages are not writing blank values to the database!

Dear all,

 

Hoping someone can help. I have written a VF page that has input fields.The issue that when there is data in a field and then wanting to enter a blank value, the changes are not written to the database.

 

Does anyone know if this a common issue or is there a solution to this?

 

 

 

<apex:page standardController="Electricity_Meter__c" recordSetVar="ElecMeters" tabStyle="Electricity_Meter__c" sidebar="false">

<style>
    body {font-family: Arial Unicode MS;}
    h1 {color:black;font-size: 20px;text-decoration: none}
</style>
    <p><h1> Logging Table - Elec Meter(s) </h1></p><p></p>  
    <apex:form >
        
        <apex:pageblock >
        <apex:pageMessage summary="Validation error" severity="warning" strength="3" />
        <apex:pageMessages />
                
        <apex:pageBlockButtons >        
            <apex:commandButton value="Save" action="{!save}" reRender="resultBlock"/>
            <apex:commandButton value="Cancel" action="{!cancel}"/>            
        </apex:pageBlockButtons>
        
                <apex:pageBlockTable value="{!selected}" var="elecM">
                
                    <apex:column value="{!elecM.name}"/>
                    <apex:column value="{!elecM.Site_Address2__c}"/>
                    <apex:column value="{!elecM.Meter_Details__c}"/>
                    
                    <apex:column headerValue="Winning Supplier">
                    <apex:inputField value="{!elecM.Winning_Supplier__c}"/>
                    </apex:column>
                                      
                    <apex:column headerValue="Commission (p/kwh)">
                    <apex:inputField value="{!elecM.Required_Commision_p_kwh__c}"/>
                    </apex:column>                    
                    
                    <apex:column headerValue="Commission (£/year))">
                    <apex:inputField value="{!elecM.Required_Commision_Contract__c}"/>
                    </apex:column>
                    
                    <apex:column headerValue="Commission (%/Contract)">
                    <apex:inputField value="{!elecM.Required_Commision_Contract_Spend__c}"/>
                    </apex:column>
                                       
                    <apex:column value="{!elecM.AQ__c}"/>
                    <apex:column headerValue="Annual Consumption as contract">
                    <apex:inputField value="{!elecM.Renw_Contract_Consumption__c}"/>
                    </apex:column>
                    
                    <apex:column headerValue="Start Date">
                    <apex:inputField value="{!elecM.Required_contract_start_date__c}"/>
                    </apex:column>
                    
                    <apex:column headerValue="End Date">
                    <apex:inputField value="{!elecM.Required_contract_end_date_1__c}"/>
                    </apex:column>
                                        
                    <apex:column headerValue="TL Check)">
                    <apex:inputField value="{!elecM.TL_Logging_Check__c }"/>
                    </apex:column>
                                        
                </apex:pageBlockTable>
        </apex:pageBlock>
    
    </apex:form>
</apex:page>

Best Answer chosen by Admin (Salesforce Developers) 
Pat PattersonPat Patterson

Hi Alan,

 

Combining the example controller I posted with its test method, the result is:

 

public class inputnulls { 
  ApexPages.StandardSetController mycon; 
  public List<Opportunity> Selectedopportunities {get; set;} 
  ID accId{get;set;} 

  public inputnulls(ApexPages.StandardSetController controller) { 
    accId = ApexPages.currentPage().getParameters().get('id'); 
    mycon = controller; 
    Selectedopportunities = mycon.getSelected(); 
  } 

  public PageReference mySave() { 
    mycon.save(); 
    PageReference pageRef = new PageReference( '/' + accId); 
    return pageRef ; 
  } 

  public static testMethod void testInputNulls() {
    List<Opportunity> opps = new List<Opportunity>();
        
    for(Integer i=0;i<10;i++) {
      opps.add(new Opportunity(Name = 'TEST' + i, StageName = 'Prospecting', CloseDate = Date.today().addMonths(1)));
    }
        
    insert opps;
        
    ApexPages.StandardSetController con = new ApexPages.StandardSetController(opps);
    con.setSelected(opps);
    inputnulls ext = new inputnulls(con);
        
    Test.startTest();
    PageReference ref = ext.mySave();
    Test.stopTest();
        
    System.assertNotEquals(null, ref);
    // Add whatever other assertions make sense for your logic
  }
} 

 

I just pasted this into the developer console and it works great.

 

Cheers,


Pat

All Answers

Suresh RaghuramSuresh Raghuram

please check with your field validations if the field is required or some other validation  associated with it,

 

This may be possible or not . I am not 100% sure 

 

Try this since your Vf page is not having controller.

 

Lets check the page flow by writing the java script alerts, place a java script alert after every field and chek weather the control passing through the field or not.

 

I

LAMCORPLAMCORP

Hi,

 

Thanks for the reply.

 

I have this morning run a test from a cookbook example to make sure that it is not something I have missed in the code.
http://developer.force.com/cookbook/recipe/editing-multiple-records-using-a-visualforce-list-controller


Because the example provided uses required fields (not allowing blank values), I have added a custom field utility__c. The only difference between the 2 codes below is that I have replaced the

<apex:pageBlockTable value="{!opportunities}"

with

<apex:pageBlockTable value="{!selected}"

to allow me select from a related multi select list with checkboses. The first code works fine and allows me to write a "NONE" (blank from picklist) value and writes it to the database. As soon as I changed the code and created a multi select related list button. The "NONE" (blank from picklist) value is ignored when hitting save.

 

I changed the code from:
<apex:page standardController="Opportunity"
               recordSetVar="opportunities"
               tabStyle="Opportunity" sidebar="false">
      <apex:form >
        <apex:pageBlock >
          <apex:pageMessages />
          <apex:pageBlockButtons >
            <apex:commandButton value="Save"
                                action="{!save}"/>
          </apex:pageBlockButtons>
          <apex:pageBlockTable value="{!opportunities}"
                                            var="opp">
            <apex:column value="{!opp.name}"/>
            <apex:column headerValue="Stage">
              <apex:inputField value="{!opp.stageName}"/>
            </apex:column>
            <apex:column headerValue="Close Date">
              <apex:inputField value="{!opp.closeDate}"/>
            </apex:column>
                <apex:column headerValue="Utility">
            <apex:inputField value="{!opp.Utility__c}"/>
          </apex:column>
          </apex:pageBlockTable>     
        </apex:pageBlock>
      </apex:form>
    </apex:page>

To (For use with a related list button and selected items):
<apex:page standardController="Opportunity"
             recordSetVar="opportunities"
             tabStyle="Opportunity" sidebar="false">
    <apex:form >
      <apex:pageBlock >
        <apex:pageMessages />
        <apex:pageBlockButtons >
          <apex:commandButton value="Save"
                                             action="{!save}"/>
        </apex:pageBlockButtons>
        <apex:pageBlockTable value="{!selected}"
                                          var="opp">
          <apex:column value="{!opp.name}"/>
          <apex:column headerValue="Stage">
            <apex:inputField value="{!opp.stageName}"/>
          </apex:column>
          <apex:column headerValue="Close Date">
            <apex:inputField value="{!opp.closeDate}"/>
          </apex:column>
            <apex:column headerValue="Utility">
            <apex:inputField value="{!opp.Utility__c}"/>
          </apex:column>
        </apex:pageBlockTable>     
      </apex:pageBlock>
    </apex:form>
  </apex:page>

 

You can easily test my examples above by just creating a custom field called utility__c.

 

I also happy to try a Javascript alerts, do you have any examples that I can use?

Pat PattersonPat Patterson

Hi LAMCORP - I see the same as you do with a custom list button and 'selected' in the PageBlockTable. I'm investigating whether this is expected behavior, and/or there is a workaround for you. I'm out for the rest of this week, but, if I don't turn anything up by end of day today, someone else will reply.

LAMCORPLAMCORP

Hi Pat,

 

I understand that Carl Dempsey has been in touch.

 

Your assistance is much appreciated as this has been a long standing issue for us.

 

I'm not sure if this information is relevant or even matters but something that a developer asked a few weeks back was why we had:

 

recordSetVar="opportunities"         

and

<apex:pageBlockTable value="{!selected}"

 

For your info, when recordSetVar="selected" then the selected / checked functionality is ignored. Instead of pulling the selected / checked items, the VF page seems to return 20 random results in the system.

 

 

LAMCORPLAMCORP

Hi Pat,

 

Hope all is well.

 

Wondered if you there has been any progress with this one?

 

Kind Regards,

 

Alan

Pat PattersonPat Patterson

Hi Alan,

 

I have reproduced your issue, but I have not been able to find a workaround. As far as I can see, it's a bug.

 

Please open a case with support.

 

Cheers,

 

Pat

Pat PattersonPat Patterson

Hi Alan,

 

Word from support:

 

<apex:pageBlockTable value="{!selected}" ...

getSelected() is a method however we are expecting a class property here, as it's not a property we are not setting this on the POST back and hence the value will be null. 


Then when a user tries to make a value null it will not be set as we have internal code that checks if the values have not been changed and since we never posted the value because it's not a property nothing will be changed. 

The correct way to do this is as follows: 

Page: 
========= 

<apex:page standardController="Opportunity" extensions="inputnulls" recordSetVar="Selectedopportunities"> 
  <apex:form > 
    <apex:pageBlock > 
      <apex:pageBlockButtons > 
        <apex:commandButton value="Save" action="{!mySave}"/> 
      </apex:pageBlockButtons> 
      <apex:pageBlockTable value="{!Selectedopportunities}" var="opp"> 
        <apex:column headerValue="Test_blank_field__c"> 
          <apex:inputField value="{!opp.Test_blank_field__c}"/> 
        </apex:column> 
      </apex:pageBlockTable> 
    </apex:pageBlock> 
  </apex:form> 
</apex:page> 

 

Controller: 
=========== 

public class inputnulls { 
  ApexPages.StandardSetController mycon; 
  public List<Opportunity> Selectedopportunities {get; set;} 
  ID accId{get;set;} 

  public inputnulls(ApexPages.StandardSetController controller) { 
    accId = ApexPages.currentPage().getParameters().get('id'); 
    mycon = controller; 
    Selectedopportunities = mycon.getSelected(); 
  } 

  public PageReference mySave() { 
    mycon.save(); 
    PageReference pageRef = new PageReference( '/' + accId); 
    return pageRef ; 
  } 
} 

Hope this works for you!

 

Cheers,

 

Pat

LAMCORPLAMCORP

Hi Pat,

 

Sorry the delayed response. I have been hols. 

 

Thanks for the follow up. 

 

I will give it a shot and come back if any issues.

 

In the meantime do you / support have any idea of how to write the test for this?

 

Alan

 

 

Pat PattersonPat Patterson

Hi Alan,

 

This will get you 100% coverage. You can add more assertions to suit the real business logic.

 

  public static testMethod void testInputNulls() {
        List<Opportunity> opps = new List<Opportunity>();
        
        for(Integer i=0;i<10;i++) {
            opps.add(new Opportunity(Name = 'TEST' + i, StageName = 'Prospecting', CloseDate = Date.today().addMonths(1)));
        }
        
        insert opps;
        
        ApexPages.StandardSetController con = new ApexPages.StandardSetController(opps);
        con.setSelected(opps);
        InputNullsController ext = new InputNullsController(con);
        
        Test.startTest();
        PageReference ref = ext.mySave();
        Test.stopTest();
        
        System.assertNotEquals(null, ref);
        // Add whatever other assertions make sense for your logic
    }

 Cheers,

 

Pat

LAMCORPLAMCORP

Thanks Pat.

 

Great help and much appreciated. I will give this a shot and let you know if I have any issues.

 

Alan

LAMCORPLAMCORP

Hi Pat,

 

I have tried the VF controller and adjusted it to requirements and it seems to be working well thanks.

I am now trying to use the test for the VF controller you have provided and have read that the test should be included in the VF controller.

I keep getting an errors when trying to include the test in the controller.

Are you able to advise or send me how it should look.. some examples etc?

Many thanks

 

Alan

 

Pat PattersonPat Patterson

Hi Alan,

 

Combining the example controller I posted with its test method, the result is:

 

public class inputnulls { 
  ApexPages.StandardSetController mycon; 
  public List<Opportunity> Selectedopportunities {get; set;} 
  ID accId{get;set;} 

  public inputnulls(ApexPages.StandardSetController controller) { 
    accId = ApexPages.currentPage().getParameters().get('id'); 
    mycon = controller; 
    Selectedopportunities = mycon.getSelected(); 
  } 

  public PageReference mySave() { 
    mycon.save(); 
    PageReference pageRef = new PageReference( '/' + accId); 
    return pageRef ; 
  } 

  public static testMethod void testInputNulls() {
    List<Opportunity> opps = new List<Opportunity>();
        
    for(Integer i=0;i<10;i++) {
      opps.add(new Opportunity(Name = 'TEST' + i, StageName = 'Prospecting', CloseDate = Date.today().addMonths(1)));
    }
        
    insert opps;
        
    ApexPages.StandardSetController con = new ApexPages.StandardSetController(opps);
    con.setSelected(opps);
    inputnulls ext = new inputnulls(con);
        
    Test.startTest();
    PageReference ref = ext.mySave();
    Test.stopTest();
        
    System.assertNotEquals(null, ref);
    // Add whatever other assertions make sense for your logic
  }
} 

 

I just pasted this into the developer console and it works great.

 

Cheers,


Pat

This was selected as the best answer
LAMCORPLAMCORP

Thanks Pat.. Very helpful.

 

I have altered the code to our requirements but getting an error

 

"Error: inputnulls Compile Error: Invalid type: InputNullsController at line 28 column 36". Code as below.

 

Another q, Once able to save the controller and test would I run the test via "Test Execution"?

I am using the browser to code and not the developer console.

 

public class inputnulls {
  ApexPages.StandardSetController mycon;
  public List<Electricity_Meter__c> Selectedopportunities {get; set;}
  ID accId{get;set;}

  public inputnulls(ApexPages.StandardSetController controller) {
    accId = ApexPages.currentPage().getParameters().get('id');
    mycon = controller;
    Selectedopportunities = mycon.getSelected();
  }

  public PageReference mySave() {
    mycon.save();
    PageReference pageRef = new PageReference( '/' + 'a0J/o' );
    return pageRef ;
  }
  public static testMethod void testInputNulls() {
    List<Electricity_Meter__c> opps = new List<Electricity_Meter__c>();
        
    for(Integer i=0;i<10;i++) {
      opps.add(new Electricity_Meter__c(Name = 'TEST' + i, Linked_Account__c = '001Q000000Vx5HO'));
    }
        
    insert opps;
        
    ApexPages.StandardSetController con = new ApexPages.StandardSetController(opps);
    con.setSelected(opps);
    InputNullsController ext = new InputNullsController(con);
        
    Test.startTest();
    PageReference ref = ext.mySave();
    Test.stopTest();
        
    System.assertNotEquals(null, ref);
    
  }
}

LAMCORPLAMCORP

And to save potentially making a mess.. I have left all variable names the same EG Opps, con etc

Pat PattersonPat Patterson

Hi Alan - my bad - copy/paste error putting the code together - I just edited my example above - it should be right now.

 

Yes - you can run the test via 'Apex Test Execution'.

 

Cheers,


Pat

LAMCORPLAMCORP

Hi Pat,

 

thanks but I don't see any code in your last post.

LAMCORPLAMCORP

Hi Pat,

 

Happy new year and hope you are well.

 

Are you able to point me in the right direction of the code as I could not see any added in your last post.

 

Many thanks Alan

Pat PattersonPat Patterson

Hi Alan - the code is in my earlier message (#13 in the discussion), at http://boards.developerforce.com/t5/Visualforce-Development/VForce-pages-are-not-writing-blank-values-to-the-database/m-p/544085#M58289

 

That code originally had a bug, which caused the error you reported in message #14; I went back and corrected the code in message #13.

 

Cheers,


Pat

LAMCORPLAMCORP

Hi Pat,

 

Just to let you know I finally got this one into production. 

 

Thanks very much for your time and assistance to get this one resolved. 

 

Regards Alan 

Pat PattersonPat Patterson

Good to know - thanks for the confirm, Alan!