Friday, October 26, 2012

Create Product record with Standard Price in APEX

Post API 24, we have to create all our data for test classes until we set SeeAllData to true. http://www.salesforce.com/us/developer/docs/apexcode/Content/apex_testing_data_access.htm

However you cannot create OLI or PricebookEntry without setting SeeAllData since you cannot create a default Pricebook using custom code.



 Pricebook2 pb = [select Id, IsActive from PriceBook2 where IsStandard=True];

 Product2 p1 = new Product2(Name='Prod 1', Family='Container', Description='Prod 1 Description');
 insert p1;
           
 // Create a pricebook entry
 PricebookEntry pbe = new PricebookEntry (Pricebook2Id=pb.id, Product2Id=p1.id, IsActive=true, UnitPrice=100.0);
 insert pbe;

 

Thursday, October 25, 2012

Creating Custom Setting record using APEX

Since API 24, you cannot use existing Salesforce data in your test classes until you set SeeAllData to true. (http://www.salesforce.com/us/developer/docs/apexcode/Content/apex_testing_data_access.htm)

Hence you would require data in Custom Settings too to be available to your code. Creating a new record for Custom Settings is also same as that for any other Standard or Custom Object.

Custom_Settings__c cs = new Custom_Settings__c (Name='Owner_Name', Value__c='HS');
insert cs;


Monday, October 22, 2012

Increase font size in Shabad View in SikhiToTheMaxII

For Sikhi To The Max version 2, I don't want to have the power point view where I can see only one tuk at a time. I want a way so that I can see the shabad in the default "Shabad View" and that too it is readable on a TV screen. Some how I want to increase the font size in the Shabad View in Sikhi To The Max version 2

By default the application does not provide any dropdown to select a font size. However using keyboard you can do so. Select the complete shabad or a line and
Ctrl + Shift + >      to increase font size.
Ctrl + Shift + <      to decrease font size.

However this has a limitation that if you Split Shabad or Reset Shabad, the size restores to default. But still you do get continuous shabad with increased font size without PowerPoint.




Friday, October 19, 2012

How to use DataTables

Datatables a real strong library to create really cool tables using minimum handling and maximum functionality like searching, sorting, fixed headers, pagination etc. etc.. How to create a new table using DataTables from a simple HTML table. I used this implementation in Salesforce but you can easily use the same on any web technology.

    <script>
        var j$ = jQuery.noConflict(); // In Salesforce to avoid any conflict.

        j$(document).ready(function() {
            var teTable = j$('#ActivityTable').dataTable( {
                "sScrollY": 200,
                "bPaginate": true,
                "iDisplayLength": 300,
                "bScrollCollapse": false,
                "sDom": 'tips',
                "sPaginationType" : 'two_button',
                "bSort": true,
                "aaSorting": [[2,'desc']],
                "aoColumnDefs": [
                      { "bSearchable": false, "aTargets": [ 0, 1, 2, 3, 4, 5 ] },
                      { "bVisible": false, "aTargets": [ 6, 7, 8 ] }
                ]
            } );
        } );


    </script>

For more details on all functions refer to http://www.sprymedia.co.uk/article/DataTables 

To allow creation of filters based on data in the table, use the following

    (function(j$) {
    /*
     * Function: fnGetColumnData
     * Purpose:  Return an array of table values from a particular column.
     * Returns:  array string: 1d data array
     * Inputs:   object:oSettings - dataTable settings object. This is always the last argument past to the function
     *           int:iColumn - the id of the column to extract the data from
     *           bool:bUnique - optional - if set to false duplicated values are not filtered out
     *           bool:bFiltered - optional - if set to false all the table data is used (not only the filtered)
     *           bool:bIgnoreEmpty - optional - if set to false empty values are not filtered from the result array
     * Author:   Benedikt Forchhammer
     */
    j$.fn.dataTableExt.oApi.fnGetColumnData = function ( oSettings, iColumn, bUnique, bFiltered, bIgnoreEmpty ) {
        // check that we have a column id
        if ( typeof iColumn == "undefined" ) return new Array();
       
        // by default we only want unique data
        if ( typeof bUnique == "undefined" ) bUnique = true;
       
        // by default we do want to only look at filtered data
        if ( typeof bFiltered == "undefined" ) bFiltered = true;
       
        // by default we do not want to include empty values
        if ( typeof bIgnoreEmpty == "undefined" ) bIgnoreEmpty = true;
       
        // list of rows which we're going to loop through
        var aiRows;
       
        // use only filtered rows
        if (bFiltered == true) aiRows = oSettings.aiDisplay;
        // use all rows
        else aiRows = oSettings.aiDisplayMaster; // all row numbers
   
        // set up data array 
        var asResultData = new Array();
       
        for (var i=0,c=aiRows.length; i
<c; i++) {
            iRow = aiRows[i];
            var aData = this.fnGetData(iRow);
            var sValue = aData[iColumn];
           
            // ignore empty values?
            if (bIgnoreEmpty == true && sValue.length == 0) continue;
   
            // ignore unique values?
            else if (bUnique == true && jQuery.inArray(sValue, asResultData)
&gt; -1) continue;
           
            // else push the value onto the result data array
            else asResultData.push(sValue);
        }
       
        return asResultData;
    }}(jQuery));
 


This function iterates through the data and provides you the list of select options. We will use this function to create a select input field for search.

In the document ready event, add the following

    j$("#recordTypeFilter").each( function () {
        this.innerHTML = fnCreateRecordTypeSelect( teTable.fnGetColumnData(6) );
        j$('select', this).change( function () {
            teTable.fnFilter( j$(this).val(), 6 );
        } );
    } );


 and this function to the script tag of js library.

    function fnCreateRecordTypeSelect( aData ) {
        var r='< select> <option value=""> --All-- </option>', i, iLen=aData.length;
        for ( i=0 ; i<iLen ; i++ ) {
            r += '<option value="'+aData[i]+'">'+aData[i]+'</option>';
        }
        return r+'</select>';
    }


You can refer to more live examples on datatables here - http://www.datatables.net/examples/

Allow datatables to filter data on page load

To allow datatables to filter data on page load itself use

$(document).ready(function() {
    oTable = $('#example').dataTable();

    /* Filter immediately all columns */
    oTable.fnFilter( 'test string' );
     /* Filter only 2nd columns */
    oTable.fnFilter( 'test string', 2 );
} );

Thursday, September 13, 2012

Google Visualization APIs with Salesforce

Google Visualization API samples being used with Salesforce

Good thing about this is that these are available for public sites as well where we cannot use Reports and Dashboards. Refer to Google Charts here and here

Here are two sample pages (link1 and link2) displaying charts on Salesforce public site.

To see the code install this unmanaged package; open "Google Charts" Apps and select Chart1 and Chart2 tabs. The code uses Google Visualization project from Code Share. Here are the sample images of Google Charts being used on Salesforce public site.





Wednesday, September 5, 2012

Adding a wait screen for Salesforce AJAX request

While working on one of the Sites project in Salesforce, a requirement was that clicking on checkbox against a row in the table, it should create a record and then reload the table without refreshing the complete page. Everything was simple but one of the requirement was to show a wait screen when user clicks on checkbox. Searching around, I came across this implementation - http://jsfiddle.net/jonathansampson/VpDUG/170/ 
I really liked this implementation - simple, clean and minimal. Referring to this I did the implementation in my Salesforce page.

What I used
As in the example, I used jQuery, a cool cool js library to get this working. Add javascript library to your static resources and inside the script tag on your page define j$ variable as
var j$ = jQuery.noConflict();

Here are the steps:
  • Add a div tag to the end of page.
<div class="modal"></div>

  • Add style tag to the page with following contents
/* Start by setting display:none to make this hidden.
   Then we position it in relation to the viewport window
   with position:fixed. Width, height, top and left speak
   speak for themselves. Background we set to 80% white with
   our animation centered, and no-repeating */
.modal {
    display:    none;
    position:   fixed;
    z-index:    1000;
    top:        0;
    left:       0;
    height:     100%;
    width:      100%;
    background: rgba( 255, 255, 255, .8 ) 
                url('http://sampsonresume.com/labs/pIkfp.gif') 
                50% 50% 
                no-repeat;
}

/* When the body has the loading class, we turn
   the scrollbar off with overflow:hidden */
body.loading {
    overflow: hidden;   
}

/* Anytime the body has the loading class, our
   modal element will be visible */
body.loading .modal {
    display: block;
}


  • Create an actionFunction tag based on your requirements. tableList is the id of table that gets re-rendered after AJAX request. Note that we are using onComplete event too.
<apex:actionFunction name="jsActionFunction"  action="{!ServerSideFunction}"  rerender="tableList" oncomplete="jsDoConsiderMeComplete()">
    <apex:param name="eid" value=""/>
    <apex:param name="eName" value=""/>
</apex:actionFunction>

  • Set the onClick event of inputCheckbox
<apex:inputCheckBox value="{!lst.isChecked}" id="chkbx1" onclick="checkBoxClick('{!lst.eId}', '{!lst.eName}')" />


  • Create a javascript function that first displayed the wait screen and then calls the actionFunction method. Another function to hide the wait screen.

function checkBoxClick( eId, eName ) {
    j$('body').addClass("loading");
    jsActionFunction(eId, eName);
}
function jsDoConsiderMeComplete() {
    j$('body').removeClass("loading"); 
}

Make these changes, save the page, fix the issues if any and it should work just the way it is working in the sample page.