1

i have problem for inline editing visualforce with pagination. In the right column i have input text area and its the problem, everytime i fill that field and click next button, i always get error Modified rows exist in the records collection!

I using object Case, hope anyone can try and help. Here is the code:

Apex class

public with sharing class ResendEmailCaseController {
// account and selection set/variables
private List<CaseSubClass> CaseSubClassList {get; set;}
private Set<Id> caseSelectedSet;
public Integer caseSelectedCount {get; set;}
public String selectedOneCase {get; set;}
// selection and filter 
public List<String> alphaList {get; set;}
public String alphaFilter {get; set;}
public String searchName {get; set;}
public String searchBillingAddress {get; set;} 
private String saveSearchName;
private String saveSearchBillingAddress;
private String queryCase;
public String emailCaseList {get;set;}
// display sort and number
public String recPerPage {get; set;}
public List<SelectOption> recPerPageOption{get; set;}
public String sortFieldSave;
public String allString {get;set;}
public List <Email_History__c> listeh = new List <Email_History__c> ();

private static final String DEFAULT_REC_PER_PAGE = '10';

/***
* TableExampleController - Constructor initialization
***/
public ResendEmailCaseController(){
    CaseSubClassList = new List<CaseSubClass>();
    caseSelectedSet = new Set<Id>();

    buildQuery();  
}

/***
* StdSetControllerAccount - paging through the Account list
***/ 
public ApexPages.StandardSetController StdSetControllerCase {
    get {
        if(StdSetControllerCase == null) {
            StdSetControllerCase = new ApexPages.StandardSetController(Database.getQueryLocator(queryCase));
            // sets the number of records in each page set
            StdSetControllerCase.setPageSize(Integer.valueOf(recPerPage));
        }
        return StdSetControllerCase;
    }
    set;
}

/***
* getCurrentInvoiceList - return an Account list for the table
***/  
public List<CaseSubClass> getCurrentInvoiceList() {
    updatecaseSelectedSet();

    CaseSubClassList = new List<CaseSubClass>();
    **for (Case a : (List<Case>)StdSetControllerCase.getRecords()) { //.deepClone(true)**
        CaseSubClassList.add(new CaseSubClass(a, caseSelectedSet.contains(a.Id)));
    }
    return CaseSubClassList;
}

/***
* updatecaseSelectedSet - add/remove accounts from the selected account id list
***/
public void updatecaseSelectedSet(){
    for (CaseSubClass CaseSubClassObj : CaseSubClassList) {
        if (CaseSubClassObj.aCheckBox == true) {
            caseSelectedSet.add(CaseSubClassObj.aCase.Id);
            List<String> arrayemail2 = new List<String>();
            List<Case> emaillist = [SELECT Id, AccountId, Account.Primary_Email_Address__c, Account.Secondary_Email_Address_1__c, Account.Secondary_Email_Address_2__c, address_List__c FROM Case WHERE Id = :CaseSubClassObj.aCase.Id];
            List<Contact> conlist2 = [SELECT Id, Email, Secondary_Email_1__c, Secondary_Email_2__c FROM Contact WHERE AccountId = :emaillist[0].AccountId];
            if (conlist2.size() > 0) {
                for (Contact c : conlist2) {
                    if (String.isNotBlank(c.email)) {
                        arrayemail2.add(c.email);
                    }
                    if (String.isNotBlank(c.Secondary_Email_1__c)) {
                        arrayemail2.add(c.Secondary_Email_1__c);
                    }
                    if (String.isNotBlank(c.Secondary_Email_2__c)) {
                        arrayemail2.add(c.Secondary_Email_2__c);
                    }
                }
            }
            if (emaillist[0].Account.Primary_Email_Address__c!=null) {
                arrayemail2.add(emaillist[0].Account.Primary_Email_Address__c);
            }
            if (emaillist[0].Account.Secondary_Email_Address_1__c!=null) {
                arrayemail2.add(emaillist[0].Account.Secondary_Email_Address_1__c);
            }
            if (emaillist[0].Account.Secondary_Email_Address_2__c!=null) {
                arrayemail2.add(emaillist[0].Account.Secondary_Email_Address_2__c);
            }
            allString = String.join(arrayemail2,';');
            emailCaseList = allString;
            CaseSubClassObj.aCase.Address_List__c = 'allstring';
        } 
        else {
            if (caseSelectedSet.contains(CaseSubClassObj.aCase.Id)) {
                caseSelectedSet.remove(CaseSubClassObj.aCase.Id);
                emailCaseList = '';
                CaseSubClassObj.aCase.Address_List__c = '';
            }
        } 
    }  
    caseSelectedCount = caseSelectedSet.size();
}

/***
* ClearcaseSelectedSet - remove selected accounts and initialize counter
***/
public PageReference clearAll(){
    CaseSubClassList.clear();
    caseSelectedSet.clear();
    caseSelectedCount = 0;
    searchName = '';
    searchBillingAddress = '';
    saveSearchName = '';
    saveSearchBillingAddress = '';
    alphaFilter = 'All';

    buildQuery();

    return null;
}

/***
* searchAccount - set search criteria fields and refresh Account table
***/
public PageReference searchAccount() {
    saveSearchName = searchName;
    saveSearchBillingAddress = searchBillingAddress;

    buildQuery();

    return null;
}

/***
* BuildQuery - build query command for list selection change
***/
public void buildQuery() {

}

/***
* SortDirection - return sort direction. Default ascending(asc)
***/
public String sortDirection {
    get { if (sortDirection == null) {  sortDirection = 'asc'; } return sortDirection;  }
    set;
}

/***
* SortField - return sort by field. Default to Name
***/
public String sortField {
    get { if (sortField == null) {sortField = 'CaseNumber'; } return sortField;  }
    set; 
}

/***
* SortToggle - toggles the sorting of query from asc<-->desc
***/

/***
* DoSomethingOne - do something with one selected account
***/
public PageReference doSomethingOne() {
    System.debug(LoggingLevel.DEBUG, '***selectedOneCase: ' + selectedOneCase);
    return null;
}

/***
* DoSomethingMany - do something with many selected accounts
***/
public PageReference doSomethingMany() {
    System.debug(LoggingLevel.DEBUG, '***caseSelectedSet.size(): ' + caseSelectedSet.size());

    for (Id CaseId : caseSelectedSet) {
        List<Case> invlist = [SELECT Id, Invoice__c, Account.preferredLanguage__c FROM Case WHERE Id = :CaseId];
        List<String> arrayemail = allString.split(';');
        System.debug(LoggingLevel.DEBUG, '***invlist: ' + JSON.serializePretty(invlist));
        System.debug('***Email Invoice :'+ allString);
        System.debug('*****Array Email :'+ arrayemail);
        System.debug('***Array Email :'+ JSON.serializePretty(arrayemail));

        List<Id> ids= new List<Id>();
        for(Case inv2:invlist) {
            for (Integer i=0; i<arrayemail.size(); i++ ) {

                system.debug('Array : '+arrayemail[i]);
            }
        }
    }
    return null;
}

/***
* CaseSubClass - Sub-Class to hold Account and checkbox for the table
***/
public class CaseSubClass {
    public Boolean aCheckBox {get;set;}
    public Case aCase {get;set;}

    // sub-class initialization
    public CaseSubClass(Case a, Boolean chk){
        aCase = a;
        aCheckBox = chk;
    }
}
}

Visualforce Page

<apex:page controller="ResendEmailCaseController" 
lightningStylesheets="true">
<script>
     function updateMessage(){
        alert('Successfully resend email');
    }    
  </script>
  <apex:form id="TheForm">
  <!-- ***************************** -->
  <!-- Search Criteria               -->
  <apex:pageBlock mode="maindetail">
     <div class="search-block">
        <div style="display: inline-table">
            <span>Case No:</span>
           <apex:inputText value="{!searchName}" />
        </div>
        <div style="display: inline-table">
            <span>Hotel Name:</span>
           <apex:inputText value="{!searchBillingAddress}" />
        </div>
        <apex:commandButton styleClass="search-block-button" value="Search" action="{!searchAccount}" rerender="TablePanel"
           status="TableUpdateStatus" />
        <apex:actionStatus id="ProcessButtonStatus">
           <apex:facet name="stop">
              <apex:outputPanel >
                 <apex:commandButton styleClass="process-block-button" value="Resend Email" action="{!doSomethingMany}"
                    status="ProcessButtonStatus" rerender="nothing" oncomplete="updateMessage();"/>
                 <apex:commandButton styleClass="process-block-button" value="Clear All" action="{!ClearAll}"
                    rerender="TheForm,TablePanel" />
              </apex:outputPanel>
           </apex:facet>
           <apex:facet name="start">
              <apex:outputPanel >
                 <apex:commandButton styleClass="process-block-button" value="Processing..." disabled="true" />
                 <apex:commandButton styleClass="process-block-button" value="Processing..." disabled="true" />
              </apex:outputPanel>
           </apex:facet>
        </apex:actionStatus>
     </div>

  </apex:pageBlock>

  <!-- ************************* -->
  <!-- search results table      -->
  <apex:pageBlock id="TablePanel">
     <div>
        <span class="page-buttons" style="float: left; margin-bottom: 5px;"> <apex:commandButton disabled="{!!StdSetControllerCase.hasprevious}" value="Previous" action="{!StdSetControllerCase.previous}"
              rerender="TablePanel" /> <apex:commandButton disabled="{!!StdSetControllerCase.hasnext}" value="Next"
              action="{!StdSetControllerCase.next}" rerender="TablePanel" />
        </span> 
        <!-- alphabet selection -->
        <span style="float: right; margin: 5px 5px 5px 5px;"> <apex:repeat value="{!AlphaList}" var="a">
              <apex:commandLink value="{!a}" action="{!BuildQuery}" rerender="TablePanel"
                 styleClass="alpha-link{!if(AlphaFilter=a,' alpha-select','')}" status="TableUpdateStatus">
                 <apex:param name="AlphaFilter" value="{!a}" assignTo="{!AlphaFilter}" />
              </apex:commandLink>
           </apex:repeat>
        </span>
     </div>

     <div style="clear: both;"></div>

     <apex:actionStatus id="TableUpdateStatus">
        <apex:inputHidden value="{!AlphaFilter}" id="hiddenField" />
        <!-- loading message -->
        <apex:facet name="start">
           <apex:outputPanel layout="block" styleClass="message infoM4">
              <apex:panelGrid columns="2" styleClass="messageTable" columnClasses="messageCell" style="padding:0px;margin:0px;">
                 <apex:panelGroup >
                    <img class="loading-icon" src="/s.gif" />
                 </apex:panelGroup>
                 <apex:panelGroup >
                    <div class="messageText">Please wait...</div>
                 </apex:panelGroup>
              </apex:panelGrid>
           </apex:outputPanel>
        </apex:facet>

        <!-- Account table -->
        <apex:facet name="stop">
           <apex:pageBlockTable value="{!CurrentInvoiceList}" var="a" id="TheBlock">
             <apex:column >
                 <apex:facet name="header">
                    <apex:outputPanel id="SelectedCount">
                       <div style="text-align: center;">
                          <apex:outputText value="Selected" />
                          <br />
                         <apex:outputText value="{!CaseSelectedCount}" />
                       </div>
                    </apex:outputPanel> 
                 </apex:facet>
                 <div style="text-align: center;">
                    <apex:inputCheckBox value="{!a.aCheckBox}" id="check-box">
                       <apex:actionSupport event="onchange" rerender="SelectedCount,outputID" action="{!UpdateCaseSelectedSet}" />
                       </apex:inputcheckbox>
                 </div>
              </apex:column>
              <apex:column >
                 <apex:facet name="header">
                    <apex:commandLink action="{!SortToggle}" rerender="TablePanel" status="TableUpdateStatus">
                       <apex:param name="SortField" value="casenumber" assignTo="{!SortField}" />
                       <apex:outputText value="{!$ObjectType.case.Fields.casenumber.Label}{!IF(SortField=='casenumber',IF(SortDirection='asc','▲','▼'),'')}" />
                    </apex:commandLink>
                 </apex:facet>
                 <apex:outputLink value="/{!a.aCase.Id}" target="_blank">{!a.acase.casenumber}</apex:outputlink>
              </apex:column>
             <apex:column >
                 <apex:facet name="header">
                    <apex:commandLink action="{!SortToggle}" rerender="TablePanel" status="TableUpdateStatus">
                       <apex:param name="SortField" value="Account.name" assignTo="{!SortField}" />
                       <apex:outputText value="{!$ObjectType.Case.Fields.Accountid.Label}{!IF(SortField=='Account.name',IF(SortDirection='asc','▲','▼'),'')}" />
                    </apex:commandLink>
                 </apex:facet>
                 <apex:outputField value="{!a.aCase.Account.name}" />
              </apex:column>
              <apex:column >
                 <apex:facet name="header">
                    <apex:commandLink action="{!SortToggle}" rerender="TablePanel" status="TableUpdateStatus">
                       <apex:param name="SortField" value="Status" assignTo="{!SortField}" />
                       <apex:outputText value="{!$ObjectType.Case.Fields.Status.Label}{!IF(SortField=='Status',IF(SortDirection='asc','▲','▼'),'')}" />
                    </apex:commandLink>
                 </apex:facet>
                 <apex:outputField value="{!a.aCase.Status}" />
              </apex:column>
              <apex:column >
                 <apex:facet name="header">
                    <apex:commandLink action="{!SortToggle}" rerender="TablePanel" status="TableUpdateStatus">
                       <apex:param name="SortField" value="Priority" assignTo="{!SortField}" />
                       <apex:outputText value="{!$ObjectType.Case.Fields.Priority.Label}{!IF(SortField=='Priority',IF(SortDirection='asc','▲','▼'),'')}" />
                    </apex:commandLink>
                 </apex:facet>
                 <apex:outputField value="{!a.aCase.Priority}" />
              </apex:column>
              <apex:column >
                 <apex:facet name="header">
                    <apex:commandLink action="{!SortToggle}" rerender="TablePanel" status="TableUpdateStatus">
                       <apex:param name="SortField" value="Invoice_No__c" assignTo="{!SortField}" />
                       <apex:outputText value="{!$ObjectType.Case.Fields.Invoice_No__c.Label}{!IF(SortField=='Invoice_No__c',IF(SortDirection='asc','▲','▼'),'')}" />
                    </apex:commandLink>
                 </apex:facet>
                 <apex:outputField value="{!a.aCase.Invoice_No__c}" />
              </apex:column>
              <apex:column >
                 <apex:facet name="header">
                    <apex:commandLink action="{!SortToggle}" rerender="TablePanel" status="TableUpdateStatus">
                       <apex:param name="SortField" value="Priority_Number__c" assignTo="{!SortField}" />
                       <apex:outputText value="{!$ObjectType.Case.Fields.Priority_Number__c.Label}{!IF(SortField=='Priority_Number__c',IF(SortDirection='asc','▲','▼'),'')}" />
                    </apex:commandLink>
                 </apex:facet>
                 <apex:outputField value="{!a.aCase.Priority_Number__c}" />
              </apex:column>
              <apex:column >
                 <apex:facet name="header">
                    <apex:commandLink action="{!SortToggle}" rerender="TablePanel" status="TableUpdateStatus">
                       <apex:param name="SortField" value="Latest_Collection_Log_Status__c" assignTo="{!SortField}" />
                       <apex:outputText value="{!$ObjectType.Case.Fields.Latest_Collection_Log_Status__c.Label}{!IF(SortField=='Latest_Collection_Log_Status__c',IF(SortDirection='asc','▲','▼'),'')}" />
                    </apex:commandLink>
                 </apex:facet>
                 <apex:outputField value="{!a.aCase.Latest_Collection_Log_Status__c}" />
              </apex:column>
              <apex:column >
                 <apex:facet name="header">
                        <apex:outputText value="Email" />
                 </apex:facet>
                 **<apex:inputTextarea value="{!a.aCase.Address_List__c}" id="outputID" rows="15" html-maxlength="1024" style="width: 80%;height: 15px;" />**
                 <!-- <apex:inputTextarea value="{!a.aCase.Address_List__c}" id="outputID" rows="15" html-maxlength="1024" style="width: 80%;height: 15px;" /> -->
              </apex:column> 
           </apex:pageBlockTable>
        </apex:facet>
     </apex:actionStatus>
     <div style="margin-top: 5px;">
        <apex:outputText value="Number of Records per Page: " />
        <apex:selectList value="{!RecPerPage}" size="1">
           <apex:selectOptions value="{!RecPerPageOption}" />
           <apex:actionSupport event="onchange" action="{!BuildQuery}" reRender="TablePanel" status="TableUpdateStatus" />
        </apex:selectList>
     </div>
  </apex:pageBlock>
  </apex:form>

  </apex:page>

I give ** ** for indicate problem, at line:

  • for (Case a : (List)StdSetControllerCase.getRecords()) { //.deepClone(true)

  • apex:inputTextarea value="{!a.aCase.Address_List__c}" id="outputID" rows="15" html-maxlength="1024" style="width: 80%;height: 15px;"

This is the view of VF enter image description here

Please help me to solve this problem, i already try using deep.clone but it make my code fail to get default value in visualforce. I really appreciate for everyone that can help. Thanks.

  • 2
    can you clean up unnecessary code from your question – Santanu Boral Jun 25 '18 at 12:00
  • @SantanuBoral Hi, i've been clean up some unnecessary code. The key in apex class are updatecaseSelectedSet(), getCurrentInvoiceList(), CaseSubClass(). My purpose is when user checked one of case, email address in right column will automatic appear from account email and contact email ( done), but when user click next it give the error and i still fail to get temporary value email from input text when user changed it. – Enriko Jun 25 '18 at 12:16
1

as per the error message indicates that the controller dataset has been modified but the changes has not been reflected in the database.

Kindly call StdSetControllerCase.save(); method when are you clicking on the next and previous button will resolve the error. Like below,

public void nextFunction(){
  StdSetControllerCase.save();
  StdSetControllerCase.next();
}
public void prevFunction(){
  StdSetControllerCase.save();
  StdSetControllerCase.previous();
}

And refer them to the vf page like below,

<span class="page-buttons" style="float: left; margin-bottom: 5px;"> <apex:commandButton disabled="{!!StdSetControllerCase.hasprevious}" value="Previous" action="{!prevFunction}"
              rerender="TablePanel" /> <apex:commandButton disabled="{!!StdSetControllerCase.hasnext}" value="Next"
              action="{!nextFunction}" rerender="TablePanel" />
        </span>

Once you hit save button it will reflect the chnages and resolves your error. let me know any issues.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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