apex:pageBlockSectionItem>
<apex:outputLabel value="Name on Card"/>
<apex:outputPanel>
<div class="requiredInput">
<div class="requiredBlock"></div>
<apex:inputText value="{!name}" label="Name on Card" required="true"/>
</div>
</div>
</apex:outputPanel>
</apex:pageBlockSectionItem>
Saturday, 15 February 2014
Required Mark on Input Text
If you are using inputText the red bar doesn't come with it. You have to consider inputField and make it required to show the red bar. If you want to show red bar with inputtext then you have to use requireInput css. Below is the code snippet.
Sunday, 28 July 2013
Custom Cloning of Object using dynamic SOQL
If you want to clone custom object along with its child objects then standard won't work. Standard cloning only clone the object record itself and does not clone its child objects.
In order to fulfil that requirement you have create custom clone button and invoke a webservice. Javascript which needs to be written to call webservice is not included in this example.
Standard Clone method only copy the fields which are queried from object and as you know fields may change during developmemt so in order to make a solution flexible and not dependent on fields we can make dynamic SOQL for quering the fields.
The below example will clone object (Clone_Object__c) record along with its child (Clone_Object_Child__c) record and redirect the user to new cloned record without having dependency of fields.
Code Snippet
In order to fulfil that requirement you have create custom clone button and invoke a webservice. Javascript which needs to be written to call webservice is not included in this example.
Standard Clone method only copy the fields which are queried from object and as you know fields may change during developmemt so in order to make a solution flexible and not dependent on fields we can make dynamic SOQL for quering the fields.
The below example will clone object (Clone_Object__c) record along with its child (Clone_Object_Child__c) record and redirect the user to new cloned record without having dependency of fields.
Code Snippet
// Class is global because of webservice
global class CloneClass {
// Returns a dynamic SOQL statement for the whole object, includes only creatable fields since we will be inserting a cloned result of this query
public static string getCreatableFieldsSOQL(String objectName, String whereClause){
String selects = '';
if (whereClause == null || whereClause == ''){ return null; }
// Get a map of field name and field token
Map<String, Schema.SObjectField> fMap = Schema.getGlobalDescribe().get(objectName.toLowerCase()).getDescribe().Fields.getMap();
list<string> selectFields = new list<string>();
if (fMap != null){
for (Schema.SObjectField ft : fMap.values()){ // loop through all field tokens (ft)
Schema.DescribeFieldResult fd = ft.getDescribe(); // describe each field (fd)
if (fd.isCreateable()){ // field is creatable
selectFields.add(fd.getName());
}
}
}
if (!selectFields.isEmpty()){
for (string s:selectFields){
selects += s + ',';
}
if (selects.endsWith(',')){selects = selects.substring(0,selects.lastIndexOf(','));}
}
return 'SELECT ' + selects + ' FROM ' + objectName + ' WHERE ' + whereClause;
}
// Clone method and redirect the user to cloned record.
public String clone(String cloneObjId){
String soql = CloneClass.getCreatableFieldsSOQL('Clone_Object__c','id=\''+cloneObjId+'\''); // Static method is called by class
Clone_Object__c cloneObj = (Clone_Object__c')Database.query(soql);
Clone_Object__c newcloneObj = cloneObj.clone(false, true);
newcloneObj.Name = 'Clone-'+ cloneObj.Name;
insert newcloneObj;
List<Clone_Object_Child__c> lstcloneObjChild = new List<Clone_Object_Chld__c'>();
String soqlCloneObjChild = CloneClass.getCreatableFieldsSOQL('Clone_Object_Child__c'','Clone_Object__c'=\''+cloneObjId+'\'');
List<Clone_Object_Child__c> lstcloneObjChild = (List<Clone_Object_Child__c'>)Database.query(soqlCloneObjChild);
for(Clone_Object_Child__c cloneObjChild : lstcloneObjChild){
Clone_Object_Child__c newcloneObjChild = cloneObjChild.clone(false);
newcloneObjChild.Clone_Object__c = newcloneObj.id;
newcloneObjChild.Is_default__c = false;
lstcloneObjChild.add(newcloneObjChild);
}
insert lstcloneObjChild;
return String.valueOf( new PageReference('/'+newcloneObj.Id+'/e').getUrl() + '?retURL='+newcloneObj.Id); //This lands on the new cloned record n Edit Mode.
}
// Webservice which is called by custom button
webservice static String deepClone(String aid){
Clone_Object__c cloneObj = [Select Id,Name, FROM Clone_Object__c' WHERE Id =: aid]; // aid : Id of record which we want to clone
CloneClass cloneClassObj = new CloneClass(cloneObj);
String p = cloneClassObj.clone(aid); // Calling class clone method and passing Id of record
return p;
}
}
Formatting date field in apex:inputtext
If we would like to have the ability to use a date field in Visualforce without relying on a salesforce or custom object then we can acheive this by using <apex:inputtext>. Below is the code snippet
Visualforce Page:
Visualforce Page:
<apex:page controller="inputTextDemo" id="mypage">
<span class="dateInput dateOnlyInput">
<apex:inputText id="inputFieldId" size="12" value="{!DateStringProperty}" style="width:72px;text-align:center;" onclick="DatePicker.pickDate(false, this, false);" onfocus="DatePicker.pickDate(false, this, false);"/>
</span>
</apex:page>
Controller: public class inputTextDemo{
// String Property which is bind to <apex:inputtext>
public String DateStringProperty{get;set;}
public inputTextDemo(){
// Populating field value by today date.
DateStringProperty = Date.Today().format(); // Populating field value by today date.
}
public void insertDateMethod(){
Custom_Object__c obj = new Custom_Object__c();
// Since value is string and Date field does not take string value so we need to parse this string as Date
obj.DateField__c = Date.parse(DateStringProperty);
insert obj;
}
}
Hierachy Custom Settings in Salesforce
A type of custom setting that uses a built-in hierarchical logic that lets you “personalize” settings for specific profiles or users.The hierarchy logic checks the organization, profile, and user settings for the current user and returns the most specific, or “lowest,” value.
In the hierarchy, settings for an organization are overridden by profile settings, which, in turn, are overridden by user settings.
Hierarchy custom settings can be configured at varying user specificity levels under a single name; the platform will look for the most specific configuration first, then fall back / inherit to the least specific that is why the lowest level of data in the custom setting is specified at the user level.
- setting per user,
- setting per profile,
- setting for whole org,
Id pid = Userinfo.getProfileId(); // Getting profile of current user.
//Obtain values from Custom Settings
HierarchyExampleSettings__c arc = HierarchyExampleSettings__c.getInstance(pid);
String exampleURL = arc.Site_URL__c; // Setting variable from custom setting
String examplePage = arc.Example_Page__c;
Monday, 24 June 2013
Conditioning in Visualforce Page
If you want to override Opportunity detail page and show OpportunityLineItem's detail page underneath the Opportunity page, you can do it easily by using <apex:detail>,<apex:repeat> and <apex:variable> with some conditioning in VF page.
<apex:detail> shows the standard detail page for a particular object, as defined by the associated page layout for the object in Setup. So in order to show Opportunity detail page, we can use <apex:detail> and bind VF page by Opportunity standard controller.
Use custom controller as an extension to get the related OpportunityLineItems of that particular Opportunity in list and bind it with <apex:detail>.But here is a tricky part, We have a list of OpportunityLineItems and <apex:detail> includes 'subject' attribute which takes ID of the record that should provide data to the component. To set ID of record in <apex:detail> we can give the name of the list with the element's index position in square brackets
<apex:detail subject="{!oppLineItemList[cnt]}"/>.
Iterate the list with incrementing the list index(local variable 'cnt').<apex:variable> is a local variable that can be used as a replacement for a specified expression within the body of the component.
<apex:variable var="cnt" value="{!0}"/>.
To iterate and increment local variable value we can use <apex:repeat>. It is an iteration component that allows you to output the contents of a collection according to a structure that you specify and in our case it is iterating to size of OpportunityLineItem list.
<apex:repeat value="{!oppLineItemList}">.
If we increment list index(local variable) like <apex:variable var="cnt" value="{!cnt+1}"/> then and it will throw us an error "List index out of bounds" because in last iteration list index(local variable) will be equal to list size and we know list index is zero based and it should be less than the size of the collection. To avoid this error, we can give condition that when [list index(local variable) value] is less than [one less than list size] then increment list index(local variable) otherwise keep it as it is.
value="{!IF(cnt < oppLineItemList.size-1,cnt+1,cnt)}".
Below is the code snippet of Controller and Page.
Controller:
VisualForce Page:
Use custom controller as an extension to get the related OpportunityLineItems of that particular Opportunity in list and bind it with <apex:detail>.But here is a tricky part, We have a list of OpportunityLineItems and <apex:detail> includes 'subject' attribute which takes ID of the record that should provide data to the component. To set ID of record in <apex:detail> we can give the name of the list with the element's index position in square brackets
<apex:detail subject="{!oppLineItemList[cnt]}"/>.
<apex:variable var="cnt" value="{!0}"/>.
To iterate and increment local variable value we can use <apex:repeat>. It is an iteration component that allows you to output the contents of a collection according to a structure that you specify and in our case it is iterating to size of OpportunityLineItem list.
<apex:repeat value="{!oppLineItemList}">.
If we increment list index(local variable) like <apex:variable var="cnt" value="{!cnt+1}"/> then and it will throw us an error "List index out of bounds" because in last iteration list index(local variable) will be equal to list size and we know list index is zero based and it should be less than the size of the collection. To avoid this error, we can give condition that when [list index(local variable) value] is less than [one less than list size] then increment list index(local variable) otherwise keep it as it is.
value="{!IF(cnt < oppLineItemList.size-1,cnt+1,cnt)}".
public class contOppLineItem{
public list<OpportunityLineItem> oppLineItemList{get;set;}
public Opportunity opp;
public contOppLineItem(ApexPages.StandardController stdController){
//Constructor
this.opp = (Opportunity)stdController.getRecord();
oppLineItemList = [Select Id,OpportunityId From OpportunityLineItem Where OpportunityId =: opp.Id];
}
}
<apex:page standardController="Opportunity" extensions="contOppLineItem">
<apex:detail relatedList="false" title="true"/>
<apex:pageBlock mode="detail">
<apex:pageBlockSection title="OpportunityLineItem">
<div align="center">
<apex:variable var="cnt" value="{!0}" />
<apex:repeat value="{!oppLineItemList}">
<apex:detail subject="{!oppLineItemList[cnt]}"/>
<apex:variable var="cnt" value="{!IF(cnt<oppLineItemList.size-1,cnt+1,cnt)}"/>
</apex:repeat>
</div>
</apex:pageBlockSection>
</apex:pageBlock>
</apex:page>
Thursday, 3 May 2012
Inline scripting in Vf pages
If you want to get id of any element and set certain property to it you can do that by inline scripting.
Below is the code snippet which is getting inputtext id and set the disabled property to it.
<apex:inputText id="testid" style="width:40pt;text-align:center;" styleClass="testclass"></apex:inputText>
<script>document.getElementById('{!$Component.testid}').disabled = true; </script>
Labels:
Inline Script,
javascript,
Salesforce,
SalesforceZone,
visualforce
Location:
Auckland, New Zealand
Future Methods in Salesforce
Future annotation is used to identify methods that are executed asynchronously. When you specify future, the method executes when Salesforce has available resources.
For example, you can use the future annotation when making an asynchronous Web service callout to an external service. Without the annotation, the Web service callout is made from the same thread that is executing the Apex code, and no additional processing can occur until the callout is complete (synchronous processing).
Points to Remember about future method :
For example, you can use the future annotation when making an asynchronous Web service callout to an external service. Without the annotation, the Web service callout is made from the same thread that is executing the Apex code, and no additional processing can occur until the callout is complete (synchronous processing).
global class MyFutureClass {
@future
public static void myMethod() {
EmailClass.SendEmailNotification();
//do callout, other long running code
}
}
Email Class
global class EmailClass{
WebService static void SendEmailNotification() {
//create a mail object to send a single email.
Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage();
//set the email properties
mail.setToAddresses(new string[] {'wahib.idris@xyz.com'});
mail.setSenderDisplayName('SF.com Email Agent');
mail.setSubject('A new reminder');
mail.setHtmlBody('Password');
//send the email
Messaging.sendEmail(new Messaging.SingleEmailMessage[] { mail } );
}
}
Points to Remember about future method :
- No more than 10 method calls per Apex invocation.
- The specified parameters must be primitive data types, arrays of primitive data types, or collections of primitive data types.
- Methods with the future annotation cannot take sObjects or objects as arguments.
- Methods with the future annotation cannot be used in Visualforce controllers in either getMethodName or setMethodName methods, nor in the constructor.
- You cannot call a method annotated with future from a method that also has the future annotation. Nor can you call a trigger from an annotated method that calls another annotated method.
- @future(callout = true) means that the method has ability to invoke external web services.
Subscribe to:
Posts (Atom)


