Wednesday, December 11, 2013

Message Dialogue Box / Splash Screen in Salesforce

Hello Friends,
I am back with a new logic for Salesforce developers. Lots of time our client / project manager requirements to display a Error message in a message dialogue box OR in a splash Screen.
I have figure out the simplest way to display message in dialogue box OR in a splash.

For Demo of Splash Screen / Dialogue Box-  
https://rajjha-developer-edition.ap1.force.com/apexontips/splashDemo

For this you are required some CSS that you can change according to your requirements. and 4 lines of code.
In a dialogue box you can display -
Error Message:  Custom OR ApexPages messages.
Button : apex buttons, HTML buttons etc.
and all of things that we are using on VFPages.

For this you need a CSS file that have to be stored in Static Resource, With the name  "splashCSS".
link for download the CSS file -
https://drive.google.com/file/d/0B4ctbLlHaa29Tl9URHl6Z2szQ0k/edit?usp=sharing

For the Splash Screen OR Dialogue box you can use this code -


<apex:page>
    <apex:form>
        <apex:stylesheet value="{!$Resource.splashCSS}"/>  <!-- CSS file that is stored in Static Resource. -->
        <Apex:outputPanel rendered="true">                 <!--- output panel for render the splash screen. TRUE= visible / FALSE = Hide  -->
            <apex:outputPanel styleClass="popupBackground" layout="block" />
            <apex:outputPanel styleClass="custPopup" layout="block" >    <!--- output panel for start you code which will display on splash screen. -->
                         This is demo of Splash Screen                 <!-- your code for splash screen -->
            </apex:outputPanel>
        </Apex:outputPanel>
     </apex:form>
</apex:page>

After alteration this code according to your need,  you will got the splash screen something like -









Tuesday, July 16, 2013

Sorting Columns With Null Values In SOQL

Recently one of my friend was faced a problem. He wants contact list in sorted order, but the issue is he wants sorting the table according to email columns where some records are without email value.
In that case sorting result is like this type
he fired this Query -
select id, lastname, email from contact order by email 

When he tried to sort in descending order then result is -
he fired this Query -
select id, lastname, email from contact order by email DESC

In a descending case result was wrong. Result must be show where null email values are at the last.
Sorting are working on filled values not on Null value.
So,
I found the way of sorting values including null values. -

select id, lastname, email from contact order by email DESC NULLS LAST

Using this query you will get this type of result - 

NULLS LAST is a keyword for including the null values in a order column. 




Thursday, July 11, 2013

Google Map on a Field

We have seen lots of code for google map implementation. But, all codes are for Visualforce pages. Users created a visualforce page and classes for implement google map. But,

Today I introduce you how you implementation of  google map on a Field.

For This, you will need to create a Custom Label with these values -
Name :               GApiKey
Short Description : GApiKey
Value  :                      BbiTjwR8z1eBST0mNpJvtWvmgvEdrgGXs5szHHahQdD86Zd50nyAzG0QAkxwmgieQrLQ


Then create a Formula field ( type - text) with this formula value - 

IMAGE(
"http://maps.google.com/maps/api/staticmap?center=" + BillingStreet + "," + BillingCity + "," + BillingState + " " + BillingPostalCode +"&zoom=13&size=650x250&markers=color:blue|" + BillingStreet + "," + BillingCity + "," + BillingState + " " + BillingPostalCode + "&sensor=false&format=png32&key=" + $Label.GApiKey
, "no map available", 250, 650)

After adding this field in a object page payout, Result will shows like -


I created a Location name formula field for demo to show Google Map on Field. 
Here the link for online demo:

Wednesday, April 3, 2013

Execute Java Script On Every Screen Of SFDC


The aforementioned blog which I am posting was the severe demand of one of my client who was wondering if we could deliver some code that will be executed on every standard screen of Salesforce.

So ,  the theoretical requirement was cited on the fact that Mr. Client was in urge of some code which would run on every standard page load in salesforce. For this I made an recipe which I am sharing below. Hope that you like it .


For this, You can make one "Narrow Home Page Component". 

In that component you can simply use below JS code and alter according to your need.

<script type="text/javascript" language="javascript">
try    {
   var doc = window.top.document;
   var head = doc.head;
   var scriptElement = doc.createElement('script');
   scriptElement.async = true;
   scriptElement.innerHTML = "alert('test1')";
   head.appendChild(scriptElement); 
}
catch(e){  }
</script>

and add that to your home page layout.

Make sure you have enabled that sidebar component to show on all pages of your sfdc. 
Setup -> customize -> user Interface




You can also use this code by a deploying this package -

NOTE: After deployed this package please assign "JS on Every Screen Layout" to System Administraor Profile or profile that you want to use this functionility. 

Result - 
  

Monday, April 1, 2013

Required Information / Required Field Mark

This time I explore a small but useful code, Some time we have validate the input text boxes using Jave Script or using required attribute but we didn't mark as Required field like a Salesforce required field red mark -



Using this code you can mark any <apex:inputText />  , <apex:inputField/> , <apex:inputTextarea/> , <apex:selectCheckboxes> , <apex:selectList> ....etc.

I have written a code for only <apex:inputText />

<apex:page>
  <apex:form>
      <Apex:pageBlock>
          <Apex:pageBlockSection>
              <Apex:pageBlockSectionItem>
                    Field Label                     <!-----Enter here field label ------>
                    <apex:outputPanel >
                      <div class="requiredInput">
                             <div class="requiredBlock"></div>
                             <!---- APEX / HTML Tag which you marked a required------>
                            <apex:inputText required="true" id="reqField" />          
                     </div>
                   </apex:outputPanel>
             </Apex:pageBlockSectionItem>
         </Apex:pageBlockSection>
      </Apex:pageBlock>
  </apex:form>
</apex:page>






Wednesday, February 27, 2013

Best Practices For Salesforce Coding

  • Use header comments on top classes as below:

      /**
        @ name                      :
        @ author                    :
        @ date                      :
        @ description               :
        @ VF page Name              :
      */

  • Variable/method names needs to be in camelCase as possible. Like creatCase(), getClosedWonOpportunity() etc.

  • Variables names must be meaningful as possible, don't like x, y etc


  • Use curly braces with same line instead of next line in if/else and loops constructs as below:
       if(bla bla){

       }

  • Comments at on every possible complex logic, on top of each methods also about its working.


  • Keep method as possible small , if going logic more than 50 rows, then break that into other method.


  • Test classes must be meaningful, means must have asserts of the main logic, must have coverage near to 80% as possible (at-least 75% is required), use separate test class to cover each separate apex class.


  • Use proper Oops concept as possible , means use private where ever possible, extends, method overriding , method overloading etc.


  • Don’t hard code ids and any hard code values in code, use query to fetch data or in test classes make new objects.


  • Don’t hard code message or error text, try to use Label as possible (If client says).


  • Use components as possible for header, footer in pages.


  • use standard apex tags as possible.


  • Whenever possible make your Utility class which has useful, re-used methods and put your methods in that and use that class in every class logic.


  • If any trigger logic is very big, then try to make one class and put your logic in that class and call that class in your trigger. Keep trigger small and as simple as possible.

  • Check if condition before using the list. eg: 
     if(ContactList.size() > 0)
     {bla bla}

  • Avoid Nested loops, which may cause maximum script statements governor limits to be hit. Should make use of Maps to avoid nested loops.


NOTE: The aforementioned Best Practices are according to me. Salesforce itself output their own Best Practices. I have cited and summarized some of the excerpts it.

Wednesday, February 20, 2013

Google Map On Detail Page Without Controller


Lot of time we need to implement Google map direct on production. On production we can't create classes or contorllers. But we can create VF pages. So I tried to solve this problem. 
I implemented Google Map on Visualforce page, you can Implement this as inline VF page of any object. 
I am using here Account object and Billing Adress for pointing -

For this you need two jquery file that will stored in Static Resource, 
download from this link - 

and then Copy and paste this code on visualforce page. - 


<apex:page standardController="Account" showHeader="false" sidebar="false" >  
   <apex:includeScript value="https://maps.googleapis.com/maps/api/js?sensor=false"/>  
   <apex:includeScript value="{!URLFOR($Resource.jQuery, 'js/jquery-1.6.2.min.js')}"/>  
   <apex:includeScript value="{!URLFOR($Resource.jQuery, 'js/jquery-ui-1.8.16.custom.min.js')}"/>  
   <apex:includeScript value="{!URLFOR($Resource.jqPlugin, '/jquery.blockUI.js')}"/>  
   <apex:stylesheet value="{!URLFOR($Resource.jQuery, 'css/ui-lightness/jquery-ui-1.8.16.custom.css')}"/>  
   <script>  
      var console = {log: function(){}};
      var map,geocoder,infowindow;  
      var latLngs = [];  
      $j = jQuery.noConflict();   
      $j(document).ready(function(){  
        initialize();  
      });  
      function initialize() {  
       geocoder = new google.maps.Geocoder();  
       //initial cordinates for map init  
         
       var latlng = new google.maps.LatLng(37.09024, -95.712891);  
       //var latlng = new google.maps.LatLng(0, 0);  
       var myOptions = {  
         zoom: 10,  
         center: latlng,  
         mapTypeId: google.maps.MapTypeId.ROADMAP  
       };  
       map = new google.maps.Map($j('#map')[0], myOptions);  
       codeAddress();  
      }  
     function codeAddress(){  
       var address = '{!Account.BillingStreet},{!Account.BillingCity},{!Account.BillingState},{!Account.BillingCountry}';  
        console.log(address);  
       geocoder.geocode( { 'address': address }, function(results, status) {  
          //if it is a success  
          
          if (status == google.maps.GeocoderStatus.OK) {  
            var location = results[0].geometry.location;  
           
            var marker=addMarker(location );  
            //attach info window to the marker  
            attachInfoWindow(marker,results[0]);  
          }  
          else {  
            //alert(status);  
          }  
        });   
      }  
     
      function addMarker(location) {  
       marker = new google.maps.Marker({  
           position: location,  
           map: map  
         });  
       var latlngbounds = new google.maps.LatLngBounds();  
       latlngbounds.extend(marker.getPosition());  
       map.fitBounds(latlngbounds);  
       map.setZoom(14);  
       return marker;  
      }  
     //this function shows the address of a marker when it is clicked  
     function attachInfoWindow(marker,address){  
        google.maps.event.addListener(marker, 'click', function() {  
          if(infowindow!=null)  
           {  
             infowindow.close();  
           }  
        
         var contentString = '<div class=" ui-state-active ui-corner-top" style="font-size: 1em; padding: 5px;">Address</div>'  
                   +'<div class="ui-widget-content ui-corner-bottom" style="font-size: .9em; padding: 15px;">'+address.formatted_address+'</div>';  
         infowindow = new google.maps.InfoWindow({  
           content: contentString  
         });  
          infowindow.open(map,marker);  
        });  
     }  
   </script>  
   <style>  
     #map {  
       width:100%;  
       height:200px;   
       margin-left:0;  
     }  
   </style>  
     <meta http-equiv="X-UA-Compatible" content="IE=EmulateIE8" />
   <div id="map" class="ui-widget-content ui-corner-all ui-state-default"></div>  
 </apex:page>
                       

Wednesday, February 13, 2013

Transient Keyword

Many times we are struggling with view state error on visualforce page at the time of uploading files.
Salesforce provides facility to a upload file upto 10mb, But when we try to upload file through visualforce page then visualforce page limit (135kb) create a wall. It is I try to jump this wall and upload the files through visual force page.

Using Transient Keyword  we can achieve this. Decalaring Variables as transient to reduces view states. View state maintains state of the Database between request and Visualforce page.

I try to explain this using code -

Controller
public class UploadFileDemo


    public Attachment attch{get;set;} 
    public Transient blob myAttachedBody {get; set;}
    
    public UploadFileDemo()
    {
          attch = new Attachment();
    }
    public void uploadFile()
    {
          attch.body = myAttachedBody;
          attch.parentId = parentIdOfRelatedObject;
          insert attch;
    }
}
VisualForce page
<Apex:page>
  <apex:form>
      <Apex:pageblock> 
          <apex:inputFile id="idSelectFile" fileName="{!attch.Name}"  value="{!myAttachedBody}" contentType="{!attch.contentType}"  ></apex:inputFile>
            <apex:commandbutton value="Upload" action="{!uploadFile}"/>
      </apex:pageblock>
  </apex:form>
</apex:page>