• b.d
  • NEWBIE
  • 25 Points
  • Member since 2007

  • Chatter
    Feed
  • 1
    Best Answers
  • 0
    Likes Received
  • 0
    Likes Given
  • 2
    Questions
  • 4
    Replies

I have been working to expose a process using Visualforce Mobile on BlackBerry.

 

I found that initial load performance (presumabaly due to a login process) is very bad.

 

For testing I created a Visualforce page and set the showHeaders and standardStyles options to false.  Thus the page that is returned is very basic consisting of just the default content for a new Visualforce page.

 

Even with this various page I found that initially opening the Visualforce page by selecting the Visualforce tab from the mobile client is very slow (i.e. 60+ seconds).

 

It is interesting to note that selecting the refresh option from the menu while in the Visualforce tab on the mobile device reloads the page in less than 5 seconds.

 

Further the problem persists even if I enable the WiFi option on my BlackBerry.

 

Using the same WiFi connection the same Visualforce page loads instantly on my PC.

 

Any ideas why the initial connect would take so long?

 

Anyone sucessfully using the Visualforce Mobile option for BlackBerry?

 

Thanks!

 

James

I am having a problem with the Visualforce ajax components. 

 

I have a selectCheckboxes for which I want to dynamically populate the selected boxes as a function of two other components on the SObject. The selected items is a property on the controller, a getter. The issue is that when the ajax call is made, the fields that this property is using to calculate the items that should be selected do not seem to be set on the controller. My understanding is that they are not updated on the server side, because they are outside the action region of the ajax call. I tried adding those components to the rerender attribute, but have not seen the desired behavior. Is there a way to make sure the setters for those fields are called before the rest of the methods in question are called?

 

 

<apex:page standardController="Call_Report__c"
	extensions="CallReportExtension">
	<apex:form >
		<apex:pageBlock title="Call Report">
			<apex:messages style="color:red"/>
			<apex:pageBlockButtons >
				<apex:commandButton action="{!saveCall}" value="Save" />
				<apex:commandButton action="{!Cancel}" value="Cancel" />
			</apex:pageBlockButtons>

			<apex:pageBlockSection title="Call Details" columns="2">
				<apex:inputField value="{!call.Account__c}" id="acct"
					required="True" />
				<apex:inputField value="{!call.Contact__c}" />
				
				</apex:actionRegion>
                <apex:pageBlockSectionItem >
                    <apex:outputLabel value="               " for="blank"/>
                    <apex:outputText value="                " id="blank"/>
                </apex:pageBlockSectionItem>
				
				<br />
				<br />
			</apex:pageBlockSection>
			<apex:pageBlockSection columns="2">
				<apex:actionRegion >
					<b> <apex:pageBlockSectionItem >
						<apex:outputLabel value="Select Topic:" for="topic" />
						<apex:inputField value="{!Call_Report__c.Topic__c}" id="topic"
							required="true">
							<apex:actionSupport event="onchange" rerender="detailInput">
							</apex:actionSupport>
						</apex:inputField>
					</apex:pageBlockSectionItem> </b>
				</apex:actionRegion>
				<apex:outputPanel id="detailInput">
					<b> <apex:pageBlockSectionItem rendered="{!Call_Report__c.Topic__c=='Tickers'}">
						<apex:outputLabel value="Select Tickers: " for="tickerInput" />
						<apex:inputField value="{!Call_Report__c.Tickers__c}"
							required="{!Call_Report__c.Topic__c=='Tickers'}" id="tickerInput" />
					</apex:pageBlockSectionItem> <apex:pageBlockSectionItem rendered="{!Call_Report__c.Topic__c=='Industry'}">
						<apex:outputLabel value="Select Industry: " for="sectorInput" />
						<apex:inputField value="{!Call_Report__c.Sector__c}"
							required="{!Call_Report__c.Topic__c=='Industry'}"
							id="sectorInput" />
					</apex:pageBlockSectionItem> <apex:pageBlockSectionItem rendered="{!Call_Report__c.Topic__c=='Specific Bond'}">
						<apex:outputLabel value="Select Security:" for="bondInput" />
						<apex:inputField value="{!Call_Report__c.Security__c}"
							required="{!Call_Report__c.Topic__c=='Specific Bond'}"
							id="bondInput" />
					</apex:pageBlockSectionItem> </b>
				</apex:outputPanel>

				<apex:actionRegion >
                
					<apex:pageBlockSectionItem >
						<apex:outputLabel style="font-weight:bold;"
							value="Select Specific Employees to Notify"
							for="specificEmpsSelector" />

						<apex:inputCheckbox id="specificEmpsSelector"
							value="{!renderSpecificEmps}">
							<apex:actionSupport action="{!setFields}" event="onchange" rerender="checks,topic,detailInput,acct">
							</apex:actionSupport>
						</apex:inputCheckbox>

					</apex:pageBlockSectionItem>

				</apex:actionRegion>
				<!-- the following element is included because the controller only has access to fields on the page,
                so this saves a query in the controller.  -->
				<apex:outputText value="{!Call_Report__c.Specific_Employees__c}"
					rendered="false" />
			</apex:pageBlockSection>
			<apex:outputPanel id="checks">
			
			</br> </b>
				<apex:selectCheckboxes value="{!chosenEmployeeNames}"
					layout="pageDirection" rendered="{!renderSpecificEmps}">
					<apex:selectOptions value="{!availableEmployeeNames}" />
				</apex:selectCheckboxes>
			</apex:outputPanel>
		</apex:pageBlock>


	</apex:form>
</apex:page>

 and the controller is here:

 

 

 public static final String TICKER_TOPIC = 'Issuer';
    public static final String SECTOR_TOPIC = 'Industry';
    public static final String SPECIFIC_BOND_TOPIC = 'Specific Bond';
    public static final String DEFAULT_HOURS = '0';
    public static final String DEFAULT_MIN = '10';
    public static final String LIST_VIEW_URL = 'https://na7.salesforce.com/a0c/o';
    
    
    private Map<String, String> parameters;   
    public Contact newContact{get; private set;} 	
   // public String newContactFirst {get; set;}
   // public String newContactLast {get;set;}
    public Boolean creatingNewContact {get; set;} 
    
    public Call_Report__c call{
    	get{
        if (call == null){
            call = (Call_Report__c) controller.getRecord();
        }
        return call;
        }
     set;}
     
    private ApexPages.StandardController controller;
   
    
    public Boolean isEnabledTickers{ 
        get{
        	System.debug('~~~~~~~RENDERING TICKERS');
        	
            return parameters.get('topicSelection') == TICKER_TOPIC;
        }
    }
    
    public Boolean isEnabledSectors{
    	get {
    		System.debug('~~~~~~RENDERING SECTORS');
    		return parameters.get('topicSelection') == SECTOR_TOPIC;
    	
    	} 
    }

    public Boolean isEnabledBonds{
    	get {
    		System.debug('~~~~~~~~~~RENDERING SPECIFIC BONDS');
    		return parameters.get('topicSelection') == SPECIFIC_BOND_TOPIC;
    	}
    }
  
 
    public List<SelectOption> availableEmployeeNames {get; private set;}
    
    public ID[] chosenEmployeeNames {
    	get{
    	   EmployeeCollection interested = CallReportManager.determineInterested(call);
    	   return interested.getIDs();
        } 
    set;}
   
    
    public Map<String, Employee__c> employeeIdMap;
    public Map<String, ID> nameIDMap {
    	get{
    		Map<String, ID> m = new Map<String, ID>();
    		for (Employee__c  e: employeeIdMap.values()){
    		     m.put(e.Name, e.Id);
    			
    		}
    		return m; 
    	}
    }
    
    private void populateEmployeeMap(){
    	EmployeeCollection ec = new EmployeeSelector().whereCompanyEmailIsNotNull().whereIsCurrent().execute();
    	employeeIdMap = new Map<String, Employee__c>();
    	for (Employee__c e : ec.getList()){
    		employeeIdMap.put(e.Id, e);
    	}
    }
    
    private void getSelectOptionList(){
    	
    	//NOTE: this is convoluted and weird because Apex does not have a built-in sort
    	//for anything other than primitives, so thanks guys.
    	List<String> names = new List<String>(nameIdMap.keySet());
    	names.sort();
    	System.assert(names.size() > 0, 'employeeIDMap not populated!');
    	availableEmployeeNames = new List<SelectOption>();
    	for (String name: names){
    	   ID id = nameIdMap.get(name);
    		availableEmployeeNames.add(new SelectOption(id, name));
    	}
    	
    }
    
    private String formatSpecificEmployees(){
    	String s = call.Specific_Employees__c;
    	
    	if (s == null){
    		s= '';
    	}
    	if (chosenEmployeeNames==null){
    	   return s;
    	  
    	}
    	System.debug('~~~~~~~~~~User has selected '+ chosenEmployeeNames.size() + 'employees to notify.');
    	for (String theId : chosenEmployeeNames){
    	   //String idString = (String) o.getValue();
    	   s +=  theId + ',';
    	}
    	return s;//s.substring(0, s.lastIndexOf(','));
    }
    
    public CallReportExtension(ApexPages.StandardController c){
    	controller = c;
    	parameters = ApexPages.currentPage().getParameters();
    	chosenEmployeeNames = new List<ID>();
    	call.Call_Time__c = (call.Call_Time__c == null) ? Datetime.now(): call.Call_Time__c;
    	call.Duration_Hours__c=(call.Duration_Hours__c == null) ? CallReportExtension.DEFAULT_HOURS : call.Duration_Hours__c;
    	call.Duration_Minutes__c= (call.Duration_Minutes__c == null) ?  CallReportExtension.DEFAULT_MIN : call.Duration_Minutes__c;
    	populateEmployeeMap();
    	getSelectOptionList();
    	this.newContact = new Contact();
    	
    }
    private void addTopicToNotes(){
    	String tickerstring = 'All Tickers discussed: ';
    	String industrystring = 'Industry discussed: ';
    	String bondstring = 'Bond discussed: ';
    	if (call.Topic__c == 'Tickers'){
    		if (call.Call_Notes__c.contains(tickerstring)) {
    		 call.Call_Notes__c = call.Call_Notes__c;
    		 }else{
    		  call.Call_Notes__c = tickerstring + call.Tickers__c + '\n\n' + call.Call_Notes__c;
    		}
    	}
    	if (call.Topic__c == 'Industry'){
    		if (call.Call_Notes__c.contains(industrystring)) { 
    			call.Call_Notes__c = call.Call_Notes__c;
    		}else{
    		  call.Call_Notes__c = industrystring + call.Sector__r.name + '\n\n' + call.Call_Notes__c;
    		}
    	}
    	if (call.Topic__c == 'Specific Bond'){
    		if (call.Call_Notes__c.contains(bondstring)) {
    		  call.Call_Notes__c = call.Call_Notes__c;
    		}else{
    		  call.Call_Notes__c =  + call.Security__r.name + '\n\n' + call.Call_Notes__c;
    		}
    	}
    }
    
    public Employee__c caller{
    	get{
    		if (caller == null){
    		  ID uid = UserInfo.getUserID();
    		  EmployeeCollection emps = new EmployeeSelector().whereIsCurrent().whereUserIn(new ID[]{uid}).execute();
    		  if (emps.size() > 0){
    		  	caller = emps.getList().get(0);
    		  }else{
    		  	throw new InvalidEmployeeSetupException('There is no employee record associated with the current user-- contact HR or your IT staff to correct this configuration');
    		  }
    		}
    		return caller;
    	}
    	
    	private set;
    }
    
    
 
    public void setFields(){
    	
    }
    
    public Boolean renderSpecificEmps {
    	get; 
        set;
        
    }
    
    class InvalidEmployeeSetupException extends Exception{}
}

 

 

 

  • July 26, 2010
  • Like
  • 0
I was wondering if anyone had any similar issues:

I created and tested a trigger + Apex class to send a plain-text email when certain changes were made to Account objects. It behaves as I would expect in the developer environment.

When I deploy (successfully) to the production environment, I never receive the emails. I have tested that I am able to receive emails from Salesforce in general (all the IP addresses), and the specific user is able to send emails as well.

Is there anywhere to see a log of email creations, of calls to the Apex class, etc.? Or am I just missing something obvious?
  • December 29, 2009
  • Like
  • 0

I am having a problem with the Visualforce ajax components. 

 

I have a selectCheckboxes for which I want to dynamically populate the selected boxes as a function of two other components on the SObject. The selected items is a property on the controller, a getter. The issue is that when the ajax call is made, the fields that this property is using to calculate the items that should be selected do not seem to be set on the controller. My understanding is that they are not updated on the server side, because they are outside the action region of the ajax call. I tried adding those components to the rerender attribute, but have not seen the desired behavior. Is there a way to make sure the setters for those fields are called before the rest of the methods in question are called?

 

 

<apex:page standardController="Call_Report__c"
	extensions="CallReportExtension">
	<apex:form >
		<apex:pageBlock title="Call Report">
			<apex:messages style="color:red"/>
			<apex:pageBlockButtons >
				<apex:commandButton action="{!saveCall}" value="Save" />
				<apex:commandButton action="{!Cancel}" value="Cancel" />
			</apex:pageBlockButtons>

			<apex:pageBlockSection title="Call Details" columns="2">
				<apex:inputField value="{!call.Account__c}" id="acct"
					required="True" />
				<apex:inputField value="{!call.Contact__c}" />
				
				</apex:actionRegion>
                <apex:pageBlockSectionItem >
                    <apex:outputLabel value="               " for="blank"/>
                    <apex:outputText value="                " id="blank"/>
                </apex:pageBlockSectionItem>
				
				<br />
				<br />
			</apex:pageBlockSection>
			<apex:pageBlockSection columns="2">
				<apex:actionRegion >
					<b> <apex:pageBlockSectionItem >
						<apex:outputLabel value="Select Topic:" for="topic" />
						<apex:inputField value="{!Call_Report__c.Topic__c}" id="topic"
							required="true">
							<apex:actionSupport event="onchange" rerender="detailInput">
							</apex:actionSupport>
						</apex:inputField>
					</apex:pageBlockSectionItem> </b>
				</apex:actionRegion>
				<apex:outputPanel id="detailInput">
					<b> <apex:pageBlockSectionItem rendered="{!Call_Report__c.Topic__c=='Tickers'}">
						<apex:outputLabel value="Select Tickers: " for="tickerInput" />
						<apex:inputField value="{!Call_Report__c.Tickers__c}"
							required="{!Call_Report__c.Topic__c=='Tickers'}" id="tickerInput" />
					</apex:pageBlockSectionItem> <apex:pageBlockSectionItem rendered="{!Call_Report__c.Topic__c=='Industry'}">
						<apex:outputLabel value="Select Industry: " for="sectorInput" />
						<apex:inputField value="{!Call_Report__c.Sector__c}"
							required="{!Call_Report__c.Topic__c=='Industry'}"
							id="sectorInput" />
					</apex:pageBlockSectionItem> <apex:pageBlockSectionItem rendered="{!Call_Report__c.Topic__c=='Specific Bond'}">
						<apex:outputLabel value="Select Security:" for="bondInput" />
						<apex:inputField value="{!Call_Report__c.Security__c}"
							required="{!Call_Report__c.Topic__c=='Specific Bond'}"
							id="bondInput" />
					</apex:pageBlockSectionItem> </b>
				</apex:outputPanel>

				<apex:actionRegion >
                
					<apex:pageBlockSectionItem >
						<apex:outputLabel style="font-weight:bold;"
							value="Select Specific Employees to Notify"
							for="specificEmpsSelector" />

						<apex:inputCheckbox id="specificEmpsSelector"
							value="{!renderSpecificEmps}">
							<apex:actionSupport action="{!setFields}" event="onchange" rerender="checks,topic,detailInput,acct">
							</apex:actionSupport>
						</apex:inputCheckbox>

					</apex:pageBlockSectionItem>

				</apex:actionRegion>
				<!-- the following element is included because the controller only has access to fields on the page,
                so this saves a query in the controller.  -->
				<apex:outputText value="{!Call_Report__c.Specific_Employees__c}"
					rendered="false" />
			</apex:pageBlockSection>
			<apex:outputPanel id="checks">
			
			</br> </b>
				<apex:selectCheckboxes value="{!chosenEmployeeNames}"
					layout="pageDirection" rendered="{!renderSpecificEmps}">
					<apex:selectOptions value="{!availableEmployeeNames}" />
				</apex:selectCheckboxes>
			</apex:outputPanel>
		</apex:pageBlock>


	</apex:form>
</apex:page>

 and the controller is here:

 

 

 public static final String TICKER_TOPIC = 'Issuer';
    public static final String SECTOR_TOPIC = 'Industry';
    public static final String SPECIFIC_BOND_TOPIC = 'Specific Bond';
    public static final String DEFAULT_HOURS = '0';
    public static final String DEFAULT_MIN = '10';
    public static final String LIST_VIEW_URL = 'https://na7.salesforce.com/a0c/o';
    
    
    private Map<String, String> parameters;   
    public Contact newContact{get; private set;} 	
   // public String newContactFirst {get; set;}
   // public String newContactLast {get;set;}
    public Boolean creatingNewContact {get; set;} 
    
    public Call_Report__c call{
    	get{
        if (call == null){
            call = (Call_Report__c) controller.getRecord();
        }
        return call;
        }
     set;}
     
    private ApexPages.StandardController controller;
   
    
    public Boolean isEnabledTickers{ 
        get{
        	System.debug('~~~~~~~RENDERING TICKERS');
        	
            return parameters.get('topicSelection') == TICKER_TOPIC;
        }
    }
    
    public Boolean isEnabledSectors{
    	get {
    		System.debug('~~~~~~RENDERING SECTORS');
    		return parameters.get('topicSelection') == SECTOR_TOPIC;
    	
    	} 
    }

    public Boolean isEnabledBonds{
    	get {
    		System.debug('~~~~~~~~~~RENDERING SPECIFIC BONDS');
    		return parameters.get('topicSelection') == SPECIFIC_BOND_TOPIC;
    	}
    }
  
 
    public List<SelectOption> availableEmployeeNames {get; private set;}
    
    public ID[] chosenEmployeeNames {
    	get{
    	   EmployeeCollection interested = CallReportManager.determineInterested(call);
    	   return interested.getIDs();
        } 
    set;}
   
    
    public Map<String, Employee__c> employeeIdMap;
    public Map<String, ID> nameIDMap {
    	get{
    		Map<String, ID> m = new Map<String, ID>();
    		for (Employee__c  e: employeeIdMap.values()){
    		     m.put(e.Name, e.Id);
    			
    		}
    		return m; 
    	}
    }
    
    private void populateEmployeeMap(){
    	EmployeeCollection ec = new EmployeeSelector().whereCompanyEmailIsNotNull().whereIsCurrent().execute();
    	employeeIdMap = new Map<String, Employee__c>();
    	for (Employee__c e : ec.getList()){
    		employeeIdMap.put(e.Id, e);
    	}
    }
    
    private void getSelectOptionList(){
    	
    	//NOTE: this is convoluted and weird because Apex does not have a built-in sort
    	//for anything other than primitives, so thanks guys.
    	List<String> names = new List<String>(nameIdMap.keySet());
    	names.sort();
    	System.assert(names.size() > 0, 'employeeIDMap not populated!');
    	availableEmployeeNames = new List<SelectOption>();
    	for (String name: names){
    	   ID id = nameIdMap.get(name);
    		availableEmployeeNames.add(new SelectOption(id, name));
    	}
    	
    }
    
    private String formatSpecificEmployees(){
    	String s = call.Specific_Employees__c;
    	
    	if (s == null){
    		s= '';
    	}
    	if (chosenEmployeeNames==null){
    	   return s;
    	  
    	}
    	System.debug('~~~~~~~~~~User has selected '+ chosenEmployeeNames.size() + 'employees to notify.');
    	for (String theId : chosenEmployeeNames){
    	   //String idString = (String) o.getValue();
    	   s +=  theId + ',';
    	}
    	return s;//s.substring(0, s.lastIndexOf(','));
    }
    
    public CallReportExtension(ApexPages.StandardController c){
    	controller = c;
    	parameters = ApexPages.currentPage().getParameters();
    	chosenEmployeeNames = new List<ID>();
    	call.Call_Time__c = (call.Call_Time__c == null) ? Datetime.now(): call.Call_Time__c;
    	call.Duration_Hours__c=(call.Duration_Hours__c == null) ? CallReportExtension.DEFAULT_HOURS : call.Duration_Hours__c;
    	call.Duration_Minutes__c= (call.Duration_Minutes__c == null) ?  CallReportExtension.DEFAULT_MIN : call.Duration_Minutes__c;
    	populateEmployeeMap();
    	getSelectOptionList();
    	this.newContact = new Contact();
    	
    }
    private void addTopicToNotes(){
    	String tickerstring = 'All Tickers discussed: ';
    	String industrystring = 'Industry discussed: ';
    	String bondstring = 'Bond discussed: ';
    	if (call.Topic__c == 'Tickers'){
    		if (call.Call_Notes__c.contains(tickerstring)) {
    		 call.Call_Notes__c = call.Call_Notes__c;
    		 }else{
    		  call.Call_Notes__c = tickerstring + call.Tickers__c + '\n\n' + call.Call_Notes__c;
    		}
    	}
    	if (call.Topic__c == 'Industry'){
    		if (call.Call_Notes__c.contains(industrystring)) { 
    			call.Call_Notes__c = call.Call_Notes__c;
    		}else{
    		  call.Call_Notes__c = industrystring + call.Sector__r.name + '\n\n' + call.Call_Notes__c;
    		}
    	}
    	if (call.Topic__c == 'Specific Bond'){
    		if (call.Call_Notes__c.contains(bondstring)) {
    		  call.Call_Notes__c = call.Call_Notes__c;
    		}else{
    		  call.Call_Notes__c =  + call.Security__r.name + '\n\n' + call.Call_Notes__c;
    		}
    	}
    }
    
    public Employee__c caller{
    	get{
    		if (caller == null){
    		  ID uid = UserInfo.getUserID();
    		  EmployeeCollection emps = new EmployeeSelector().whereIsCurrent().whereUserIn(new ID[]{uid}).execute();
    		  if (emps.size() > 0){
    		  	caller = emps.getList().get(0);
    		  }else{
    		  	throw new InvalidEmployeeSetupException('There is no employee record associated with the current user-- contact HR or your IT staff to correct this configuration');
    		  }
    		}
    		return caller;
    	}
    	
    	private set;
    }
    
    
 
    public void setFields(){
    	
    }
    
    public Boolean renderSpecificEmps {
    	get; 
        set;
        
    }
    
    class InvalidEmployeeSetupException extends Exception{}
}

 

 

 

  • July 26, 2010
  • Like
  • 0

I have been working to expose a process using Visualforce Mobile on BlackBerry.

 

I found that initial load performance (presumabaly due to a login process) is very bad.

 

For testing I created a Visualforce page and set the showHeaders and standardStyles options to false.  Thus the page that is returned is very basic consisting of just the default content for a new Visualforce page.

 

Even with this various page I found that initially opening the Visualforce page by selecting the Visualforce tab from the mobile client is very slow (i.e. 60+ seconds).

 

It is interesting to note that selecting the refresh option from the menu while in the Visualforce tab on the mobile device reloads the page in less than 5 seconds.

 

Further the problem persists even if I enable the WiFi option on my BlackBerry.

 

Using the same WiFi connection the same Visualforce page loads instantly on my PC.

 

Any ideas why the initial connect would take so long?

 

Anyone sucessfully using the Visualforce Mobile option for BlackBerry?

 

Thanks!

 

James

Hi

I have created one visual force page with Custom Controller
Now i want to override that page on standard button "New".
now when i click on "Override" link from setup it redirects me on proper page but there is no Visual Force pages available in dropdown list of Visual force pages.

What could be the problem?

any idea?

Thanks in Advance
  Hi All,

I want to assign my Custom Records to some queues or users based on some Assignment Rule is it possible inside Salesforce.com,if not do we have some work around to achieve this.


Thanks,
Saurabh Rawane