Wednesday, January 29, 2014


I just seeded a new version of VisualStrap with much more components and added a bit of optimisation to existing css. This blog is more about how you can create your Force.com site page very easily using VisualStrap.

Lets take an example of a site of a Product/Company and talks about its features/offering. The site will be a very simple one, one main block which has the company/product banner and some other small blocks that talks about the features.


The Design


The Design
To achieve the above design we will basically need the following stuff


  • navbar (header & footer)
  • well (for features and some minor items)
  • column (grid)
  • row (grid)
  • jumbotron (Highlighted main panel)


Desktop View

Mobile View (the column type/class "col-md-4" makes the blocks stack on devices with lower screen resolution)

So finally the actual page uses


  • navbar
  • well
  • column (grid)
  • row (grid)
  • button
  • modal
  • glyph
  • jumbotron


The Code


<apex:page showHeader="false" docType="html-5.0" >  
   <vs:importvisualstrap />  
   <style>  
     body{  
         font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;  
       }  
     .intro{  
       margin-top:20px;  
       font-size:140%;  
       font-weight: 200;  
     }  
   </style>  
   <vs:visualstrapblock >  
     <apex:form >  
       <!--header -->  
       <vs:navbar brand="Blogforce9" inverse="true" type="fixed-top">  
         A site about VisualStrap  
       </vs:navbar>  
       <!-- highlighted content -->  
       <apex:outputPanel layout="block" styleClass="container" >  
         <apex:outputPanel layout="block" styleClass="jumbotron" style="text-align:center">  
           <h1><vs:glyph icon="bookmark" style="font-size:75%"/> VisualStrap Demo Site</h1>  
           <p>This is a example how VisualStrap can be used to create a site page. All the standard components can be used inside this page without any problem </p>  
           <apex:commandButton styleClass="btn-lg btn-success" value="Submit Request" html-data-toggle="modal" html-data-target="#newRequest"/>  
         </apex:outputPanel>  
       </apex:outputPanel>  
       <!-- the feature section -->  
       <apex:outputPanel layout="block" styleClass="container" >  
         <apex:outputPanel layout="block" styleClass="row">  
           <apex:outputPanel layout="block" styleClass="col-md-4">  
             <apex:outputPanel layout="block" styleClass="well">  
               <h3>   
                 <vs:glyph icon="cog"/> Optimized  
               </h3>  
               <div class="intro" >VisualStrap is based on Bootstrap 3. It uses a wrapper style class to designate the areas where actual theming using bootstrap is required. VisualStrap CSS is optimized to work with Visualforce pages even with standard stylesheet and header on.</div>  
             </apex:outputPanel>  
           </apex:outputPanel>  
           <apex:outputPanel layout="block" styleClass="col-md-4">  
             <apex:outputPanel layout="block" styleClass="well">  
               <h3>   
                 <vs:glyph icon="retweet"/> Flexible  
               </h3>  
               <div class="intro" >VisualStrap is based on bootstrap there are many components available in the package that can be used to create pages. If are aware about bootstrap components you can directly implement them in page without using components </div>  
             </apex:outputPanel>  
           </apex:outputPanel>  
           <apex:outputPanel layout="block" styleClass="col-md-4">  
             <apex:outputPanel layout="block" styleClass="well">  
               <h3>   
                 <vs:glyph icon="tasks"/> Components  
               </h3>  
               <div class="intro" >There are many components available in the package that makes Bootstrap/VisualStrap implementation inside a page very easy. These components handles most of the styling based on a very familiar syntax</div>  
             </apex:outputPanel>  
           </apex:outputPanel>  
         </apex:outputPanel>  
       </apex:outputPanel>  
       <!-- footer -->  
       <vs:navbar brand="Blogforce9" inverse="true" type="fixed-bottom" layout="none">  
         <center>  
           <apex:outputPanel styleClass="text-muted" style="margin:20px;font-size:130%" layout="block">  
             <vs:glyph icon="bullhorn"/> Site powered by Force.com  
           </apex:outputPanel>  
         </center>  
       </vs:navbar>  
       <!-- the modal form-->  
       <vs:modal title="New Request" id="newRequest">  
         <apex:pageBlock mode="maindetail">  
           <apex:pageBlockSection >  
             <apex:pageBlockSectionItem >  
               <apex:outputLabel >First Name</apex:outputLabel>  
               <apex:input type="text"/>  
             </apex:pageBlockSectionItem>  
             <apex:pageBlockSectionItem >  
               <apex:outputLabel >Last Name</apex:outputLabel>  
               <apex:input type="text"/>  
             </apex:pageBlockSectionItem>  
             <apex:pageBlockSectionItem >  
               <apex:outputLabel >Email</apex:outputLabel>  
               <apex:input type="text"/>  
             </apex:pageBlockSectionItem>  
           </apex:pageBlockSection>  
         </apex:pageBlock>  
         <apex:outputPanel styleClass="modal-footer" layout="block">  
           <apex:commandButton value="Close" styleClass="btn-warning" html-data-dismiss="modal"/>  
           <apex:commandButton value="Save Request" styleClass="btn-success" html-data-dismiss="modal"/>  
         </apex:outputPanel>  
       </vs:modal>  
     </apex:form>  
   </vs:visualstrapblock>  
 </apex:page>


To use the above code you need to install the latest version of VisualStrap from the below link. If you are using the source files from Github to install the components replace the "vs:" in the above code with "c:".

Important Notice : There is a bug in platform related to Managed Package only due to which salesforce is not able to resolve the namespace name properly. I have a ticket raised with salesforce but its still open. Meanwhile if you face issues with it you can use the source from the Github or use the Unmanaged Package


Thursday, January 16, 2014


A bit of Introduction 


PageBlockTableEnhancerADV is a plugin that lets you convert a normal VisualForce pageblock table into a datatable. The component internally uses the Datatables plugin to bring in features like sorting, filtering and pagination.



So what's new ?


So as planned this post is all about File Exports!, Yes files export is being ported from Datatables to PageBlockTableEnhancerADV. To export files PageBlockTableEnhancerADV uses the Datatable plugin TableTools. TableTools is very flexible plugin that hooks in to the Datatables API to give in an amazing set of exporting option.

So this version of PageBlockTableEnhancerADV with the help of TableTools brings in 
  • Export to PDF
  • Export to CSV
  • Export to Excel
  • Printable view
  • Copy to clipboard
If you are not aware about the PageBlockTableEnhancerADV or PageBlockTableEnhancer you can read about the same from the below links

List of Parameters 


  • targetPbTableIds : comma-separated Ids of the target Pageblock tables 
  • paginate : Assign true if you want to use the pagination feature,default value is true.
  • pageSizeOptions : A comma separated list of integer values that will displayed as dropdown for page size
  •  defaultPageSize : Default page size that needs to be selected (at page load).
  • enableExport : Set this option to true to enable export toolbar (new in v2)
  • exportFileName : Default filename to use when a user uses the export feature. (new in v2)

Syntax


<c:PageBlockTableEnhancerADV targetPbTableIds="mid,mid2" paginate="true" defaultPageSize="5" pageSizeOptions="5,10,20,30,40,50,100" enableExport="true" exportFileName="myFile"/> 



Thursday, January 9, 2014


Few days ago I introduced a set of components called "VisualStrap" which will bring the BootStrap to VisualForce pages very easily. VisualStrap is still work in progress , I am adding new components and improving it whenever I get time.

Till now, I was able to document about most of the components but the documentation needs much more than just description rather may be some examples, showing the capability of the package.

Here are some very first examples.

Case Overview Page 


A simple highlight bar style page that gives a quick glance of the Case. This page demonstrates the use of some common VisualStrap components and how VisualStrap grid works.







This page mainly uses the following VisualStrap components

  • row
  • column
  • glyph
  • well
  • panel

<apex:page standardController="Case" sidebar="false" docType="html-5.0">  
   <style>  
     .glow{  
        animation: flashBg 0.9s;  
        -webkit-animation: flashBg 0.9s alternate infinite;  
     }  
     @keyframes flashBg  
     {  
       from {  
           border: 3px solid #ff6161;  
          }  
       to {  
           border: 3px solid #ffd324;  
         }  
     }  
     @-webkit-keyframes flashBg /* Safari and Chrome */  
     {  
       from {  
           border: 3px solid #ff6161;  
          }  
       to {  
           border: 3px solid #ffd324;  
           box-shadow: 0px 0px 50px 3px #e14f1c;  
         }  
     }  
   </style>  
   <vs:importvisualstrap />  
   <vs:visualstrapblock >  
     <vs:panel type="primary" title="Case Overview">  
       <vs:row >  
         <vs:column type="col-md-3">  
           <div class="glow">  
             <vs:well style="text-align:center">                
               <vs:row >  
                 <vs:column type="col-md-4" style="font-size:54px">  
                   <vs:glyph icon="time" style="color:red"/>              
                 </vs:column>  
                 <vs:column type="col-md-8">                  
                   <h2>  
                     {!ROUND(NOW() - Case.CreatedDate,0)}  
                   </h2>  
                   <p class="text-muted infolabel">Days waiting for response</p>              
                 </vs:column>  
               </vs:row>                
             </vs:well>  
           </div>   
         </vs:column>  
         <vs:column type="col-md-3">  
           <vs:well style="text-align:center">  
             <vs:row >  
               <vs:column type="col-md-4" style="font-size:54px">  
                 <vs:glyph icon="flag"/>              
               </vs:column>  
               <vs:column type="col-md-8">                  
                 <h2>  
                   {!Case.Status}  
                 </h2>  
                 <p class="text-muted infolabel">Current case status</p>              
               </vs:column>  
             </vs:row>  
           </vs:well>  
         </vs:column>  
         <vs:column type="col-md-3">  
           <vs:well style="text-align:center">  
             <vs:row >  
               <vs:column type="col-md-4" style="font-size:54px">  
                 <vs:glyph icon="filter"/>              
               </vs:column>  
               <vs:column type="col-md-8">                  
                 <h2>  
                   {!Case.Type}  
                 </h2>  
                 <p class="text-muted infolabel">Case Type</p>              
               </vs:column>  
             </vs:row>  
           </vs:well>  
         </vs:column>  
         <vs:column type="col-md-3">  
           <vs:well style="text-align:center">  
             <vs:row >  
               <vs:column type="col-md-4" style="font-size:54px">  
                 <vs:glyph icon="comment"/>              
               </vs:column>  
               <vs:column type="col-md-8">                  
                 <p>  
                   {!Case.Subject}  
                 </p>  
                 <p class="text-muted infolabel">Subject</p>              
               </vs:column>  
             </vs:row>  
           </vs:well>  
         </vs:column>  
       </vs:row>  
     </vs:panel>  
   </vs:visualstrapblock>  
   <apex:detail title="false"/>  
 </apex:page> 

User Dashboard Page


This page is a simple dashboard that gives user about the daily information that they need.  Like pending activities for the day, assigned cases, assigned leads, last viewed Accounts/contacts. 



[The layout is mobile friendly try opening the link in a iPad or try to scale down your browser window. The blocks will stack according to screen real estate]

This page mainly uses the following VisualStrap components
  • row
  • column
  • glyph
  • alert
  • panel
  • tables
  • well


<apex:page sidebar="false" docType="html-5.0" controller="VSDashBoard_Con">  
   <vs:importvisualstrap />  
   <vs:visualstrapblock >  
     <center>  
       <vs:pageheader title="User Dashboard" icon="calendar" subtitle="{!$User.FirstName} {!$User.LastName}"/>  
     </center>  
     <vs:row >  
       <vs:column type="col-md-4">  
         <vs:panel title="Tasks" type="primary">  
           <vs:well style="text-align:center;">  
              <vs:glyph icon="tasks" style="font-size:40px"/> &nbsp;<span style="font-size:54px">{!Tasks.size}</span>  
              <p class="text-muted">Tasks due for Today</p>  
           </vs:well>  
           <apex:dataTable value="{!Tasks}" var="task" styleClass="table table-condensed table-hover table-bordered" rows="3">  
             <apex:column headerValue="Subject">  
               <apex:outputLink value="/{!task.Id}">{!task.Subject}</apex:outputLink>  
             </apex:column>  
             <apex:column value="{!task.Status}" headerValue="Status"/>  
             <apex:column value="{!task.ActivityDate}" headerValue="Due Date"/>  
           </apex:dataTable>  
           <vs:alert rendered="{!Tasks.empty}" type="success" style="text-align:center">  
             <vs:glyph icon="ok-sign"/> No records to display  
           </vs:alert>  
         </vs:panel>  
       </vs:column>  
       <vs:column type="col-md-4">  
         <vs:panel title="Cases" type="primary">  
           <vs:well style="text-align:center;">  
              <vs:glyph icon="briefcase" style="font-size:40px"/>&nbsp;<span style="font-size:54px">{!Cases.size}</span>  
              <p class="text-muted">Assigned Cases</p>  
           </vs:well>  
           <apex:dataTable value="{!Cases}" var="case" styleClass="table table-condensed table-hover table-bordered" rows="3">  
             <apex:column headerValue="Case Number">  
               <apex:outputLink value="/{!case.Id}">{!case.CaseNumber}</apex:outputLink>  
             </apex:column>  
             <apex:column value="{!case.Status}" headerValue="Status"/>  
             <apex:column value="{!case.Priority}" headerValue="Priority"/>  
           </apex:dataTable>  
           <vs:alert rendered="{!Cases.empty}" type="warning" style="text-align:center">  
             <vs:glyph icon="exclamation-sign"/> No records to display  
           </vs:alert>  
         </vs:panel>  
       </vs:column>  
       <vs:column type="col-md-4">  
         <vs:panel title="Leads" type="primary">  
           <vs:well style="text-align:center;">  
              <vs:glyph icon="user" style="font-size:40px"/>&nbsp;<span style="font-size:54px">{!Leads.size}</span>  
              <p class="text-muted">Unread Leads</p>  
           </vs:well>  
           <apex:dataTable value="{!Leads}" var="lead" styleClass="table table-condensed table-hover table-bordered" rows="3">  
             <apex:column headerValue="Name">  
               <apex:outputLink value="/{!lead.Id}">{!lead.Name}</apex:outputLink>  
             </apex:column>  
             <apex:column value="{!lead.Status}" headerValue="Status"/>  
             <apex:column value="{!lead.CreatedDate}" headerValue="Created Date"/>  
           </apex:dataTable>  
           <vs:alert rendered="{!Leads.empty}" type="warning" style="text-align:center">  
             <vs:glyph icon="exclamation-sign"/> No records to display  
           </vs:alert>  
         </vs:panel>  
       </vs:column>        
     </vs:row>  
     <vs:row >  
       <vs:column type="col-md-6">  
         <vs:panel title="Last Viewed Accounts" type="primary">  
           <apex:dataTable value="{!Accounts}" var="acc" styleClass="table table-condensed table-hover table-bordered" >  
             <apex:column headerValue="Name">  
               <apex:outputLink value="/{!acc.Id}">{!acc.Name}</apex:outputLink>  
             </apex:column>  
             <apex:column value="{!acc.Type}" headerValue="Type"/>  
             <apex:column value="{!acc.BillingState}" headerValue="State"/>  
           </apex:dataTable>  
           <vs:alert rendered="{!Accounts.empty}" type="warning" style="text-align:center">  
             <vs:glyph icon="exclamation-sign"/> No records to display  
           </vs:alert>  
         </vs:panel>  
       </vs:column>  
       <vs:column type="col-md-6">  
         <vs:panel title="Last Viewed Contacts" type="primary">  
           <apex:dataTable value="{!Contacts}" var="contact" styleClass="table table-condensed table-hover table-bordered" rows="3">  
             <apex:column headerValue="Name">  
               <apex:outputLink value="/{!contact.Id}">{!contact.Name}</apex:outputLink>  
             </apex:column>  
             <apex:column value="{!contact.Phone}" headerValue="Phone"/>  
             <apex:column value="{!contact.Department}" headerValue="Department"/>  
           </apex:dataTable>  
           <vs:alert rendered="{!Contacts.empty}" type="warning" style="text-align:center">  
             <vs:glyph icon="exclamation-sign"/> No records to display  
           </vs:alert>  
         </vs:panel>  
       </vs:column>    
     </vs:row>  
   </vs:visualstrapblock>  
 </apex:page>  


 public without sharing class VSDashBoard_Con {  
   public List<Task> getTasks(){  
     return [SELECT Id,Subject,Status, ActivityDate FROM Task WHERE ActivityDate = TODAY AND Status != 'Completed' AND Status != 'Deferred'];  
   }  
   public List<Case> getCases(){  
     return [SELECT Id,CaseNumber,Status,Subject, Priority FROM Case WHERE OwnerId=:UserInfo.getUserId() AND isClosed = FALSE];  
   }  
   public List<Lead> getLeads(){  
     return [SELECT Id,Name,Status, CreatedDate FROM Lead WHERE OwnerId=:UserInfo.getUserId() AND IsUnreadByOwner = true];  
   }  
   public List<Account> getAccounts(){  
     return [SELECT Id,Name,BillingState,Type FROM Account ORDER BY LastViewedDate DESC limit 5 ];  
   }  
   public List<Contact> getContacts(){  
     return [SELECT Id,Name,Phone, Department FROM Contact ORDER BY LastViewedDate DESC limit 5 ];  
   }  
 }  

Please Note : You can use <apex:outputPanel layout="block" styleClass="row"> or <div class="row"> instead of <vs:row>. Similarly you can use <apex:outputPanel layout="block" styleClass="col-md-4"> or <div class="col-md-4"> instead of <vs:column type="col-md-4"> . And you can also use Bootstrap components inside the pages

VisualStrap is not limited to just these two pages, it can be leveraged to do much more. People out there can extend this to do much more ! Visualstrap is available as Managed package and as well as github. You can grab the same from the project detail page.

To make the above examples work you have to install VisualStrap from project page below. "vs" is namespace prefix from the managed package, if you are using the source from github you may have to replace "vs:" with just "c:".



Thursday, January 2, 2014




Well this is something that should be called as hack. While working with salesforce Js libraries I found some interesting methods hidden inside. Well most of them are very difficult to understand because of the naming of different input parameters but somehow I was able to decode one of them which are related to generating popup.

SimpleDialog


Simple dialog generates a very simple popup/dialog. So far from the code it looks like
  • Modal popup
  • Can be draggable
  • Option to set title and content
  • Supports html in the body
So here is a bit of code that will fire a SimpleDialog

function showSimpleDialog(){    
   var sd = new SimpleDialog("Test"+Dialogs.getNextId(), false);    
   sd.setTitle("Test Pop up");   
   sd.createDialog();   
   window.parent.sd = sd;   
   sd.setContentInnerHTML("<p align='center'><img src='/img/msg_icons/warning32.png' style='margin:0 5px;'/></p><p align='center'>This is awesome!</p><p align='center'><br /><button class='btn' onclick='window.parent.sd.hide(); return false;'>cancel</button></p>");    
   sd.show();   
 }  
 showSimpleDialog(); //open the popup  

This code will create a popup like below



Bit of Explanation about different parameters / Methods


  • Dialog Id
    var sd = new SimpleDialog("Test"+Dialogs.getNextId(), false);  
    The firs parameter here is the dialog Id it is pretty much handled by salesforce internal method "getNextId" you can change the prefix to something more relevant. Make sure you use "getNextId" method everytime you generate a dialog else the popup won't be generated properly.
  • Draggable
    var sd = new SimpleDialog("Test"+Dialogs.getNextId(), false);  
    whether a dialog is draggable or not it is decided by the second parameter. Set the second parameter to true to make the dialog draggable
  • Title / setTitle
    sd.setTitle("Test Pop up");  
    This line actually sets the title of the popup
  • setContentInnerHTML
    sd.setContentInnerHTML("<p align='center'><img src='/img/msg_icons/warning32.png' style='margin:0 5px;'/></p><p align='center'>This is awesome!</p><p align='center'><br /><button class='btn' onclick='window.parent.sd.hide(); return false;'>cancel</button></p>");   
    
    This lines basically sets the content of the popup. It should be a valid HTML content
  • show
    This method triggers the popup and displays the content
  • hide
    This method hides the popup
Or code can be wrapped a bit to make it simpler 

function showSimpleDialog(title,htmlBody,isDraggable){    
   var sd = new SimpleDialog("SD"+Dialogs.getNextId(), isDraggable);    
   sd.setTitle(title);    
   sd.createDialog();     
   sd.setContentInnerHTML(htmlBody);    
   sd.show();   
   return sd;   
}    
showSimpleDialog('Sample','This is sample modal popup',false);   

So simplified parameters would be
  • title : Title of the popup
  • htmlBody : html content that you want to display in the popup
  • isDraggable : set this to true if you want the popup to be draggable.

Special consideration while using the popup in a standard page



You can copy the sample script inside onclick javascript of a custom button on a standard layout to implement the popup. But you have to bit careful and have to maintain the context of the "sd" variable.

If you check the sample script code you can see that we can display a popup by calling the "show()" method, but while working with standard pages the context variable "sd" is lost and you cannot actually call "sd.hide()" to hide the popup. To overcome this we are saving the context of the popup in "window.parent" global variable. 
window.parent.sd = sd;  
and now you can access the dialog context and call hide/show function by doing 
window.parent.sd.hide();
Well if you are working in a VF page you dont need this workaround you can directly call
sd.hide(); 

Please Note : This example uses Salesforce internal libraries to create a dialog. Use of this libraries are discouraged by Salesforce as they can change anytime