Monday, November 30, 2009

List View Editing of Accounts

Imagine if you can have a list view of Accounts where users can view accounts, edit accounts in place? Well, it will be the most user friendly system.

Obviously, best practice is, open the list view with less fields and then allow users to edit the page with the less number of fields and if they wish to see details, have a detail page link.

The following code does just this for you.


VisualForce Page: inPlaceAccounts.page

<apex:page controller="AccountsController" tabstyle="Account">     
    <apex:sectionheader subtitle="{!$User.FirstName} {!$User.LastName}" title="Quick Edit Accounts">
    
<apex:pagemessages>
    <apex:form>         
    <apex:actionfunction action="{!saveEditAcc}" name="saveEdit">    
    <apex:pageblock title="Add New Account">  
        <apex:pageblocksection>
        <b>Name:</b> <apex:inputtext value="{!newAccount.Name}"> 
         <b>Annual Revenue:</b><apex:inputtext value="{!newAccount.AnnualRevenue}"> 
       </apex:inputtext></apex:inputtext></apex:pageblocksection>     
        <apex:commandbutton action="{!add}" value="Add">
    </apex:commandbutton></apex:pageblock>
    
    <apex:pageblock title="Existing Accounts">
    <apex:outputpanel id="projectList">
    </apex:outputpanel></apex:pageblock></apex:actionfunction></apex:form></apex:pagemessages>
<apex:repeat value="{!projects}" var="p">
        </apex:repeat><apex:outputpanel id="editRow" layout="none" rendered="{!p.Id == editAccount.Id}">               
  </apex:outputpanel>
<apex:outputpanel id="viewRow" layout="none" rendered="{!p.Id != editAccount.Id}">
            </apex:outputpanel>
<table><tbody>
<tr>         <th style="width: 40px;"></th> <th style="width: 40px;"></th>    <th>Name</th> <th>Annual Revenue</th> </tr>
<tr style="height: 20px;">              <td><apex:commandlink action="{!cancelEdit}" rerender="projectList">Cancel</apex:commandlink></td>      <td><apex:commandlink action="{!saveEditAcc}" rerender="projectList">Save</apex:commandlink></td>       <td><apex:inputtext onkeypress="if (event.keyCode == 13) saveEdit()" rendered="{!p.Id == editAccount.Id}" size="40" value="{!editAccount.Name}"></apex:inputtext></td>      <td><apex:inputtext onkeypress="if (event.keyCode == 13) saveEdit()" rendered="{!p.Id == editAccount.Id}" size="40" value="{!editAccount.AnnualRevenue}"></apex:inputtext></td>        <td><apex:commandlink action="{!del}" onclick="return confirm('Are you sure you want to delete this project?')">Del            <apex:param name="delid" value="{!p.Id}">          </apex:param>        </apex:commandlink></td>    <td><apex:commandlink action="{!editAcc}" rerender="projectList">Edit          <apex:param name="editid" value="{!p.Id}">       </apex:param></apex:commandlink></td>       <td>{!p.Name}</td>    <td>{!p.AnnualRevenue}</td>    <td><apex:outputlink target="_blank" value="/{!p.id}">View Details</apex:outputlink></td>     </tr>
</tbody> </table>
</apex:sectionheader>
</apex:page>

Controller:

Controller: AccountsController
public class AccountsController {
/*
@Author: Siddhesh Kabe
@Domain: http://force.siddheshkabe.co.in
Controller for Visualforce inPlaceAccounts.page 
*/
    public AccountsController() {
        newAccount= new Account(); //Create a new object for account.
    }

    public Account newAccount { get; set; }    //A Account variable to add a new account in the place.
    public Account editAccount { get; set; }    //A temporary variable to store the existing account in place.
    
    
    /*
    @Function: getProjects
    @params: None
    @Return Type: List of Accounts to display
    @Usage: The getter method to fetch Accounts. 
    */
    public Account[] getProjects() {
        return [SELECT Name,AnnualRevenue from ACCOUNT WHERE OwnerId = :UserInfo.getUserId() ORDER BY CreatedDate DESC]; 
    }
    
    
    /*
    @Function: getParam
    @Param: String, the Parameter name to fetch value from.
    @Return Type: String, The value of the URL paramter.
    @Usage: The getter method to fetch Accounts. 
    */
    public String getParam(String name) {
        return ApexPages.currentPage().getParameters().get(name);   
    }
    
    /*
     Action method to add new account. 
    */
    public PageReference add() {
        try {
            INSERT newAccount;
            // if successful, reset the new Account for the next entry
            newAccount = new Account();
        } catch (Exception e) {
            ApexPages.addMessages(e);
        }
        return null;
    }
     
    /*
     Action method to del a account. 
    */
     
    public PageReference del() {
        try {
            String delid = getParam('delid');
            Account delAccount = [SELECT Id FROM Account WHERE ID=:delid];
            DELETE delAccount;
        } catch (Exception e) {
            ApexPages.addMessages(e);
        }
        return null;
    }
    
    /*
     Action method to edit a account. 
    */      
    public PageReference editAcc() {
        String editid = getParam('editid');
        editAccount= [SELECT Name,AnnualRevenue FROM Account WHERE Id=:editid];
        return null;
    }
    
    /*
     Action method to cancel new account. 
    */
     public PageReference cancelEdit() {
        editAccount= null;
        return null;
    }
    
    /*
     Action method to save the edited account. 
    */
    public PageReference saveEditAcc() {
        try {
            UPDATE editAccount;
            editAccount= null;
        } catch (Exception e) {
            ApexPages.addMessages(e);
        }
        return null;
    }
}






This code will nearly do the trick.

Hope it helps,
Cheers,
Sid