You need to sign in to do that
Don't have an account?
MayTheForceBeWithYou
Custom save method only saves certain fields
I've created a Visualforce edit page with a custom save method and a custom save&new method. Unfortunately it seems only some of my fields are saved while others are not. I've read a few posts about this but unfortunately none of the solutions worked for me-any help you can provide would be greatly appreciated, thanks!
VFPage:
<apex:page standardController="Janela_de_Acesso__c" extensions="JDABPEdit" sidebar="false"> <apex:sectionHeader title="Janela de Acesso"/> <apex:form > <div align="center"> <apex:messages styleClass="errorMsg"/> </div> <apex:pageBlock > <apex:pageBlockButtons > <apex:commandButton action="{!SaveRecord}" value="Salvar"/> <apex:commandButton action="{!SaveAndNew}" value="Salvar & Nova"/> <apex:commandButton action="{!Cancel}" value="Cancelar"/> </apex:pageBlockButtons> <apex:pageBlockSection title="Informações" columns="2"> <apex:inputField value="{!Janela_de_Acesso__c.Name}"/> <apex:inputField required="true" value="{!Janela_de_Acesso__c.Data_Inicial__c}"/> <apex:inputField required="true" value="{!Janela_de_Acesso__c.Status__c}"/> <apex:inputField required="true" value="{!Janela_de_Acesso__c.Data_Final__c}"/> </apex:pageBlockSection> <apex:pageBlockSection title="Membros da Janela de Acesso" columns="1"> <apex:panelGrid columns="3" cellpadding="5px"> <apex:pageBlockSectionItem labelStyle="vertical-align: middle" > <apex:outputLabel value="Pesquisa:" for="SearchList"/> <apex:selectList title="Pesquisa" size="1" id="pesquisa" onchange="searchServer(this.options[this.selectedIndex].text);"> <apex:selectOptions value="{!items}"/> <apex:actionFunction immediate="true" name="searchServer" action="{!runSearch}" reRender="Available,Over"> <apex:param assignTo="{!sObjectDesc}" name="pesq" value="" /> </apex:actionFunction> </apex:selectList> </apex:pageBlockSectionItem> <apex:pageBlockSectionItem labelStyle="vertical-align: middle"> <apex:outputLabel value="para:" for="SearchBox"/> <apex:inputText id="SearchBox" value="{!searchText}"/> </apex:pageBlockSectionItem> <apex:commandButton action="{!runSearch}" reRender="Available,Over" value="Pesquisar"/> </apex:panelGrid> <apex:outputPanel id="Over"> <apex:outputText rendered="{!overMax}" value="A consulta retornou mais de 100 registros. Somente as 100 primeiras linhas são exibidas. Por favor, refine os critérios da busca." style="text-align:center;color:red"/> </apex:outputPanel> <apex:panelGrid columns="3" style="text-align: center; vertical-align: middle;"> <apex:panelGroup style="padding-right:3px;align:center"> <apex:outputLabel value="Membros Disponíveis" style="font-weight:bold"/> <br/> <apex:selectList title="Membros Disponíveis" multiselect="true" size="14" required="false" id="Available" value="{!selected}"> <apex:selectOptions value="{!searchResults}"/> </apex:selectList> </apex:panelGroup> <apex:panelGroup > <br/> <br/> <br/> <br/> <br/> <br/> <br/> <br/> <apex:outputLabel value="Adicionar"/> <br/> <apex:commandButton action="{!DoSelect}" value=">>" rerender="Available,Selected"/> <br/> <apex:commandButton action="{!DoUnselect}" value="<<" rerender="Available,Selected"/> <br/> <apex:outputLabel value="Excluir"/> </apex:panelGroup> <apex:panelGroup style="align:center;"> <apex:outputLabel value="Membros Selecionados" style="font-weight:bold"/> <br/> <apex:selectList title="Membros Selecionados" multiselect="true" size="14" required="false" id="Selected" value="{!unselected}"> <apex:selectOptions value="{!selectResults}"/> </apex:selectList> </apex:panelGroup> </apex:panelGrid> </apex:pageBlockSection> </apex:pageBlock> </apex:form> </apex:page>
Controller:
public class JDABPEdit { // the soql without the order and limit private String soql {get;set;} // the collection of contacts to display public List<sObject> results {get;set;} public Boolean overMax=false; public String searchObject; public Janela_de_Acesso__c j; public Janela_de_Acesso__c l; public List<SelectOption> searchResult = new List<SelectOption>(); public List<SelectOption> selectResult = new List<SelectOption>(); public String searchText {get;set;} public String sObjectDesc {get;set;} public List<String> selected {get; set;} public List<String> unselected {get; set;} //Constructor to apply fields public JDABPEdit(ApexPages.StandardController controller) { l = (Janela_de_Acesso__c) controller.getRecord(); j = [SELECT Id, Name, Status__c, Data_Inicial__c, Data_Final__c, sObjectIds__c, sObjectDesc__c from Janela_de_Acesso__c WHERE Id = :l.Id]; List<String> sobjectIdList = new List<String>(); List<String> sobjectDescList = new List<String>(); for (String k : j.sObjectIds__c.split(';',0)){ sobjectIdList.add(k); } for (String m : j.sObjectDesc__c.split(';',0)){ m=m.replace('Business Plan :: ',''); m=m.replace('Perfil :: ',''); m=m.replace('Usuário :: ',''); sobjectDescList.add(m); } for (Integer i=0; i<sobjectIdList.size(); i++){ selectResult.add(new SelectOption(sobjectIdList[i],sobjectDescList[i])); } j.sObjectIds__c=''; j.sObjectDesc__c=''; searchText = ''; sObjectDesc = 'Business Plans'; searchObject = 'Business_Plan__c'; soql = 'select Id, Name, Business_Plan_Conta__r.Name from ' + searchObject + ' order by Name limit 100'; runQuery(); } public List<SelectOption> getItems() { List<SelectOption> options = new List<SelectOption>(); options.add(new SelectOption('Business Plans','Business Plans')); options.add(new SelectOption('Perfis','Perfis')); options.add(new SelectOption('Usuários','Usuários')); return options; } public List<SelectOption> getSearchResults() { return searchResult; } public List<SelectOption> getSelectResults() { return selectResult; } // runs the actual query public void runQuery() { try { results = Database.query(soql); if (results.size()==100){ overMax=true; } else { overMax=false; } searchResult.clear(); for (sObject r : results){ If (sObjectDesc.contains('Business Plans')){ Business_Plan__c BPr = (Business_Plan__c) r; searchResult.add(new SelectOption(BPr.Id,BPr.Name+' :: '+BPr.business_plan_conta__r.Name)); for (SelectOption s: selectResult) { for (Integer i=0; i<searchResult.size(); i++){ if (searchResult[i].getValue()==s.getValue()){ searchResult.remove(i); i--; } } } } Else If (sObjectDesc.contains('Perfis')){ Profile Pr = (Profile) r; searchResult.add(new SelectOption(Pr.Id,Pr.Name)); for (SelectOption s: selectResult) { for (Integer i=0; i<searchResult.size(); i++){ if (searchResult[i].getValue()==s.getValue()){ searchResult.remove(i); i--; } } } } Else If (sObjectDesc.contains('Usuários')){ User Ur = (User) r; searchResult.add(new SelectOption(Ur.Id,Ur.Name)); for (SelectOption s: selectResult) { for (Integer i=0; i<searchResult.size(); i++){ if (searchResult[i].getValue()==s.getValue()){ searchResult.remove(i); i--; } } } } } } catch (Exception e) { ApexPages.addMessage(new ApexPages.Message(ApexPages.Severity.ERROR, 'Ocorreu um erro ao efetuar a busca, por favor, tente novamente')); } } // runs the search with parameters passed via Javascript public PageReference runSearch() { If (sObjectDesc.contains('Business Plans')){ searchObject='Business_Plan__c'; } Else If (sObjectDesc.contains('Perfis')){ searchObject='Profile'; } Else If (sObjectDesc.contains('Usuários')){ searchObject='User'; } soql = 'select Id, Name from ' + searchObject; If (sObjectDesc.contains('Business Plans')){ soql = soql.replace('select Id, Name from','select Id, Name, Business_Plan_Conta__r.Name from'); soql += ' where Name LIKE \''+'%'+String.escapeSingleQuotes(searchText)+'%\' or business_plan_conta__r.name LIKE \''+'%'+String.escapeSingleQuotes(searchText)+'%\''; } Else { if (!searchText.equals('')){ soql += ' where Name LIKE \''+'%'+String.escapeSingleQuotes(searchText)+'%\''; } } soql += ' order by Name limit 100'; // run the query again runQuery(); return null; } public PageReference doSelect() { for (String s: selected) { for (Integer i=0; i<searchResult.size(); i++){ if (searchResult[i].getValue()==s){ selectResult.add(new SelectOption(s,searchResult[i].getLabel())); searchResult.remove(i); i--; } } } return null; } public PageReference doUnSelect() { for (String s: unselected) { for (Integer i=0; i<selectResult.size(); i++){ if (selectResult[i].getValue()==s){ searchResult.add(new SelectOption(s,selectResult[i].getLabel())); selectResult.remove(i); i--; } } } return null; } //Override Save & New Functionality public PageReference SaveAndNew() { for (selectOption s : selectResult){ j.sObjectIds__c += s.getValue()+';'; if (s.getValue().startswith(Label.BP_Id)){ j.sObjectDesc__c += 'Business Plan :: '+s.getLabel()+';'; } else if (s.getValue().startswith(Label.Perfil_Id)){ j.sObjectDesc__c += 'Perfil :: '+s.getLabel()+';'; } else if (s.getValue().startswith(Label.User_Id)){ j.sObjectDesc__c += 'Usuário :: '+s.getLabel()+';'; } } Update j; PageReference pr = new PageReference('/apex/JDABP'); pr.setRedirect(true); return pr; } public Boolean getOverMax(){ return overMax; } //Override Save Functionality public PageReference SaveRecord() { for (selectOption s : selectResult){ j.sObjectIds__c += s.getValue()+';'; if (s.getValue().startswith(Label.BP_Id)){ j.sObjectDesc__c += 'Business Plan :: '+s.getLabel()+';'; } else if (s.getValue().startswith(Label.Perfil_Id)){ j.sObjectDesc__c += 'Perfil :: '+s.getLabel()+';'; } else if (s.getValue().startswith(Label.User_Id)){ j.sObjectDesc__c += 'Usuário :: '+s.getLabel()+';'; } } Update j; PageReference pr = new PageReference('/'+j.Id); pr.setRedirect(true); return pr; } }
In your page you are binding fields from the standard controller record to the input fields:
but in the controller,query a different record via SOQL:
and in the save method, you update the values from the 'j' record to the database:
Thus any changes you make on the page will be discarded, as those will be from a different object instance to the one you are updating.
All Answers
In your page you are binding fields from the standard controller record to the input fields:
but in the controller,query a different record via SOQL:
and in the save method, you update the values from the 'j' record to the database:
Thus any changes you make on the page will be discarded, as those will be from a different object instance to the one you are updating.
Thanks Bob! I originally wrote the SOQL query because I was getting this error:
System.SObjectException: SObject row was retrieved via SOQL without querying the requested field: Janela_de_Acesso__c.sObjectIds__c
when I used the controller.getRecord() method alone but I discovered I could instead just add another apex:inputField component with the renderedtag set to false in my visualforce page to solve that issue. Attached is the working version of my code, thanks again!
VFPage:
Controller:
This is a very common error. The way around it is to add components for the fields you are interested in, but don't render them.
e.g.
If you are looking to pull back a collection of related records you may need a non-rendered repeating component.
Yes, that is exactly how I solved the problem after reading your original post (except I used an apex:inputField component); thanks again Bob!