Monday, September 16, 2013

Customized search and selection (Add multiple child records at one go)

Scenario:

You want your users to be able to make a customized search and not the way salesforce searches. You also would like to allow your users to select multiple records from the search results and process them.

If the user does not select any record and clicks on the Next button you want to display an Error Message asking him to select at least one record to proceed.


Tip: You may be aware that salesforce allows only one child to be added to a parent at a time. Even though some wizards allow you to mass assign child records to a parent, this is not available for all objects. Modifying this code, you can achieve the functionality of selecting many child records and assigning them to a parent at one click!!!

The screenshots below clearly expresses the scenario...

Before search..




After Search..




Note:
The following code searches for contacts based on the user inputs. Customize it as needed for your needs. Also, this code is called from a custom button on the Campaign Page Layout.


Javascript function :

We also make use of a javascript function to select all records at one go.
The code has suffecient comments to describe about each and every functionality. Do you think you need more info, then feel free to post your comment.
How to use this code?
  • Save the "Apex Class" first. Save the Visualforce page next.
  • Create a custom button in Campaign, select the source as "Visualforce Page" and select the visualforce page just now saved.
  • Go to PageLayout and add your newly created custom button to this layout.
  • Click on any Campaign Record, go to the detail page and then click on the custom button to view the page created.

VisualForce Page:

<apex:page standardcontroller="Campaign" extensions="MassEmailFromCampaign" >
<!-- Javascript function to check all rows in the table -->
<script>
function checkAll(cb)
{
   var inputElem = document.getElementsByTagName("input");
   for(var i=0;i<inputElem.length;i++)
     {
             if(inputElem[i].id.indexOf("selectLine1")!=-1)
                   inputElem[i].checked = cb.checked;
      }
}
</script>
<!-- End of Javascript function -->
<apex:form >
<apex:sectionHeader title="Step 1" subtitle="Select Contacts to send Email"/>
<apex:pageblock >
<apex:pageBlockSection title="Search Contacts" columns="1"></apex:pageBlockSection>

<!-- Div to give a colored box effect -->

<div style="border-width:2px;border-style:solid;border-color:orange;">

    <!-- Panel grid to display boxes o accept user input values -->
    <apex:panelGrid columns="2">
        <apex:outputLabel style="font-weight:bold;" value="Contact E-mail" ></apex:outputLabel>
        <apex:inputText value="{!userinput}"/>
        <apex:outputLabel style="font-weight:bold;" value="Contact Name" ></apex:outputLabel>
        <apex:inputText value="{!userinp}"/>
    </apex:panelGrid>
    <!-- End of panelgrid -->
    <!-- Div to position the commandbutton appropriately -->
        <div style="position:relative;left:75px;">
             <apex:commandButton value="Search" action="{!contactsearch}" />
        </div>
    <!-- End of div -->
        <br/>
</div>

<!-- End of colored box div -->
    <br/>
<!-- Display error message -->
<apex:pagemessage strength="2" title="Error!!" severity="error" detail="Please select a contact or enter email address to proceed" rendered="{!errormsg}"/>
<!-- End of error message -->

<!-- Display search results -->
<apex:pageblocksection columns="1" title="Search results" rendered="{!NOT(ISNULL(results))}" >
  <apex:outputpanel id="Contactlist">

        <apex:pageBlockTable value="{!results}" var="contacts">
             <apex:column >
                <apex:facet name="header">
                    <apex:inputCheckbox onclick="checkAll(this)"/>
                </apex:facet>
                    <apex:inputCheckbox value="{!contacts.selected}" id="selectLine1"/>
            </apex:column>
            <apex:column headervalue="Contact Name">
                <apex:outputtext value="{!contacts.con.Name}"/>
            </apex:column>
            <apex:column headervalue="Account Name">
                <apex:outputtext value="{!contacts.con.Account.Name}"/>
            </apex:column>
            <apex:column headervalue="Title">
                <apex:outputtext value="{!contacts.con.Title}"/>
            </apex:column>
        </apex:pageBlockTable>  <br/><br/>

    </apex:outputpanel>
</apex:pageblocksection>
<!-- End of search results -->

<!-- Commandbutton to proceed to next screen -->
  <div style="position:relative;left:75px;">
      <apex:commandButton value="Next" action="{!processSelected}"/>
      <apex:commandbutton value="Cancel" action="{!Cancel}"/>
  </div>
<!-- End of Commandbutton -->
</apex:pageblock>
</apex:form>
</apex:page>

The Apex code for this page will be...

public class MassEmailFromCampaign {

/* Constructor Function. The campaign id is captured in this function */
public MassEmailFromCampaign(ApexPages.StandardController controller)
{
 cid=System.currentPageReference().getParameters().get('id');
}
/* Variable declarations */

Public String cid;                                                            // Stroes Campaign Id
public List<cContact> contactList {get; set;}                                 // Wrapper class which stores contact data and a boolean flag.
public Boolean selectAllCheckbox {get; set;}                                  // Stores checkbox data.
public boolean errormsg=false;                                                // Error msg. When no contact has been selected.
String userinput;                                                             // Contact Email
String userinp;                                                               // Contact Name

Public boolean displayboxes;

Public List<Contact> results = new List<Contact>();                                     // Contact search results.
Public List<Contact> selectedContactsstep2 = new List<Contact>();             // Selcted Contacts


/* End of Variable declarations */

/* Getter and setter methods for getting the user input ie. Contact name and email from the UI */

public String getuserinput(){return userinput;}
public void setuserinput(String userinp){this.userinput=userinp;}
public String getuserinp(){return userinp;}
public void setuserinp(String userinp){this.userinp=userinp;}


/*End of Getter and Setter methods */



/* Method to Search the contact database to fetch the query results */
public List<Contact> contactsearch()
{
     errormsg=false;
     contactList = new List<cContact>();
     for(Contact c : [select Account.Name,Name,FirstName,LastName,Email,title,Id from Contact where Email like :userinput+'%' and Name like :userinp+'%'])
     {
         contactList.add(new cContact(c));
     }

 return null;
}
/* End of method */


/* Method for returning the contact search results to the UI */
public List<cContact> getresults()
{

 return contactList;

}
/* End of Method */


/* Wrapper class to contain contact record and a boolean flag */
public class cContact
{
 public Contact con {get; set;}
 public Boolean selected {get; set;}

 /*This is the contructor method. When we create a new cContact object we pass a
 Contact that is set to the con property. We also set the selected value to false*/
 public cContact(Contact c)
 {
     con = c;
     selected = false;
 }
}
/* end of Wrapper class */


/* Method to fetch the selected records and send email to them */
public PageReference processSelected()
{

  List<Contact> selectedContacts = new List<Contact>();
  if (contactList!= null)
  {
     for(cContact cCon : getresults()){
        if(cCon.selected == true){
             selectedContacts.add(cCon.con);
         }
     }

     selectedContactsstep2=selectedContacts;
  }
 /* return error message if no contact is selected */
 if (selectedcontacts.size()==0)
 {
     errormsg=true;
     return null;
 }
 else
 {
     errormsg=false;
     String id=System.currentpagereference().getparameters().get('id');
     Pagereference p=new Pagereference ('/apex/MassEmailFromCampaignStep2');
     return p;
 }

}
public List<SelectOption> getItems()
{
 List<SelectOption> options = new List<SelectOption>();
 options.add(new SelectOption('YES','YES'));
 options.add(new SelectOption('NO','NO'));
 return options;
}


/* return error message if no contact is selected */
public boolean geterrormsg()
{
 return errormsg;
}


/* Method to cancel the entire process */
public Pagereference Cancel()
{
        Pagereference p =new Pagereference('/'+cid);
        return p;
}
       

}
Note that, "selectedcontacts" is the variable which holds the contacts you have selected. Use this for further processing. I have just redirected to another visualforce page, you can do your own stuff...

Post your queries....

No comments: