function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
Carole Reynolds1Carole Reynolds1 

Mass Edit Sortable VF Page

We are trying to implement a mass edit type VF page that displays a few fields in a list and allows the user to edit one of those fields. We have a requirement that the list be sortable by column. I’ve taken examples from SFDC and pieced together an implementation using an extension class to do the sorting and the standardsetcontroller. The problem we are having is once a user makes edits to the data on the page and presses the Save button, their changes are not saved; When I examine the records the user supposedly edited I see no changes. Moreover, the debug logs do not indicate any updates were done.  What do I need to do to get my VF page to Save (update) the records the user has edited? 

Here is our VF Page:

<apex:page standardController="Ticket1__Ticket__c" extensions="SortingController,selectedSizeController" showHeader="false" recordsetvar="tickets">
    <apex:form >
   
        <apex:pageMessage summary="Selected Collection Size: {!selectedSize}"
            severity="info"
            id="mupms"
        />
        <apex:pageMessage summary="Record Set Size: {!recordsSize}"
            severity="info"
            id="mupmr"
        />
   
        <apex:pageBlock title="Ticket Mass-Update" mode="edit" id="mub1">
            <apex:pageMessages />
           
            <apex:pageBlockSection id="mus1">
                <apex:inputField value="{!Ticket1__Ticket__c.Status__c}" id="status">
                    <apex:actionSupport event="onchange" rerender="muselectedlist"/>
                </apex:inputField>
            </apex:pageBlockSection>
           
            <apex:pageBlockButtons location="bottom" id="mubut">
                <apex:commandButton value="Save" action="{!save}" id="butsav"/>
                <apex:commandButton value="Cancel" action="{!cancel}" id="butcan"/>
            </apex:pageBlockButtons>
        </apex:pageBlock>
       
        <apex:pageBlock title="Campaign Tickets" id="muselectedlist">
            <apex:pageBlockTable value="{!tickets}" var="tix" id="mutab">
           
                <apex:column >
                    <apex:outputText value="{!tix.Id}" />
                </apex:column>
               
                <apex:column >
                    <apex:outputText value="{!tix.Name}" />
                </apex:column>               
                            
                <apex:column >
                    <apex:facet name="header">
                        <apex:commandLink action="{!sort}" value="Ticket1__tix_LastName__c{!IF(sorterUtil.column=='Ticket1__tix_LastName__c',IF(sorterUtil.sortDirection='ASC','?','?'),'')}">
                            <apex:param value="Ticket1__tix_LastName__c" name="column" assignTo="{!sorterUtil.column}" ></apex:param>
                        </apex:commandLink>
                    </apex:facet>
                    <apex:outputText value="{!tix.Ticket1__tix_LastName__c}" />
                </apex:column>
               
                <apex:column >
                    <apex:facet name="header">
                        <apex:commandLink action="{!sort}" value="Ticket1__tix_FirstName__c{!IF(sorterUtil.column=='Ticket1__tix_FirstName__c',IF(sorterUtil.sortDirection='ASC','?','?'),'')}">
                            <apex:param value="Ticket1__tix_FirstName__c" name="column" assignTo="{!sorterUtil.column}" ></apex:param>
                        </apex:commandLink>
                    </apex:facet>
                    <apex:outputText value="{!tix.Ticket1__tix_FirstName__c}" />
                </apex:column>
               
                <apex:column >
                    <apex:facet name="header">
                        <apex:commandLink action="{!sort}" value="Attendee_Role__c{!IF(sorterUtil.column=='Attendee_Role__c',IF(sorterUtil.sortDirection='ASC','?','?'),'')}">
                            <apex:param value="Attendee_Role__c" name="column" assignTo="{!sorterUtil.column}" ></apex:param>
                        </apex:commandLink>
                    </apex:facet>
                    <apex:outputText value="{!tix.Attendee_Role__c}" />
                </apex:column>
               
                <apex:column >
                    <apex:facet name="header">
                        <apex:commandLink action="{!sort}" value="Status__c{!IF(sorterUtil.column=='Status__c',IF(sorterUtil.sortDirection='ASC','?','?'),'')}">
                            <apex:param value="Status__c" name="column" assignTo="{!sorterUtil.column}" ></apex:param>
                        </apex:commandLink>
                    </apex:facet>
                        <apex:inputField value="{!tix.Status__c}"/>
                </apex:column>
            </apex:pageBlockTable>
        </apex:pageBlock>
    </apex:form>
</apex:page>


Here is our controller:

public class SortingController {
//[Select Id, Name, Tickets1__tix_LastName__c, Tickets1__tix_FirstName__c, Attendee_Role__c, Status__c From Tickets1__Ticket__c];

private final ApexPages.StandardSetController cntr;
String qid;

private String defaultSortColumn = 'Tickets1__tix_LastName__c'; /** Set the default sort Column. /
private String sortDirection = 'ASC';
public SortingControllerUtil sorterUtil {get; set;} /* Declare Sorter Utility class Object. /

public SortingController(ApexPages.StandardSetController controller) {

qid = ApexPages.currentPage().getParameters().get('id');
system.debug('Id of object in context is=' + qid);

cntr = (ApexPages.StandardSetController)controller;

sorterUtil = new SortingControllerUtil(defaultSortColumn, sortDirection); /* Create Sorter_UTIL Object. /
}
public List<Tickets1__Ticket__c> getTickets() {
/* Add the column and sort direction value at the end of query.*/
String stringQuery =
  'Select Id, Name, Tickets1__tix_LastName__c, Tickets1__tix_FirstName__c, Attendee_Role__c, Status__c From Tickets1__Ticket__c ' +
  'Where Tickets1__tix_Campaign__c= :qid ' +
  'Order By ' + sorterUtil.getColumn() + ' ' + sorterUtil.getSortDirection() +' NULLS LAST';
return database.query(stringQuery);
}

public PageReference sort() { /* Define sorting method. **/
/** Do nothing here. **/
return null;
}

}
Best Answer chosen by Carole Reynolds1
Ryan GardnerRyan Gardner
Here's what I think is going on. When you make changes you are making them on your pageblock table to the set returned by "getTickets()", but this just runs a query, it doesn't bind to a set of records. So I think what is happening every time you save is that the controller tries to save what is returned by "getTickets()" but that just re-queries the database and you end up saving what is in there already.

Why don't you add a custom save method and see if it works to specifically save the set you're dealing with. Something like:

<pre>
public class SortingController {
  //[Select Id, Name, Tickets1__tix_LastName__c, Tickets1__tix_FirstName__c, Attendee_Role__c, Status__c From Tickets1__Ticket__c];

  private final ApexPages.StandardSetController cntr;
  String qid;
  public List < Tickets1__Ticket__c > theTickets;

  private String defaultSortColumn = 'Name'; /** Set the default sort Column. */
  private String sortDirection = 'ASC';
  public SortingControllerUtil sorterUtil {
        get;
        set;
    } /** Declare Sorter Utility class Object. */

    public SortingController(ApexPages.StandardSetController controller) {

        qid = ApexPages.currentPage().getParameters().get('id');
        system.debug('Id of object in context is=' + qid);

        cntr = (ApexPages.StandardSetController) controller;

        sorterUtil = new SortingControllerUtil(defaultSortColumn, sortDirection); /** Create Sorter_UTIL Object. */
    }
  
    public List < Tickets1__Ticket__c > getTickets() {
        /** Add the column and sort direction value at the end of query.**/
        String stringQuery =
            'Select Id, Name, Type, BillingStreet, Inustry FROM Account ' +
            'Where type = :qid ' +
            'Order By ' + sorterUtil.getColumn() + ' ' + sorterUtil.getSortDirection() + ' NULLS LAST';
        theTickets = database.query(stringQuery);
        return theTickets;
    }

    public PageReference saveTheTickets(){
        update theTickets;
        return new PageReference('wherever');
    }

    public PageReference sort() { /* Define sorting method. **/
        /** Do nothing here. **/
        return null;
    }

}
</pre>

and then in your VF just change your save button action to "=saveTheTickets()". Let me know how that works.

All Answers

Ryan GardnerRyan Gardner
Did the save action work before you implemented your extension controllers? You might try removing them for a minute from the VF page and seeing if you can save without them.
Carole Reynolds1Carole Reynolds1
ryangoblue - actually, we initially started with the following that DID save; however, it wasn't sortable. Since we need to mass edit sometimes hundreds of records (ticket holders) having them in alphebetical order is ideal.

This page will save but does not implement sorting:


<apex:page standardController="sbxe1__Ticket__c"
    recordSetVar="tickets"
    extensions="selectedSizeController"
    showHeader="false"
    id="mutix"
>
    <apex:form id="muform">
        <apex:pageMessage summary="Selected Collection Size: {!selectedSize}"
            severity="info"
            id="mupms"
        />
        <apex:pageMessage summary="Record Set Size: {!recordsSize}"
            severity="info"
            id="mupmr"
        />
        <apex:pageBlock title="Ticket Mass-Update" mode="edit" id="mub1">
            <apex:pageMessages />
           
            <apex:pageBlockSection id="mus1">
                <apex:inputField value="{!sbxe1__Ticket__c.Status__c}" id="status">
                    <apex:actionSupport event="onchange" rerender="muselectedlist"/>
                </apex:inputField>
            </apex:pageBlockSection>
           
            <apex:pageBlockButtons location="bottom" id="mubut">
                <apex:commandButton value="Save" action="{!save}" id="butsav"/>
                <apex:commandButton value="Cancel" action="{!cancel}" id="butcan"/>
            </apex:pageBlockButtons>
        </apex:pageBlock>
       
        <apex:pageBlock title="Campaign Tickets" id="muselectedlist">
            <apex:pageBlockTable value="{!tickets}" var="tix" id="mutab">
                            
                <apex:column value="{!tix.sbxe1__sbx_FullName__c}" id="tixfullname"/>
               
                <apex:column value="{!tix.Attendee_Role__c}" id="tixrole"/>
               
                <apex:column headerValue="Status">
                    <apex:inputField value="{!tix.Status__c}"/>
                </apex:column>

            </apex:pageBlockTable>
        </apex:pageBlock>
       
       
       
       
    </apex:form>
</apex:page>
Ryan GardnerRyan Gardner
Here's what I think is going on. When you make changes you are making them on your pageblock table to the set returned by "getTickets()", but this just runs a query, it doesn't bind to a set of records. So I think what is happening every time you save is that the controller tries to save what is returned by "getTickets()" but that just re-queries the database and you end up saving what is in there already.

Why don't you add a custom save method and see if it works to specifically save the set you're dealing with. Something like:

<pre>
public class SortingController {
  //[Select Id, Name, Tickets1__tix_LastName__c, Tickets1__tix_FirstName__c, Attendee_Role__c, Status__c From Tickets1__Ticket__c];

  private final ApexPages.StandardSetController cntr;
  String qid;
  public List < Tickets1__Ticket__c > theTickets;

  private String defaultSortColumn = 'Name'; /** Set the default sort Column. */
  private String sortDirection = 'ASC';
  public SortingControllerUtil sorterUtil {
        get;
        set;
    } /** Declare Sorter Utility class Object. */

    public SortingController(ApexPages.StandardSetController controller) {

        qid = ApexPages.currentPage().getParameters().get('id');
        system.debug('Id of object in context is=' + qid);

        cntr = (ApexPages.StandardSetController) controller;

        sorterUtil = new SortingControllerUtil(defaultSortColumn, sortDirection); /** Create Sorter_UTIL Object. */
    }
  
    public List < Tickets1__Ticket__c > getTickets() {
        /** Add the column and sort direction value at the end of query.**/
        String stringQuery =
            'Select Id, Name, Type, BillingStreet, Inustry FROM Account ' +
            'Where type = :qid ' +
            'Order By ' + sorterUtil.getColumn() + ' ' + sorterUtil.getSortDirection() + ' NULLS LAST';
        theTickets = database.query(stringQuery);
        return theTickets;
    }

    public PageReference saveTheTickets(){
        update theTickets;
        return new PageReference('wherever');
    }

    public PageReference sort() { /* Define sorting method. **/
        /** Do nothing here. **/
        return null;
    }

}
</pre>

and then in your VF just change your save button action to "=saveTheTickets()". Let me know how that works.
This was selected as the best answer
Carole Reynolds1Carole Reynolds1
Ryan - Very helpful, thank you! We were able to get this working based on your suggestion.
jenny_j_chen1.3971006870153901E12jenny_j_chen1.3971006870153901E12
Hi Ravin,
Can you please share the Sorter Utility class "SortingControllerUti" codes? I need to implement something similar too.


Jenny
Carole Reynolds1Carole Reynolds1
Jenny, Here is the Sorting Controller we used – hope this helps! public with sharing class SortingControllerUtil { private String column; public String sortDirection; public final static String SORT_ASC = 'ASC'; public final static String SORT_DESC = 'DESC'; public SortingControllerUtil(String defaultSortColumn, String defaultSortDirection){ this.column = defaultSortColumn; this.sortDirection = defaultSortDirection; } public String getSortDirection() { return this.sortDirection; } public String getColumn() { return this.column; } public void setColumn(String columnName) { if (column.equalsIgnoreCase(columnName)) { sortDirection = (sortDirection.equals(SORT_ASC)) ? SORT_DESC : SORT_ASC; } else { this.sortDirection = SORT_ASC; this.column = columnName; } } } *Carole Reynolds, MS* 906-487-2102