Saturday, 9 February 2013

Print VF page on button click


VF page Code
============

<apex:page controller="bhadraPieChartController" title="Pie Chart" showHeader="false">
<script>
   //this is only the code for printing the page
    function fun(){
           document.getElementById('prnBtn').style.display='none'; 
           //document.getElementById('winBtn').style.display='none';    
           window.print();
            document.getElementById('prnBtn').style.display='block'; 
    }
</script>
<apex:form >
  <div  style="padding-left: 484px;padding-top: 27px;"><input type="button"   onClick="fun();" id="prnBtn"  value="Print This Page" style="background: green;"/></div>
</apex:form>
    <apex:chart height="350" width="450" data="{!pieData}">
        <apex:pieSeries dataField="data" labelField="name"/>
        <apex:legend position="right"/>
    </apex:chart>
</apex:page>
==========
Controller
============

public class bhadraPieChartController {
 

  public List<BhadraPieWedgeData> getPieData() {

       List<BhadraPieWedgeData> namedata = new List<BhadraPieWedgeData>();  
   

    namedata.add(new BhadraPieWedgeData('Jan', 30));
     
    namedata.add(new BhadraPieWedgeData('Feb', 15));
       
    namedata.add(new BhadraPieWedgeData('Mar', 10));
       
    namedata.add(new BhadraPieWedgeData('Apr', 20));
       
    namedata.add(new BhadraPieWedgeData('May', 20));
       
    namedata.add(new BhadraPieWedgeData('Jun', 5));
       
    return namedata;
   
  }
   
 
   
   
    public class BhadraPieWedgeData {

       
        public String name { get; set; }
       
        public Integer data { get; set; }
       
        public BhadraPieWedgeData(String name1, Integer data1) {
               this.name = name1;          
               this.data = data1;
        }

 
    }

}
=============
Output:
==========


Print page



Thursday, 7 February 2013

Piechart on VFpage with dynamic data


Page:
======

<apex:page controller="PieChartController1" title="Pie Chart" sidebar="false">
  <center>  <apex:chart height="350" width="450" data="{!pieData}">
        <apex:pieSeries dataField="data" labelField="name"/>
        <apex:legend position="right"/>
    </apex:chart>
   </center>
</apex:page>


Controller
========

public class PieChartController1 {
    public List<PieWedgeData> getPieData() {
        List<PieWedgeData> data = new List<PieWedgeData>();
        integer i=0;
        for(Opportunity opp:[select id,name,stagename,amount from Opportunity limit 10]){
            data.add(new PieWedgeData(opp.name,i++));      
       }
        return data;
    }

    // Wrapper class
   
    public class PieWedgeData {

        public String name { get; set; }
        public integer data { get; set; }

        public PieWedgeData(String name, integer data) {
            this.name = name;
            this.data = data;
        }
    }
}

Output:
======



Piechart on vf page with static data(visualforce charting)

Page:
======

<apex:page controller="PieChartController" title="Pie Chart" sidebar="false">
 <center>   <apex:chart height="350" width="450" data="{!pieData}">
        <apex:pieSeries dataField="data" labelField="name"/>
        <apex:legend position="right"/>
    </apex:chart>
 </center>
</apex:page>

Controller
=========

public class PieChartController {
    public List<PieWedgeData> getPieData() {
        List<PieWedgeData> data = new List<PieWedgeData>();
        data.add(new PieWedgeData('Jan', 30));
        data.add(new PieWedgeData('Feb', 15));
        data.add(new PieWedgeData('Mar', 10));
        data.add(new PieWedgeData('Apr', 20));
        data.add(new PieWedgeData('May', 20));
        data.add(new PieWedgeData('Jun', 5));
        return data;
    }

    // Wrapper class
   
    public class PieWedgeData {

        public String name { get; set; }
        public Integer data { get; set; }

        public PieWedgeData(String name, Integer data) {
            this.name = name;
            this.data = data;
        }
    }
}
===========
Output:
======


Wednesday, 6 February 2013

Inserting dashboard on vf page

For inserting dashboard designed in salesforce on vf page we need to use <apex:iframe> tag and id of that dashboard as shown below.

vfpage  with dashboard:
=================


<apex:page sidebar="false" showHeader="false">
 <apex:iframe src="/01ZG0000000d9Qb?isdtp=nv" scrolling="true" height="1588px" width="100%"/>
</apex:page>

in the above  'src="/01ZG0000000d9Qb?isdtp=nv" '
if you are not  specifying "isdtp=nv" as a parameters it shows dashboard including header.

if you specify then it shows only dashboard with out header.


Output:
==========
======

Google charts on visualforce page

Here we are taking the url of google chart and assigning dynamic data to the google chart.
Here we are displaying account type and their count.

Controller:
=========
public class googleChartController {
private String chartData;

public String getChartData()
{
 return chartData;
}
//Contructor
public googleChartController ()
{
 //get obtain a list of picklist values
 Schema.DescribeFieldResult F = Account.Type.getDescribe();
 List<Schema.PicklistEntry> P = F.getPicklistValues();
 //where chart data should be stored.
 List<ChartDataItem> items = new List<ChartDataItem>();

 //iterate through each picklist value and get number of accounts
 // I wish we could do GROUP BY in SOQL!
 for(Schema.PicklistEntry pValue : P)
 {
    integer Count = [select count() from Account where Type = :pValue.getValue() limit 10000];
    if (Count > 0)
      items.add(new ChartDataItem(pValue.getValue()+ '-['+ Count.format() + ']' , Count.format()));
 }
 //Prepare the chart URL
 //String chartPath = 'http://chart.apis.google.com/chart?chs=600x200&cht=p3';
 String chartPath='//chart.googleapis.com/chart?chs=600x200&cht=p3&chco=7777CC|76A4FB|3399CC|3366CC';
 chartData = chartPath +  getChartData(items);
}

private String getChartData(List<ChartDataItem> items)
{
 String chd = ''; //23,34,56
 String chl = ''; //Hello|World

 for(ChartDataItem citem : items)
 {
    chd += citem.ItemValue + ',';
    chl += citem.Label + '|';
 }
 //remove the last comma or pipe
 chd = chd.substring(0, chd.length() -1);
 chl = chl.substring(0, chl.length() -1);

 String result = '&chd=t:' + chd + '&chl=' + chl;
 return result;
}// end of method

public class ChartDataItem
{
 public String ItemValue {  get;  set; }
 public String Label {   get;   set; }
 public ChartDataItem(String Label, String Value)
 {
    this.Label = Label;
    this.ItemValue = Value;
  }
 }
}// end of class
=-==================
VF page
================
<apex:page controller="googleChartController" tabStyle="Account">
<apex:sectionHeader title=" Type of Account"></apex:sectionHeader>
<apex:image url="{!chartData}"></apex:image>
</apex:page>

Output:
==========

Multiselect picklist with up and down arrows


Visualforce Component
=====================

<!--
  The MultiselectPicklist component implements a multiselect picklist similar
  to that seen when adding tabs to a Force.com application.
  
  HTML elements use the same classes as the native multiselect picklist, to
  keep visual consistency in the UI.
  
  In addition to the visible elements, the component contains two hidden input
  elements, the purpose of which is to hold a string representation of the
  contents of each listbox. As options are added, removed or moved within the
  listboxes, the content of the hidden elements is synchronized to the content
  of the listboxes. When the Visualforce page is submitted, the 
  MultiselectController updates its SelectOption[] variables from these hidden 
  elements.
 -->
<apex:component controller="MultiselectController">
  <apex:attribute name="leftLabel" description="Label on left listbox."
    type="String" required="true" />
  <apex:attribute name="rightLabel" description="Label on right listbox."
    type="String" required="true" />
  <apex:attribute name="size" description="Size of listboxes."
    type="Integer" required="true" />
  <apex:attribute name="width" description="Width of listboxes."
    type="String" required="true" />

  <apex:attribute name="leftOptions"
    description="Options list for left listbox." type="SelectOption[]"
    required="true" assignTo="{!leftOptions}" />
  <apex:attribute name="rightOptions"
    description="Options list for right listbox." type="SelectOption[]"
    required="true" assignTo="{!rightOptions}" />

  <apex:outputPanel id="multiselectPanel" layout="block" styleClass="duelingListBox">
    <table class="layout">
      <tbody>
        <tr>
          <td class="selectCell">
            <apex:outputPanel layout="block" styleClass="selectTitle">
              <!-- 
                Visualforce prepends the correct prefix to the outputLabel's 
                'for' attribute
              -->
              <apex:outputLabel value="{!leftLabel}" 
                for="multiselectPanel:leftList" />
            </apex:outputPanel>
            <select id="{!$Component.multiselectPanel}:leftList" 
              class="multilist" multiple="multiple" size="{!size}" 
              style="width: {!width};">
              <apex:repeat value="{!leftOptions}" var="option">
                <option value="{!option.value}">{!option.label}</option>
              </apex:repeat>
            </select>
          </td>
          <td class="buttonCell">
            <apex:outputPanel layout="block" styleClass="text">Add</apex:outputPanel>
            <apex:outputPanel layout="block" styleClass="text">
              <apex:outputLink value="javascript:moveSelectedOptions('{!$Component.multiselectPanel}:leftList', 
                  '{!$Component.multiselectPanel}:rightList', '{!$Component.leftHidden}', 
                  '{!$Component.rightHidden}');"
                id="btnRight">
                <apex:image value="/s.gif" alt="Add" styleClass="rightArrowIcon"
                  title="Add" />
              </apex:outputLink>
            </apex:outputPanel>
            <apex:outputPanel layout="block" styleClass="text">
              <apex:outputLink value="javascript:moveSelectedOptions('{!$Component.multiselectPanel}:rightList', 
                  '{!$Component.multiselectPanel}:leftList', '{!$Component.rightHidden}', 
                  '{!$Component.leftHidden}');"
                id="btnLeft">
                <apex:image value="/s.gif" alt="Remove"
                  styleClass="leftArrowIcon" title="Remove" />
              </apex:outputLink>
            </apex:outputPanel>
            <apex:outputPanel layout="block" styleClass="duelingText">Remove</apex:outputPanel>
          </td>
          <td class="selectCell">
            <apex:outputPanel layout="block" styleClass="selectTitle">
              <apex:outputLabel value="{!rightLabel}" for="multiselectPanel:rightList" />
            </apex:outputPanel>
            <select id="{!$Component.multiselectPanel}:rightList" 
              class="multilist" multiple="multiple" size="{!size}" 
              style="width: {!width};">
              <apex:repeat value="{!rightOptions}" var="option">
                <option value="{!option.value}">{!option.label}</option>
              </apex:repeat>
            </select>
          </td>
          <td class="buttonCell"><apex:outputPanel layout="block"
              styleClass="text">Up</apex:outputPanel>
            <apex:outputPanel layout="block" styleClass="text">
              <apex:outputLink value="javascript:slideSelectedOptionsUp('{!$Component.multiselectPanel}:rightList', 
                  '{!$Component.rightHidden}');"
                id="upBtn">
                <apex:image value="/s.gif" alt="Up" styleClass="upArrowIcon"
                  title="Up" />
              </apex:outputLink>
            </apex:outputPanel>
            <apex:outputPanel layout="block" styleClass="text">
              <apex:outputLink value="javascript:slideSelectedOptionsDown('{!$Component.multiselectPanel}:rightList', 
                  '{!$Component.rightHidden}');"
                id="downBtn">
                <apex:image value="/s.gif" alt="Down" styleClass="downArrowIcon"
                  title="Down" />
              </apex:outputLink>
            </apex:outputPanel>
            <apex:outputPanel layout="block" styleClass="text">Down</apex:outputPanel>
          </td>
        </tr>
      </tbody>
    </table>
    <apex:inputHidden value="{!leftOptionsHidden}" id="leftHidden" />
    <apex:inputHidden value="{!rightOptionsHidden}" id="rightHidden" />
  </apex:outputPanel>
  <script type="text/javascript">
    if (!buildOutputString) {
      // Create a string from the content of a listbox
      var buildOutputString = function(listBox, hiddenInput) {
        var str = '';

        for ( var x = 0; x < listBox.options.length; x++) {
          str += encodeURIComponent(listBox.options[x].value) + '&'
              + encodeURIComponent(listBox.options[x].text) + '&';
        }
        str.length--;

        hiddenInput.value = str.slice(0, -1);
      }
    }

    if (!moveSelectedOptions) {
      // Move the selected options in the idFrom listbox to the idTo
      // listbox, updating the corresponding strings in idHdnFrom and
      // idHdnTo
      var moveSelectedOptions = function(idFrom, idTo, idHdnFrom, idHdnTo) {
        listFrom = document.getElementById(idFrom);
        listTo = document.getElementById(idTo);

        for ( var x = 0; x < listTo.options.length; x++) {
          listTo.options[x].selected = false;
        }

        for ( var x = 0; x < listFrom.options.length; x++) {
          if (listFrom.options[x].selected == true) {
            listTo.appendChild(listFrom.options[x]);
            x--;
          }
        }

        listTo.focus();

        buildOutputString(listFrom, document.getElementById(idHdnFrom));
        buildOutputString(listTo, document.getElementById(idHdnTo));
      }
    }

    if (!slideSelectedOptionsUp) {
      // Slide the selected options in the idList listbox up by one position,
      // updating the corresponding string in idHidden
      var slideSelectedOptionsUp = function(idList, idHidden) {
        listBox = document.getElementById(idList);

        var len = listBox.options.length;

        if (len > 0 && listBox.options[0].selected == true) {
          return;
        }

        for ( var x = 1; x < len; x++) {
          if (listBox.options[x].selected == true) {
            listBox.insertBefore(listBox.options[x],
                listBox.options[x - 1]);
          }
        }

        listBox.focus();

        buildOutputString(listBox, document.getElementById(idHidden));
      }
    }

    if (!slideSelectedOptionsDown) {
      // Slide the selected options in the idList listbox down by one position,
      // updating the corresponding string in idHidden
      var slideSelectedOptionsDown = function(idList, idHidden) {
        listBox = document.getElementById(idList);

        var len = listBox.options.length;

        if (len > 0 && listBox.options[len - 1].selected == true) {
          return;
        }

        for ( var x = listBox.options.length - 2; x >= 0; x--) {
          if (listBox.options[x].selected == true) {
            listBox.insertBefore(listBox.options[x + 1],
                listBox.options[x]);
          }
        }

        listBox.focus();

        buildOutputString(listBox, document.getElementById(idHidden));
      }
    }
    
    // initialize the string representations
    buildOutputString(document.getElementById('{!$Component.multiselectPanel}:leftList'), 
        document.getElementById('{!$Component.leftHidden}'));
    buildOutputString(document.getElementById('{!$Component.multiselectPanel}:rightList'), 
        document.getElementById('{!$Component.rightHidden}'));
  </script>
</apex:component>

Controller for above component:
================================
/*
 * MultiselectController synchronizes the values of the hidden elements to the
 * SelectOption lists.
 */
public with sharing class MultiselectController {
    // SelectOption lists for public consumption
    public SelectOption[] leftOptions { get; set; }
    public SelectOption[] rightOptions { get; set; }
    
    // Parse &-separated values and labels from value and 
    // put them in option
    private void setOptions(SelectOption[] options, String value) {
        options.clear();
        String[] parts = value.split('&');
        for (Integer i=0; i<parts.size()/2; i++) {
            options.add(new SelectOption(EncodingUtil.urlDecode(parts[i*2], 'UTF-8'), 
              EncodingUtil.urlDecode(parts[(i*2)+1], 'UTF-8')));
        }
    }
    
    // Backing for hidden text field containing the options from the
    // left list
    public String leftOptionsHidden { get; set {
           leftOptionsHidden = value;
           setOptions(leftOptions, value);
        }
    }
    
    // Backing for hidden text field containing the options from the
    // right list
    public String rightOptionsHidden { get; set {
           rightOptionsHidden = value;
           setOptions(rightOptions, value);
        }
    }
}

=====================
Visualforce Page
=======================
<apex:page controller="MultiselectExampleController" showHeader="false">
    <apex:form >
        <apex:pageBlock title="Contacts">
            <c:MultiselectPicklist leftLabel="Available Contacts"     leftOptions="{!allContacts}"  rightLabel="Selected Contacts"
                rightOptions="{!selectedContacts}"       size="14"   width="150px"/>
            <apex:pageBlockButtons >
                <apex:commandButton value="Save" action="{!save}"/>
            </apex:pageBlockButtons>
        </apex:pageBlock>
    </apex:form>
    <apex:outputText >{!message}</apex:outputText>
</apex:page>
=================================
Controller for the visualforce page
===============================public with sharing class MultiselectExampleController {

    public SelectOption[] selectedContacts { get; set; }
    public SelectOption[] allContacts { get; set; }
    
    public String message { get; set; }
    
    public MultiselectExampleController() {
        selectedContacts = new List<SelectOption>();
        
        List<Contact> contacts = [SELECT Name, Id FROM Contact];    
        allContacts = new List<SelectOption>();
        for ( Contact c : contacts ) {
            allContacts.add(new SelectOption(c.Id, c.Name));
        }
    }

    public PageReference save() {
        message = 'Selected Contacts: ';
        Boolean first = true;
        for ( SelectOption so : selectedContacts ) {
            if (!first) {
                message += ', ';
            }
            message += so.getLabel() + ' (' + so.getValue() + ')';
            first = false;
        }
        
        return null;       
    }
}
=====================
Ouput:
=========

Sunday, 3 February 2013

Think twice before you act


Long ago, there used to live a very great King by the name Nruga, the son of Ikshvaaku. He gave as many goodaanams as there are grains of sand on the earth, stars in the heavens, or drops in a rain shower. He gave the best quality kapila varna cows, decorated with pure golden hooves and horns, along with their calves. He gave them to the most learned braahmanas, whose families were in need, were young and possessed of excellent character and qualities, who were dedicated to truth, famous for their austerity, vastly learned in the Vedic scriptures and saintly in their behaviour. He performed many other such great daanams for the needy. In addition, he performed many yagnyas and executed various pious welfare activities.

Once, a cow owned by a learned braahmana wandered away and entered the herd being given as daanam by Nruga. Unaware that he was giving a cow that did not belong to him, he gave it to one other needy braahmana. When the owner of the cow saw his cow being taken away, he said "The cow belongs to me!" and the other said "No! It was given to me by Nruga." Nruga comes to know about this and offers each one of them a thousand cows of highest quality and asked them to save him from this difficult situation. However, both the braahmanas go away leaving the cow.

Yamadharmaraaja, after King Nruga leaves his physical body and comes to Yamaloka, asks Nruga "do you wish to experience the results of your paapam first, or those of your punya? Indeed, I see no end to the greatest daanams you have performed, or to your consequent enjoyment in the urdhva lokas. However, you made the sin of stealing a cow from a braahmana". Nruga chooses to face the consequences of his paapam first and immediately falls as a huge chameleon in a well. Since he always had bhakti towards the Lord and performed uncountable number of great daanams, he always remembered who he was, and what mistake he committed. He used to repent for his mistake and spent a very long time alone in the well, always doing Bhagavat-dhyaanam.

After a very long time, once when Shri Krishna, Saamba, Pradyumna, Chaaru, Bhaanu, Gada and other boys were playing, out of thrist they goto the well where Nruga was living. Out of pity, Shri Krishna takes him out of the well. The touch of the Lord of the universe made Nruga get a divya tejaswi form, with radiating kiritam and ornaments and tejas of Sun. On being asked by Shri Krishna, the Sarvagnya, the reason for the chameleon form, Nruga tells him his unfortunate story. He does a stotram to Lord krishna, does a pradakshinam, takes leave from the Lord and before the eyes of everyone flies to urdhva lokas in a divya vimaanam.

Morals in the Story:
1. Even for a great person like Nruga, one mistake, which he did unknowingly, made him experience the result of his paapam. Thus one should be very careful not to commit any kind of sin even unknowingly and lead a very ideal life.
2. Some or the other time, one must experience the results of his paapa or punya. However, if one surrenders himself to the God, He will lift you from the samsaaram and in the end give you kaivalyam, as Krishna did to Nruga.
3. Since Nruga never forgot remembering the Lord and the Lord was impressed by his great acts, Krishna granted him urdhva lokas in the end. So the end result for a good person will always be good.

Spring 13 Release Notes in visualforce


Visualforce includes the following enhancements in Spring ’13. For detailed information on these enhancements, refer to the Visualforce Developer’s Guide.
liveAgent:clientChatAlertMessage and liveAgent:clientChatStatusMessage Components

Spring ’13 introduces two new Live Agent Visualforce components, liveAgent:clientChatAlertMessage and
liveAgent:clientChatStatusMessage.
The liveAgent:clientChatAlertMessage component lets you customize the alert messages that appear in your Live
Agent chat window. For example, you can specify alerts that inform your customers when support agents are unavailable to
chat, or if a local connection error prevents the customer from connecting to Live Agent.
The liveAgent:clientChatStatusMessage component lets you customize system status messages that appear in your
Live Agent chat window. You can specify messages that inform your customers when the system connection is disrupted –
for example, “You've been disconnected from the agent. Please wait while we attempt to re-establish the connection.”
For more information about using these components, see the Visualforce Developer’s Guide and the Live Agent Developer’s
Guide.
New Label Attribute on Live Agent Components

Spring ’13 introduces a label attribute on several Live Agent components, allowing you to specify the text that appears. The
label attribute is available on the following components:
• <liveAgent:clientChatAlertMessage>
• <liveAgent:clientChatEndButton>
• <liveAgent:clientChatLog>
• <liveAgent:clientChatSaveButton>
• <liveAgent:clientChatSendButton>
• <liveAgent:clientChatStatusMessage>

Dependent Picklists Require Controlling Field on the Page

Pages must include the controlling field for a dependent picklist. Failing to include the controlling field on the page causes a
runtime error when the page displays.
For example, if Location.city is dependent on Location.state, you must include both in your markup:
<apex:form>
<apex:outputField value="{!Location.state}"/>
<apex:outputField value="{!Location.city}"/>
</apex:form>

This change is versioned, and you must update your Visualforce pages to API version 27.0 to enable the new behavior.
Previously, when the controlling field was missing, the dependent picklist would simply show all possible values. To preserve this behavior, keep the page version set to API version 26.0 or earlier.

Custom Component Descriptions are Escaped

Beginning in the Spring ’13 release, the Description field for custom Visualforce components is escaped when it’s displayed
in the component reference, and when viewing the component definition.
Previously, the Description field for custom components wasn’t escaped, making it possible to add HTML and other markup to the Description field. This wasn’t an intended feature, and is now explicitly prevented.
Custom components with markup in the Description need to be fixed. To fix them, edit the component and remove all HTML and other markup from the Description field.

Compile-Time Checking for Custom Component Attribute Names

In the Spring ’13 release, there is a new compile-time check that prevents giving custom Visualforce component attributes the same name as the assignTo value (which can refer to a property or method in the component’s controller). This checking prevents a number of programming errors (bugs) that can result in runtime errors.This change is versioned, and you must update your Visualforce components and the pages that contain them to API version 27.0 to enable the new behavior.Previously, it was possible to create a custom component with an attribute that had the same name as the assignTo value.

For example:
<apex:component>
<apex:attribute name="currentpagename" type="string" assignTo="{!currentpagename}" description="This component can't be saved."/>
This component is no longer allowed.
</apex:component>

Force.com Visualforce
To make this component compile under API version 27.0, change either the attribute name or the assignTo value (which
might require you to also change a controller method or property). For example:
<apex:component>
<apex:attribute name="thepagename" type="string"
assignTo="{!currentpagename}"
description="This component saves just fine."/>
This component is OK!
</apex:component>
Note: Both components, as well as the pages they are displayed on, must be updated to API version 27.0 to enable the new compile-time check.



Visualforce Support in Salesforce Touch


In Spring ’13, you can enable Visualforce tabs to display in Salesforce Touch, allowing users to access associated Visualforce pages directly from the Salesforce Touch interface. Other forms of Visualforce, including inline Visualforce, overridden Visualforce pages, and standard Visualforce buttons and links, aren’t supported in the Spring ’13 release of Salesforce Touch.

Visualforce tabs in Salesforce Touch are indicated by an icon. Tapping the icon opens the tab—and the associated Visualforce page—in a new mobile browser window outside of the Salesforce Touch interface. The Visualforce page functions the same as if you were viewing it in the full Salesforce site.

Note: When Visualforce tabs are accessed from the downloadable version of Salesforce Touch, the Visualforce page is rendered with showHeader=false so all header and sidebar navigation is suppressed. In the mobile browser app,the header and sidebar do display and can be used to navigate within Salesforce.
You enable the display of Visualforce tabs in Salesforce Touch using the new boolean metadata field on the ApexPage object,isAvailableInTouch. The “Author Apex” user permission is required. Edit the isAvailableInTouch field through the metadata API or through the Salesforce setup interface.
In Salesforce, click Your Name > Setup > Develop > Pages, edit the desired page, then select the Available in Touch checkbox. isAvailableInTouch is available for API version 27.0 and above.

After you enable a Visualforce page for Salesforce Touch, any tabs that are associated with the page will display in Salesforce Touch. You can enable any Visualforce page for Salesforce Touch but if the page isn’t associated with a Visualforce tab, users won’t be able to access the page from Salesforce Touch.

In addition to enabling the desired Visualforce tabs, you need to turn on Visualforce support in Salesforce Touch from the Salesforce Touch Settings page.

Here are some notes about Visualforce tab support in this release of Salesforce Touch:
• Standard object tabs that are overridden with a Visualforce page aren't supported in Salesforce Touch. The Visualforce page is shown for full site users but Salesforce Touch users will see the default Salesforce Touch page for the entity instead. This restriction exists to maintain the Salesforce Touch experience for standard objects.

• Other Visualforce pages that are accessed from a Salesforce Touch-enabled Visualforce page don't need to have isAvailableInTouch enabled.

• The Mobile Ready checkbox on Visualforce Tab setup pages is for the Salesforce Mobile app only and has no effect on Visualforce in Salesforce Touch.


Spring 13 Release Notes in Apex



New Classes and Methods
These Apex classes have been added.
Cases
• TimeZone

Also, new UserInfo methods have been added.
Cases Class
Usage

Use the Cases class to interact with case records.

 Cases class Methods


Method Name:getCaseIdFromEmailThreadId()

Description:Returns the case ID corresponding to the specified email thread ID.The emailThreadId argument should have the following format:

_00Dxx1gEW._500xxYktg.
getCaseIdFromEmailThreadId String emailThreadId ID
Other formats, such as
ref:_00Dxx1gEW._500xxYktl:ref and
[ref:_00Dxx1gEW._500xxYktl:ref],
are invalid.


Cases Example

The following example uses an email thread ID to retrieve the related case ID.
public class GetCaseIdController {
public static void getCaseIdSample() {
// Get email thread ID
104
Force.com Apex Code
String emailThreadId = '_00Dxx1gEW._500xxYktg';
// Call Apex method to retrieve case ID from email thread ID
ID caseId = Cases.getCaseIdFromEmailThreadId(emailThreadId);
}
}

TimeZone Methods


Represents a time zone. Contains methods for creating a new time zone and obtaining time zone properties, such as the time
zone ID, offset, and display name.
Usage
You can use the methods in this class to get properties of a time zone, such as the properties of the time zone returned by
UserInfo.getTimeZone, or the time zone returned by getTimeZone of this class.
Methods
The following is the static method of the Timezone class.

getTimeZone()


Returns the time zone corresponding to the specified time zone ID.The time zone values you can use for the Id argument are any valid time zone values that the
Java TimeZone class supports. getTimeZone String Id TimeZone

Example:

TimeZone tz = TimeZone.getTimeZone('America/Los_Angeles');
System.assertEquals('Pacific Standard Time',tz.getDisplayName());

getDisplayName()




Returns this time zone’s display name.

getID()

Returns this time zone’s ID.

getOffset()


Returns the time zone offset, in milliseconds, of the specified date to the GMT time zone.The date argument is the date and time to evaluate.getOffset Datetime date Integer
Note: The returned offset is adjusted for daylight saving time if the date argument falls within daylight saving time for this
time zone.

toString()

Returns the string representation of this time zone


Sample
This example shows how to get properties of the current user’s time zone and displays them to the debug log.

TimeZone tz = UserInfo.getTimeZone();
System.debug('Display name: ' + tz.getDisplayName());
System.debug('ID: ' + tz.getID());
// During daylight saving time for the America/Los_Angeles time zone
System.debug('Offset: ' + tz.getOffset(DateTime.newInstance(2012,10,23,12,0,0)));
// Not during daylight saving time for the America/Los_Angeles time zone
System.debug('Offset: ' + tz.getOffset(DateTime.newInstance(2012,11,23,12,0,0)));
System.debug('String format: ' + tz.toString());


The output of this sample varies based on the user's time zone. This is an example output if the user’s time zone is
America/Los_Angeles. For this time zone, daylight saving time is -7 hours from GMT (-25200000 milliseconds) and standard
time is -8 hours from GMT (-28800000 milliseconds).
Display name: Pacific Standard Time
ID: America/Los_Angeles
Offset: -25200000
Offset: -28800000
String format: America/Los_Angeles

New UserInfo Methods

getTimeZone()




Returns the current user’s local time zone.
Example:
TimeZone tz =UserInfo.getTimeZone();
System.debug('Display name: ' +tz.getDisplayName());
System.debug('ID: ' +tz.getID());

getUserEmail()



Returns the current user’s email address.
Example:
String emailAddress =UserInfo.getUserEmail();
System.debug('Email address: ' +emailAddress);

Connect in Apex—Developer Preview


Note: Connect in Apex is currently available as a Developer Preview and is automatically available in all Developer
Edition organizations. For information on enabling Connect in Apex in other editions, contact Salesforce.
Connect in Apex exposes Chatter API data as Apex objects. Use classes in the ConnectApi namespace to develop Chatter
applications on the Force.com platform without using Apex callouts
The following documentation is available:
• To find out what’s new in Connect in Apex in Spring ‘13, see Connect in Apex—Developer Preview.
• The complete Connect in Apex documentation is available in the Chatter REST API Developer’s Guide from developerforce.com.
• Connect in Apex recipes are available in the Force.com Cookbook.


Triggers for CollaborationGroup and CollaborationGroupMember

Triggers are now available for CollaborationGroup and CollaborationGroupMember sObjects. You can create the
triggers by clicking Your Name > Setup > Customize > Chatter > Triggers, and then selecting CollaborationGroup Triggers or CollaborationGroupMember Triggers.

Note the following for the CollaborationGroup and CollaborationGroupMember objects:

• When CollaborationGroupMember is updated, CollaborationGroup is automatically updated as well to ensure that the member count is correct. As a result, when CollaborationGroupMember update or delete triggers run,
CollaborationGroup update triggers run as well.

• CollaborationGroup and CollaborationGroupMember objects can't be undeleted. Triggers marked only as after undelete will not be executed.


Setting Id Fields on sObjects for Updates

Starting with Apex code saved using Salesforce.com API version 27.0, the Id field is now writeable on sObject instances for all sObject types—standard objects, custom objects, and generic sObjects—for update operations. The insert operation doesn’t support setting Id fields on sObjects.

// Account a has some fields set
a.Phone = '(415) 555-1212';
// Also, set its Id field
a.Id = '00199000002JMim';
update a;

Previously, you couldn’t set the Id field after having created or obtained an sObject, such as an instance of Account. You could set the Id field only in the sObject’s constructor.
This change enables you to update existing records that correspond to sObject instances you already have, such as sObjects you obtained from deserializing JSON input. To do so, set the Id field on the sObjects to IDs of existing records in the database and call update. This call updates the corresponding records with all the other fields that are set on the sObjects.

This example shows that you can perform an update using any sObject reference of the same sObject type as long as you set the appropriate ID. First, this example creates two accounts, the second of which has an Industry field. Next, it updates the Industry field on the first account using the sObject reference of the second account (otherAcct) and sets the Id field on the sObject reference to the ID of the first account. It calls update and verifies that the Industry field has been set on the first account.

// Insert two accounts
Account acctToUpdate = new Account(Name='Account1');
insert acctToUpdate;
Account otherAcct = new Account(Name='Account2', Industry='Consulting');
insert otherAcct;
// Update the first account.
// The secondAcct sObject has the Industry field set.
// To update the first account with this same field, just set the ID
// to the first account on the sObject of the second account.
otherAcct.Id = acctToUpdate.Id;
update otherAcct;
// Verify the Industry is updated.
Account acctAfterUpdate = [SELECT Id,Name,Industry FROM Account WHERE Id=:acctToUpdate.Id];
System.assertEquals('Consulting', acctAfterUpdate.Industry);





Tests Started from the Apex Classes Page Run Asynchronously

When you run tests in the Apex Classes page by clicking Your Name > Setup > Develop > Apex Classes, and then either
clicking Run All Tests from the Apex Classes page or Run Test from a class page, the Apex tests now run asynchronously, and both the Developer Console and the Apex Test Execution page display your test results. Tests started through Run All Tests or Run Test no longer run synchronously.

Note that Apex tests that are run as part of a deployment, a package install, or a package upload, still run synchronously





Passing parameters or values to flow variables

We can pass parameters or values to flow variables.

For example i have a flow with opportunity details.Here i am navigating to this flow  from a custom detail page button on account.Here i want to pass Account Id to flow variable 'accountid' opportunity flow included in vf page.

Now construct a url  in our custom button as shown below

"/apex/pagename?accountid={!Account.Id}"

then the flow included in the vf page can get the value from 'accountid' parameter to 'accountid' variable inflow.

Here we should remember one thing.
Here both url parameter name and variable name in flow should be same.

Sorting Custom Picklist values


Sorting  custom picklist values prepared from controller is very easy when we use same values for both value and label of picklist
Here i am preparing picklist with same values for both value and label of the picklist.

List<user> lstuser=[select id,name from User];
Public List<Selectoption> lstoption{get;set;}

for(User uobj:lstuser){

lstoption.add(new selectoption(u.name,u.name));

}

in the above selectoption list having user name for both value and label
so we can sort this list by using "sort()" method as below.

eg:lstoption.sort();
===


But whenever the picklist doesn't have same values for value and label of piclist then

you cannot sort directly by using sort() method.Even it is applicable but it

doesn't sort your values properly.

See here in my case i have a picklist having  user Id as value and user name as label

now i need to have sort th picklist.

List<user> lstuser=[select id,name from User];
Public List<Selectoption> lstoption{get;set;}

for(User uobj:lstuser){

lstoption.add(new selectoption(u.id,u.name));

}


when you apply sort() method for the above selectoption list it is not sorting properly.

whenever we have the situation like this we need to apply some logic as shown below.

1)Make a string with the combination of username and user id with seperation of any character for splitting.
Add the string to string list for every iteration.
2)Then sort the string list.
3)After that iterate through the string list and split it to id,name assign them to selectoption list.


eg:
===

List<SelectOption> lstoptions=new List<SelectOption>();
List<String> lststring=new List<String>();

for(User uobj:lstuser){

lststring.add(uobj.name+'#'+u.id);//(1) step

}
lststring.sort();//(2) step
//(3) step
for(String s:lststring){
  List<String> luidname=s.split('#');
lstoptions.add(new selectoption(luidname[1],luidname[0]));

}

Now you can get the values in sorting order from selectoption list "lstoptions"