• Thomas Fuller
  • NEWBIE
  • 50 Points
  • Member since 2014

  • Chatter
    Feed
  • 0
    Best Answers
  • 0
    Likes Received
  • 0
    Likes Given
  • 8
    Questions
  • 6
    Replies
Hey Everyone,

Right now, I’m developing a new feature for our org, and I was wondering if any developers would mind looking over my code and guiding me to the best possible solution.

For this project, I am trying to create a visualforce page where the user can search through our org’s list of contacts and leads. The functionality is a lot like what you would see on a search layout. The user would enter filter keywords, a queried list would display in front of them, and then the user could select multiple records to pass onto an action or button.

User-added image

Luckily, I was able to successfully handle selecting multiple records and storing them in an Apex list. However, I am having an issue with developing a way for the user to see how many current records are selected, and see this number in real-time.

I tried to solve this by creating an integer in my Apex controller that would be increased if the user checks a checkbox, and decrease if the user unchecks the box. 
 
 
This seems that it works fine for selecting individual records, but I’m not sure how to make sure the “select all checkbox” updates the integer correctly, especially since I’m working with two different objects.

 
User-added image
 
User-added image

Here is my Visualforce Page:
<!-- Below is the Visualforce Markup for the two main pageBlockTables that each display the
      contact and lead records that were queried from the Apex Controller -->
	  
<apex:pageBlockTable id="results" value="{!contacts}" var="item">
		<apex:column width="23">
			<apex:facet name="header">
				<input type="checkbox" id="contactCB" onchange="checkAll(this);"/>
			</apex:facet>
			<apex:inputCheckbox styleClass="columnCheck" value="{!item.checked}" onchange="updateSelected(this)"/>
		</apex:column>
			<apex:column value="{!item.conObj.firstname}"/>
			<apex:column value="{!item.conObj.lastname}"/>
			<apex:column value="{!item.conObj.Title}"/>
			<apex:column value="{!item.conObj.account.Industry}"/>
			<apex:column value="{!item.conObj.Phone}"/>
			<apex:column value="{!item.conObj.Email}"/>
			<apex:column value="{!item.conObj.MailingCity}"/>
			<apex:column value="{!item.conObj.MailingState}"/>
		</apex:pageBlockTable>
		<apex:pageBlockTable id="resultsLead" value="{!leadList}" var="item">
		<apex:column width="23">
			<apex:facet name="header">
				<input type="checkbox" id="leadCB" onchange="checkAll2(this);"/>
			</apex:facet>
			<apex:inputCheckbox styleClass="columnCheck2" value="{!item.checked}" onchange="updateSelected(this)"/>
		</apex:column>
			<apex:column value="{!item.leadObj.firstname}"/>
			<apex:column value="{!item.leadObj.lastname}"/>
			<apex:column value="{!item.leadObj.Title}"/>
			<apex:column value="{!item.leadObj.Industry}"/>
			<apex:column value="{!item.leadObj.Company}"/>
			<apex:column value="{!item.leadObj.NumberOfEmployees}"/>
			<apex:column value="{!item.leadObj.AnnualRevenue}"/>
			<apex:column value="{!item.leadObj.Phone}"/>
			<apex:column value="{!item.leadObj.Email}"/>
			<apex:column value="{!item.leadObj.City}"/>
			<apex:column value="{!item.leadObj.State}"/>
</apex:pageBlockTable>

Here is my Javascript:
function checkAll(e) {
	if (j$(e).is(':checked')) {
		j$('.columnCheck').prop('checked', true);
	} else {
		j$('.columnCheck').prop('checked', false);
	}
}
function checkAll2(e) {
	if (j$(e).is(':checked')) {
		j$('.columnCheck2').prop('checked', true);
	} else {
		j$('.columnCheck2').prop('checked', false);
	}
}
function updateSelected(e) {
	if (j$(e).is(':checked')) {
		upSel();
	} else {
		downSel();
	}
}

Here is another slice of my visualforce:
<apex:actionFunction name="mainSearch" action="{!runMarketingSearch}" rerender="results, resultsLead, debug, selectedQuery, totalQuery">
   <apex:param name="title_mL" value="" />
   <apex:param name="industry_mL" value="" />
   <apex:param name="company_mL" value="" />
   <apex:param name="revenue_mL" value="" />
   <apex:param name="employNum_mL" value="" />
   <apex:param name="cityInput" value="" />
   <apex:param name="stateInput" value="" />
  </apex:actionFunction>
  <apex:actionFunction name="upSel" action="{!increaseSelected}" rerender="selectedQuery, totalQuery"/>
  <apex:actionFunction name="downSel" action="{!decreaseSelected}" rerender="selectedQuery, totalQuery"/>
<table width="100%" border="0">
<tr> 
  <td style="width:375px" valign="top">
 
   <apex:pageBlockButtons >
    <apex:commandButton action="{!saveObjects}" value="Save"/>
    <apex:commandButton action="{!next}" value="See Results"/>
   </apex:pageBlockButtons>
...

Here is my Apex Controller:
public with sharing class mLSearchController{
	private String soqlCon {get;set;}
	private String soqlLead {get;set;}
	public List<contactWrapper> contacts {get;set;}
	public List<contactWrapper> leadList {get;set;}
	public List<contactWrapper> selectedList {        
		get {
            if (selectedList == null) selectedList = new List<contactWrapper>();
            return selectedList;
        }
        set;
        }
	public List<contactWrapper> debugSoql {
	    get { return selectedList; }
	    set;
  	}
  	public Integer queryTotal {get;set;}
  	public Integer queryContactSel {get;set;}
  	public Integer queryLeadTotalSel {get;set;}
  	public Integer querySel {get;set;}
	
	
	public mLSearchController() {}
  
	public void runQuery() {

		try {

		} catch (Exception e) {
			ApexPages.addMessage(new ApexPages.Message(ApexPages.Severity.ERROR, 'Ooops!'));
		}
	}
	
	public PageReference runMarketingSearch() {
		String title_mL = Apexpages.currentPage().getParameters().get('title_mL');
		String industry_mL = Apexpages.currentPage().getParameters().get('industry_mL');
		String company_mL = Apexpages.currentPage().getParameters().get('company_mL');
		String revenue_mL = Apexpages.currentPage().getParameters().get('revenue_mL');
		String employNum_mL = Apexpages.currentPage().getParameters().get('employNum_mL');
		String cityInput = Apexpages.currentPage().getParameters().get('cityInput');
		String stateInput = Apexpages.currentPage().getParameters().get('stateInput');
		soqlCon = 'select firstname, lastname, Title, Email, Phone, account.Industry, MailingCity, MailingState, LastActivityDate from Contact WHERE account.name != null and LastActivityDate != LAST_N_DAYS:60';
		soqlLead = 'select firstname, lastname, Title, Phone, Email, Industry, Company, NumberOfEmployees, AnnualRevenue, City, State from Lead WHERE Company != null and LastActivityDate != LAST_N_DAYS:60';
      	if (!title_mL.equals('')) {
      		soqlCon += ' and Title LIKE \'%' + String.escapeSingleQuotes(title_mL) + '%\'';
      		soqlLead += ' and Title LIKE \'%' + String.escapeSingleQuotes(title_mL) + '%\'';
      	}
      	if (!industry_mL.equals('')) {
      		soqlCon += ' and account.Industry LIKE \'%' + String.escapeSingleQuotes(industry_mL) + '%\'';
      		soqlLead += ' and Industry LIKE \'%' + String.escapeSingleQuotes(industry_mL) + '%\'';
      	}
      	if (!cityInput.equals('')) {
      		soqlCon += ' and MailingCity LIKE \'' + String.escapeSingleQuotes(cityInput) + '%\'';
      		soqlLead += ' and City LIKE \'' + String.escapeSingleQuotes(cityInput) + '%\'';
      	}
      	if (!stateInput.equals('')) {
      		soqlCon += ' and MailingState LIKE \'' + String.escapeSingleQuotes(stateInput) + '%\'';
      		soqlLead += ' and State LIKE \'' + String.escapeSingleQuotes(stateInput) + '%\'';
      	}
      	if (!company_mL.equals('')) {
      		soqlLead += ' and Company LIKE \'%' + String.escapeSingleQuotes(company_mL) + '%\'';
      	}
      	
      	//if (!revenue_mL.equals('')) soqlLead += ' and AnnualRevenue LIKE \'%' + String.escapeSingleQuotes(revenue_mL) + '%\'';
      	if (revenue_mL == 'tier1_mL') {
      		soqlLead += ' and (AnnualRevenue < 1000000.00)';
      	} else if (revenue_mL == 'tier2_mL') {
      		soqlLead += ' and (AnnualRevenue >= 1000000.00 AND AnnualRevenue < 5000000.00)';
      	} else if (revenue_mL == 'tier3_mL') {
      		soqlLead += ' and (AnnualRevenue >= 5000000.00 AND AnnualRevenue < 10000000.00)';
      	} else if (revenue_mL == 'tier4_mL') {
      		soqlLead += ' and (AnnualRevenue >= 10000000.00 AND AnnualRevenue < 25000000.00)';
      	} else if (revenue_mL == 'tier5_mL') {
      		soqlLead += ' and (AnnualRevenue >= 25000000.00 AND AnnualRevenue < 50000000.00)';
      	} else if (revenue_mL == 'tier6_mL') {
      		soqlLead += ' and (AnnualRevenue >= 50000000.00 AND AnnualRevenue < 100000000.00)';
      	} else if (revenue_mL == 'tier7_mL') {
      		soqlLead += ' and (AnnualRevenue >= 100000000.00 AND AnnualRevenue < 250000000.00)';
      	} else if (revenue_mL == 'tier8_mL') {
      		soqlLead += ' and (AnnualRevenue >= 250000000.00 AND AnnualRevenue < 500000000.00)';
      	} else if (revenue_mL == 'tier9_mL') {
      		soqlLead += ' and (AnnualRevenue >= 500000000.00 AND AnnualRevenue < 2500000000.00)';
      	} else if (revenue_mL == 'tier10_mL') {
      		soqlLead += ' and (AnnualRevenue >= 2500000000.00)';
      	} else {
      		
      	}
      	
      	
      	if (employNum_mL == 'tier1_mL') {
      		soqlLead += ' and (NumberOfEmployees >= 1 AND NumberOfEmployees <= 100)';
      	} else if (employNum_mL == 'tier2_mL') {
      		soqlLead += ' and (NumberOfEmployees >= 101 AND NumberOfEmployees <= 500)';
      	} else if (employNum_mL == 'tier3_mL') {
      		soqlLead += ' and (NumberOfEmployees >= 501 AND NumberOfEmployees <= 3500)';
      	} else if (employNum_mL == 'tier4_mL') {
      		soqlLead += ' and (NumberOfEmployees > 3500)';
      	} else {
      		
      	}
      		contacts = new List<contactWrapper>();
      		leadList = new List<contactWrapper>();
			for (Contact conRec : Database.query(soqlCon + ' limit 20')) {
				contactWrapper cr = new contactWrapper(conRec);
				contacts.add(cr);
			}
			for (Lead leadRec : Database.query(soqlLead + ' limit 20')) {
				contactWrapper lr = new contactWrapper(leadRec);
				leadList.add(lr);
			}
			queryTotal = contacts.size() + leadList.size();
			querySel = selectedList.size();
    	return null;
	}
	
	public PageReference increaseSelected() {
		querySel++;
		return null;
	}
	
	public PageReference decreaseSelected() {
		querySel--;
		return null;
	}
	
	/*public PageReference contactAllSelected() {
		querySel = contacts.size();
		return null;
	}
	
	public PageReference leadAllSelected() {
		querySel = 0;
		return null;
	}*/
    
    public PageReference next() {
	selectedList.clear();
	for (contactWrapper cw : contacts) {
		if (cw.checked)
			selectedList.add(new contactWrapper(cw.conObj));
	}
	if (selectedList.size() > 0) {
		debugSoql = new List<contactWrapper>(selectedList);
		querySel = selectedList.size();
		return Page.ML_Search_Layout;
	} else {
		ApexPages.addMessage(new ApexPages.message(ApexPages.severity.ERROR,'Please select at least one Category.'));
		return null;
	}       
} 

}

Thanks so much for your time. I’m grateful for any help or suggestions on this issue.
Hey everyone,

I am currently working on a project that our organization is going to implement in our salesforce org, in order to increase user’s efficiency searching for specific contacts and leads. I proposed to create a visualforce page and an Apex controller that would allow users to search for contacts and leads in real time using javascript/jQuery/ajax. Everything seems to be working flawlessly, except for one of the two picklist fields, Revenue and Number of Employees. For both of these fields, I gave them both a list of ranged options, each representing a different tier for their respective values. After the user selects an option, the page’s Apex Controller would handle all values that were passed using conditional statements. Here are the two picklists:
<tr>
<td>
  <p>Revenue:</p>
</td>
<td>                         
  <select id="revenue_mL" onchange="runSearch();">
   <option value=""></option>
   <option value="tier1_mL">Less than $1 Million</option>
   <option value="tier2_mL">$1 million - $5 million</option>
   <option value="tier3_mL">$5 million - $10 million</option>
   <option value="tier4_mL">$10 million - under $25 million</option>
   <option value="tier5_mL">$25 million - under $50 million</option>
   <option value="tier6_mL">$50 million - under $100 million</option>
   <option value="tier7_mL">$100 million - under $250 million</option>
   <option value="tier8_mL">$250 million - under $500 million</option>
   <option value="tier9_mL">$500 million - under $2.5 billion</option>
   <option value="tier10_mL">Over $2.5 billion</option>
  </select>
</td>
</tr>
<tr>
<td>
  <p>Employees:</p>
</td>
<td>
  <select id="employNum_mL" onchange="runSearch();">
   <option value=""></option>
   <option value="tier1_mL">1-100 Employees</option>
   <option value="tier2_mL">101-500 Employees</option>
   <option value="tier3_mL">501-3,500 Employees</option>
   <option value="tier4_mL">3,500+ Employees</option>
  </select>
</td>
</tr>
Both picklists have the event, “onchange”, attributed to them. So, anytime the picklist is changed to a different value, the runSearch() function is executed. The function, runSearch(), is used to “scoop” all the data from the form using an <apex:actionFunction> tag. Here is the runSearch() javascript function:
function runSearch() {
	var e = document.getElementById("employNum_mL");
	var strUser = e.options[e.selectedIndex].value;
	var f = document.getElementById("revenue_mL");
	var strUser2 = f.options[f.selectedIndex].value;
	mainSearch(
		document.getElementById("title_mL").value,
		document.getElementById("industry_mL").value,
		document.getElementById("company_mL").value,
		strUser2,
		strUser,
		document.getElementById("zipInput").value
	);
}
Here is the actionFunction tag that sends the form parameters to the apex controller:
<apex:actionFunction name="mainSearch" action="{!runMarketingSearch}" rerender="results, resultsLead">
	  <apex:param name="title_mL" value="" />
	  <apex:param name="industry_mL" value="" />
	  <apex:param name="company_mL" value="" />
	  <apex:param name="revenue_mL" value="" />
	  <apex:param name="employNum_mL" value="" />
	  <apex:param name="zipInput" value="" />
  </apex:actionFunction>
Finally, all the data ends up in the Apex Controller. Here is the apex controller:
public with sharing class mLSearchController{
private String soqlCon {get;set;}
private String soqlLead {get;set;}
public List<Contact> contacts {get;set;}
public List<Lead> leadList {get;set;}

public mLSearchController() {
  runQuery();
}
 
public void runQuery() {
  try {
   contacts = Database.query(soqlCon + ' limit 20');
   leadList = Database.query(soqlLead + ' limit 20');
  } catch (Exception e) {
   ApexPages.addMessage(new ApexPages.Message(ApexPages.Severity.ERROR, 'Ooops!'));
  }
}

public PageReference runMarketingSearch() {
  String title_mL = Apexpages.currentPage().getParameters().get('title_mL');
  String industry_mL = Apexpages.currentPage().getParameters().get('industry_mL');
  String company_mL = Apexpages.currentPage().getParameters().get('company_mL');
  String revenue_mL = Apexpages.currentPage().getParameters().get('revenue_mL');
  String employNum_mL = Apexpages.currentPage().getParameters().get('employNum_mL');
  String zipcode = Apexpages.currentPage().getParameters().get('zipInput');
  soqlCon = 'select firstname, lastname, Title, Email, Phone, account.Industry, MailingCity, MailingState, MailingPostalCode from Contact where account.name != null';
  soqlLead = 'select firstname, lastname, Title, Phone, Email, Industry, Company, NumberOfEmployees, AnnualRevenue, City, State, PostalCode from Lead where Company != null';
       if (!title_mL.equals('')) {
        soqlCon += ' and Title LIKE \'%' + String.escapeSingleQuotes(title_mL) + '%\'';
        soqlLead += ' and Title LIKE \'%' + String.escapeSingleQuotes(title_mL) + '%\'';
       }
       if (!industry_mL.equals('')) {
        soqlCon += ' and account.Industry LIKE \'%' + String.escapeSingleQuotes(industry_mL) + '%\'';
        soqlLead += ' and Industry LIKE \'%' + String.escapeSingleQuotes(industry_mL) + '%\'';
       }
       if (!zipcode.equals('')) {
        soqlCon += ' and MailingPostalCode LIKE \'' + String.escapeSingleQuotes(zipcode) + '%\'';
        soqlLead += ' and PostalCode LIKE \'' + String.escapeSingleQuotes(zipcode) + '%\'';
       }
       if (!company_mL.equals('')) {
        soqlLead += ' and Company LIKE \'%' + String.escapeSingleQuotes(company_mL) + '%\'';
       }
 
       // ===============================================================================================
  // THIS IS THE REVENUE CONDITIONAL STATEMENTS ALL SEEM TO WORK EXCEPT FOR tier9_mL AND tier10_mL
  // ===============================================================================================
       if (revenue_mL == 'tier1_mL') {
        soqlLead += ' and (AnnualRevenue < 1000000)';
       } else if (revenue_mL == 'tier2_mL') {
        soqlLead += ' and (AnnualRevenue >= 1000000 AND AnnualRevenue < 5000000)';
       } else if (revenue_mL == 'tier3_mL') {
        soqlLead += ' and (AnnualRevenue >= 5000000 AND AnnualRevenue < 10000000)';
       } else if (revenue_mL == 'tier4_mL') {
        soqlLead += ' and (AnnualRevenue >= 10000000 AND AnnualRevenue < 25000000)';
       } else if (revenue_mL == 'tier5_mL') {
        soqlLead += ' and (AnnualRevenue >= 25000000 AND AnnualRevenue < 50000000)';
       } else if (revenue_mL == 'tier6_mL') {
        soqlLead += ' and (AnnualRevenue >= 50000000 AND AnnualRevenue < 100000000)';
       } else if (revenue_mL == 'tier7_mL') {
        soqlLead += ' and (AnnualRevenue >= 100000000 AND AnnualRevenue < 250000000)';
       } else if (revenue_mL == 'tier8_mL') {
        soqlLead += ' and (AnnualRevenue >= 250000000 AND AnnualRevenue < 500000000)';
       } else if (revenue_mL == 'tier9_mL') {
        soqlLead += ' and (AnnualRevenue >= 500000000 AND AnnualRevenue < 2500000000)';
       } else if (revenue_mL == 'tier10_mL') {
        soqlLead += ' and (AnnualRevenue >= 2500000000)';
       } else {
       
       }
      
       if (employNum_mL == 'tier1_mL') {
        soqlLead += ' and (NumberOfEmployees >= 1 AND NumberOfEmployees <= 100)';
       } else if (employNum_mL == 'tier2_mL') {
        soqlLead += ' and (NumberOfEmployees >= 101 AND NumberOfEmployees <= 500)';
       } else if (employNum_mL == 'tier3_mL') {
        soqlLead += ' and (NumberOfEmployees >= 501 AND NumberOfEmployees <= 3500)';
       } else if (employNum_mL == 'tier4_mL') {
        soqlLead += ' and (NumberOfEmployees > 3500)';
       } else {
       
       }
       runQuery();
     return null;
}

}
   The problem that I am faced with is that the Revenue picklist is not functioning correctly, while the Number of Employees picklist is working fine. The apex seems to be appending the correct data from the revenue picklist, except for the last two values, tier9_mL and tier10_mL. Here are two lead use cases that are in my sandbox I do have two Lead cases. One lead has an annual revenue of $10,000,000, and another has $4,000,000,000. For some reason, the query is able to pull the $10 million lead, but not the $4 billion. I was hoping that any more experienced developers might be kind enough to look at my problem and help guide me to where the issue is. Any suggestions, ideas, etc. are greatly appreciated. Thanks so much for your time.
Hey everybody,

I am currently working on a Visualforce component where it will display a filtered related list on the main page layout of the "Projects" ("PE_Projects__c") custom object. I've looked up various sources on how to achieve a filtered related list, and I've created a rough bit of code to test. However, everytime I load a Projects page, an error message appears in the Visualforce window saying: "Content cannot be displayed: Cannot modify a collection while it is being iterated." After researching this error a bit, I've tried using the addAll() method to copy a finished list to the "projConList" list. However, I'm still back at square one.


Visualforce Code:
<apex:page standardController="PE_Projects__c" extensions="ProjectRolesMainClass">
     <apex:form>
    <apex:pageBlock >
        <apex:pageBlockTable value="{!projConList}" var="p">
            <apex:column value="{!p.Name}"/>
            <apex:column value="{!p.Project_Contacts_con__c}"/>
        </apex:pageBlockTable>
    </apex:pageBlock>
    </apex:form>
</apex:page>

Apex Code:
public class ProjectRolesMainClass {
    public List<Project_Contacts__c> projConList{get;set;}
    public ProjectRolesMainClass(ApexPages.StandardController controller) {
        List<Project_Contacts__c> tempList=[select Id, Project_Contacts_con__c from Project_Contacts__c where Project_Contacts_proj__c=:ApexPages.currentPage().getParameters().get('id')];
        for(Project_Contacts__c PR:tempList) {
			tempList.add(PR);
        }
        projConList.addAll(tempList);
    }
}


I was hoping some experienced VF developers would mind helping a newbie out by providing any suggestions, ideas, solutions, etc.

Thanks so much for your time.
Hey everyone,

I'm new to Apex and VisualForce, and I wanted to see if any developers out there could give a newbie like me some direction in how to tackle this project I'm working on.

In our Org, we have a custom object called "Projects", that is a child of the "Accounts" object. This object is used to store info on the status, cost, hours spent, etc. of each of our firm's projects. I am currently developing a way to easily store a number of project-specific contacts in a related list under each project. Each related list should have a default contact that is the default for all projects in the same account, but also should have the ability to add or subtract from the list.

In order to solve this, I've proposed creating a custom "junction" object to bridge "Projects" and "Contacts" under the same account. I am planning on using APEX and VisualForce to create a related list that can be set with default contacts when created, but also be flexible enough to allow the user to add new contacts for that specific project. Once all needed contacts are in the related list, the user is able to fire a Conga Composer email that sends an email to all those contacts within the related list.

At this point, this is the best solution that I have come up with. Like I said, I am new to apex coding and VisualForce, so any and all suggestions or ideas are greatly appreciated.

Thank you for your time,
Thomas
Hey,

I'm in the process of developing a custom button on Salesforce that is able to toggle a checkbox on and off.
At this point, I am using the Salesforce AJAX Toolkit in order to do the main backend functions of the custom button.
I have the backend working, but I was hoping I could have the custom button label toggle between "Start Process" and "End Process".
To do this, I assume I would need the custom button to change it's own label.
I attempted this by placing these lines in my code:
    var toggleButton = new sforce.SObject("Lead");
    var toggleButtonT ="{!Lead.Begin_Touch_Process}"; //my attempt to reference the button
    toggleButtonT.Id = "00bc0000000QoaE"; // my attempt to reference the button id
    toggleButtonT.Label = "test"; // entering new value for the button label
    result = sforce.connection.update([toggleButton]); // updating the button
NOTE:  {!RequireScript} is already mentioned in script.
It's also entirely possible that I cannot change the name of the button with the AJAX Toolkit.

I am very new to Salesforce and learning about this tool, so any ideas or suggestions will be greatly appreciated!


Thanks,
TF