Monday, October 13, 2014

Disabled Save Button on Forms while Saving in Salesforce



How to Disable the Save Button on your Form while the Form is Saving to Prevent Multiple Submissions in a Custom Salesforce Visualforce Page



Salesforce default functionality on forms will disable the save button after the form is submitted to prevent multiple submissions.

The disabled Save button will look like:

Disabled save button after submitting a form in Salesforce
Disabled save button after form submit

When creating your own VisualForce page you can write custom code to mimic this functionality in your forms using just Javascript and modifying the button's CSS styles.





Create Javascript functions to disable and enable the save button




You will need to create 2 Javascript functions that will enable and disable the button by modifying the css and properties of the save button.

I am using jQuery but you can also do this with vanilla Javascript. I am currently using a unique style class attached to the button to look it up for convenience since this page does not get modified very often if ever and also because the element id is used by Salesforce for internal SFDC functionality.

    function disableSave() {
     j$(".saveButtonId").prop("disabled","true");
        j$(".saveButtonId").val("Saving...");
                
        j$(".saveButtonId").css( "border-color", "#c4c4c4" );
        j$(".saveButtonId").css( "color", "#909090" );
    }

    function enableSave() {
        j$(".saveButtonId").removeProp( "disabled" )
        j$(".saveButtonId").val("Save");
            
        j$(".saveButtonId").css( "border-color", "#7f7f7f" );
        j$(".saveButtonId").css( "color", "#333" ); 
    }    


Add events to the Salesforce save button on your Visualforce Page




You will then need to bind your Javascript functions to the onclick and oncomplete event on your save button. I am using binding within the tag since I am using a custom apex:commandbutton Visualforce tag to create the save button.

This will disable the save button on click and re-enable the button when the AJAX request completes that clicking your save button initiated.

<apex:commandbutton action="{!save}" onclick="disableSave()" oncomplete="enableSave()" status="savingStatus" styleclass="saveButtonId" value="Save"> 
</apex:commandbutton>

Tuesday, August 26, 2014

Setup Service Rocket Connector for Salesforce.com and JIRA

Setup Service Rocket Connector for Salesforce.com and JIRA





Are you looking into integrating Salesforce and JIRA? The following product comes pre-installed on Cloud On-Demand JIRA instances.

Service Rocket Connector for Salesforce.com and JIRA

The ServiceRocket Connector for Salesforce.com and JIRA links and synchronizes Salesforce.com cases and JIRA issues for an integrated experience from either interface.


Add your Application Link to JIRA for your Salesforce instance




First you need to go into your Add-ons section and navigate to the add a application link for your Salesforce instance:


Add application link


Add your salesforce domain:


Add application link


Get your SEN Number



You will need your SEN number to setup the plugin.

Finding the JIRA Support Entitlement Number (SEN)


Acquire a Connector License



You will need to acquire a license for the Salesforce JIRA connector.  Navigate to the following link to acquire a license which will be valid for 30 days.

Get a Connector License


You will receive an email with the following heading:  "Download - Connector for Salesforce.com and JIRA"

Within the email, click on:  User Profile


Download your license

Download License



Upload your license file

Upload your license file





Setup Connector 




You will need to create a new cloud connection to your Salesforce instance using your Application Link.

For password, you will want to append your security token on the end of your password when you configure authentication.

Setup connector

Tuesday, July 22, 2014

Create a Salesforce User in Apex with all Required Fields Populated



Create a Salesforce User with Code in Apex with all of the Required Fields Populated for a Test Class



When attempting to create a user with code in Apex you will encounter an error if you do not populate every single required field. You may be attempting to do this for a Test class or for any number of reasons. The error you encounter may look similar to the following:

Missing fields Exception

System.DmlException: Insert failed. First exception on row 0; first error: REQUIRED_FIELD_MISSING, Required fields are missing: [LastName, Email, Alias, TimeZoneSidKey, LocaleSidKey, EmailEncodingKey, ProfileId, LanguageLocaleKey]: [LastName, Email, Alias, TimeZoneSidKey, LocaleSidKey, EmailEncodingKey, ProfileId, LanguageLocaleKey]


Create a User




Many of those fields require specific values populated from a picklist. Below is some boilerplate code you can use to create a use programmatically with all of those fields populated correctly. You can use your own values for timezonesidkey and locale if desired. They are listed below.

List of TimeZoneSidKey values you can use

Pacific/Kiritimati
Pacific/Chatham
Pacific/Auckland
Pacific/Enderbury
Pacific/Fiji
Pacific/Tongatapu
Asia/Kamchatka
Pacific/Norfolk
Australia/Lord_Howe
Australia/Sydney
Pacific/Guadalcanal
Australia/Adelaide
Australia/Darwin
Asia/Seoul
Asia/Tokyo
Asia/Hong_Kong
Asia/Kuala_Lumpur
Asia/Manila
Asia/Shanghai
Asia/Singapore
Asia/Taipei
Australia/Perth
Asia/Bangkok
Asia/Ho_Chi_Minh
Asia/Jakarta
Asia/Rangoon
Asia/Dhaka
Asia/Yekaterinburg
Asia/Kathmandu
Asia/Colombo
Asia/Kolkata
Asia/Karachi
Asia/Tashkent
Asia/Kabul
Asia/Dubai
Asia/Tbilisi
Europe/Moscow
Asia/Tehran
Africa/Nairobi
Asia/Baghdad
Asia/Kuwait
Asia/Riyadh
Europe/Minsk
Africa/Cairo
Africa/Johannesburg
Asia/Jerusalem
Europe/Athens
Europe/Bucharest
Europe/Helsinki
Europe/Istanbul
Africa/Algiers
Europe/Amsterdam
Europe/Berlin
Europe/Brussels
Europe/Paris
Europe/Prague
Europe/Rome
Europe/Dublin
Europe/Lisbon
Europe/London
GMT
Atlantic/Cape_Verde
America/Sao_Paulo
Atlantic/South_Georgia
America/Argentina/Buenos_Aires
America/Santiago
America/St_Johns
America/Halifax
America/Puerto_Rico
Atlantic/Bermuda
America/Caracas
America/Bogota
America/Indiana/Indianapolis
America/Lima
America/New_York
America/Panama
America/Chicago
America/El_Salvador
America/Mexico_City
America/Denver ****America/Denver
America/Phoenix
America/Los_Angeles
America/Tijuana
America/Anchorage
Pacific/Honolulu
Pacific/Niue
Pacific/Pago_Pago


List of LocaleSidKey values you can use

sq
sq_AL
ar
ar_BH
ar_EG
ar_JO
ar_KW
ar_LB
ar_QA
ar_SA
ar_AE
hy
hy_AM
az_AZ
eu
eu_ES
be_BY
bn_BD
bs
bs_BA
bg
bg_BG
ca
ca_ES_EURO
ca_ES
zh
zh_CN_PINYIN
zh_CN_STROKE
zh_CN
zh_HK_STROKE
zh_HK
zh_MO
zh_SG
zh_TW_STROKE
zh_TW
hr
hr_HR
cs
cs_CZ
da
da_DK
nl
nl_BE
nl_NL
nl_SR
en_AU
en_BB
en_BM
en_CA
en_GH
en_IN
en_ID
en_IE_EURO
en_IE
en_MY
en_NZ
en_NG
en_PK
en_PH
en_SG
en_ZA
en_GB
en_US
et
et_EE
fi
fi_FI_EURO
fi_FI
fr
fr_BE
fr_CA
fr_FR_EURO
fr_FR
fr_LU
fr_MC
fr_CH
ka
ka_GE
de
de_AT_EURO
de_AT
de_DE_EURO
de_DE
de_LU_EURO
de_LU
de_CH
el
el_GR
iw
iw_IL
hi
hi_IN
hu
hu_HU
is
is_IS
in
in_ID
ga
ga_IE
it
it_IT
it_CH
ja
ja_JP
kk_KZ
km_KH
ky_KG
ko
ko_KR
lv
lv_LV
lt
lt_LT
lb
lb_LU
mk
mk_MK
ms
ms_BN
ms_MY
mt
mt_MT
sh_ME
no
no_NO
pl
pl_PL
pt
pt_AO
pt_BR
pt_PT
ro
ro_MD
ro_RO
rm
rm_CH
ru
ru_RU
sr
sr_BA
sh
sh_BA
sh_CS
sr_CS
sk
sk_SK
sl
sl_SI
es
es_AR
es_BO
es_CL
es_CO
es_CR
es_DO
es_EC
es_SV
es_GT
es_HN
es_MX
es_PA
es_PY
es_PE
es_PR
es_ES_EURO
es_ES
es_UY
es_VE
sv
sv_SE
tl
tl_PH
tg_TJ
th
th_TH
tr
tr_TR
uk
uk_UA
ur
ur_PK
vi
vi_VN
cy
cy_GB


List of EmailEncodingKey values you can use

UTF-8
ISO-8859-1
Shift_JIS
ISO-2022-JP
EUC-JP
ks_c_5601-1987
Big5
GB2312


List of LanguageLocaleKey values you can Use

Chinese (Simplified): zh_CN
Chinese (Traditional): zh_TW
Danish: da
Dutch: nl_NL
English: en_US
Finnish: fi
French: fr
German: de
Italian: it
Japanese: ja
Korean: ko
Portuguese (Brazil): pt_BR
Russian: ru
Spanish: es
Swedish: sv
Thai: th
Arabic: ar
Bulgarian: bg
Czech: cs
English (UK): en_GB
Greek: el
Spanish (Mexico): es_MX
Hebrew: iw
Hungarian: hu
Indonesian: in
Norwegian: no
Polish: pl
Romanian: ro
Turkish: tr
Ukrainian: uk
Vietnamese: vi
Albanian: sq
Armenian: hy
Basque: eu
Bosnian: bs
Croatian: hr
English (Australia): en_AU
English (Canada): en_CA
English (India): en_IN
English (Malaysia): en_MY
English (Philippines): en_PH
Estonian: et
French (Canada): fr_CA
Georgian: ka
Hindi: hi
Icelandic: is
Irish: ga
Latvian: lv
Lithuanian: lt
Luxembourgish: lb
Macedonian: mk
Malay: ms
Maltese: mt
Moldovan: ro_MD
Montenegrin: sh_ME
Portuguese (European): pt_PT
Romansh: rm
Serbian (Cyrillic): sr
Serbian (Latin): sh
Slovak: sk
Slovenian: sl
Tagalog: tl
Urdu: ur
Welsh: cy


Code to create a user in Apex

        User user = new User();
        
        user.FirstName = 'Test';
        user.LastName = 'Name';
        user.CompanyName = 'IT Test Company';
        user.MobilePhone = '123-456-7890';
        
        user.Username = 'testUser-' + generateRandomString() + '@test.com';
        user.Email = 'testUser-' + generateRandomString() + '@test.com';
  user.Alias = 'test';
        user.CommunityNickname = 'test1';
        user.TimeZoneSidKey = 'America/New_York';
        user.LocaleSidKey = 'en_US';
        user.EmailEncodingKey = 'UTF-8';
        user.ProfileId = prof.Id;
        user.LanguageLocaleKey = 'en_US';
        
        user.Street = '123 Test St';
        user.City = 'Testcity';
        user.State = 'va';
        user.PostalCode = '23223';
        user.Country = 'USA';
        
        insert user;


Generate a Random Numeric String

    private static String generateRandomString() {
        return '' + math.rint( math.random() * 100000 );
    }


Here is a link to a user having a similar problem on the Salesforce forums: Creating a user in Apex

Using System.runAs() to Run Code as the User you just Created




After creating that user, you may want to explicitly run code as this user. You may want to check permissions or sharing rules are applying correctly to that user's profile for instance. You can accomplish this using a runAs block and passing in the user you just created.

IsTest Annotation to use Existing Data in Test Class

          System.runAs(user) {
             // The following code runs as user 'u' 
             System.debug('Current User: ' + UserInfo.getUserName());
      // Perform user specific operations here            
          }



More info on the runAs command here: Salesforce runAs Documentation

It is also documented in this Salesforce article: Salesforce Intro to Testing

Avoid Staging User Data by Using Existing Data




Alternatively, you may be able to avoid having to stage user data entirely by using existing data in the database. If you want your Test Class to use existing data in your environment, whether its Sandbox or Test or Prod, you can use the following modification to the isTest annotation:

IsTest Annotation to use Existing Data in Test Class

@IsTest(SeeAllData=true)


Place the annotation above the class declaration for your test class. Then your test class should have access to all of your organization's data in your Salesforce instance. Be sure to consider your use cases when deciding to use existing data or staging new data.

Additional info on the @IsTest annotation: IsTest Annotation

Tuesday, July 1, 2014

Salesforce Combobox Autocomplete in IE8 using jQuery


Creating a Combobox Autocomplete Input Field Compatible with Internet Explorer 8+ using jQuery





Issues with Built-in Combobox functionality in Visualforce



If you try to use the off-the-shelf apex tag to using a inputText field to create a combobox by passing in a list of comma-separated values you will get a nasty surprise when you try to open the page in Internet Explorer. Even though IE is officially supported, it will not display correctly.

Apex Default Combobox Tag

 <apex:inputtext list="{!getAccounts}" value="{!accountName}"></apex:inputtext>  


A great way to get around this limitation is to use the jQuery combo box. The jQuery combo box is not a standard widget and will not be packed into the jQuery UI by default, but you can configure it with a reasonable amount of code.

You will need the following libs:
  • jQuery javascript library - jQuery
  • jQuery UI javascript library - jQuery UI




Avoid conflicts with the Prototype library built into Salesforce



Use this line of code at the top of your visualforce page to avoid conflicts with other javascript libraries. Salesforce uses the Prototype library behind the scenes to implement much of it's functionality. You will need to use j$ instead of $ in all of your jQuery code after using this snippet to avoid conflicts.

Avoid Conflicts with other Javascript Libs

var j$ = jQuery.noConflict();


Configure your Combobox



Then this code will initialize and configure your basic combo box functionality. You can modify various functions and behaviors of the combobox here such as the duration that tooltips display or the names of the css classes applied to your widget.

Configure your jQuery Combobox Widget

  (function( $ ) {  
   j$.widget( "custom.combobox", {  
    _create: function() {  
     this.wrapper = $( "<span>" )  
      .addClass( "custom-combobox" )  
      .insertAfter( this.element );  
     this.element.hide();  
     this._createAutocomplete();  
     this._createShowAllButton();  
    },  
    _createAutocomplete: function() {  
     var selected = this.element.children( ":selected" ),  
      value = selected.val() ? selected.text() : "";  
     this.input = j$( "<input>" )  
      .appendTo( this.wrapper )  
      .val( value )  
      .attr( "title", "" )  
      .addClass( "custom-combobox-input ui-widget ui-widget-content ui-state-default ui-corner-left" )  
      .autocomplete({  
       delay: 0,  
       minLength: 0,  
       source: $.proxy( this, "_source" )  
      })  
      .tooltip({  
       tooltipClass: "ui-state-highlight"  
      });  
     this._on( this.input, {  
      autocompleteselect: function( event, ui ) {  
       ui.item.option.selected = true;  
       this._trigger( "select", event, {  
        item: ui.item.option  
       });  
      },  
      autocompletechange: "_removeIfInvalid"  
     });  
    },  
    _createShowAllButton: function() {  
     var input = this.input,  
      wasOpen = false;  
     j$( "<a>" )  
      .attr( "tabIndex", -1 )  
      .attr( "title", "Show All Items" )  
      .tooltip()  
      .appendTo( this.wrapper )  
      .button({  
       icons: {  
        primary: "ui-icon-triangle-1-s"  
       },  
       text: false  
      })  
      .removeClass( "ui-corner-all" )  
      .addClass( "custom-combobox-toggle ui-corner-right" )  
      .mousedown(function() {  
       wasOpen = input.autocomplete( "widget" ).is( ":visible" );  
      })  
      .click(function() {  
       input.focus();  
       // Close if already visible  
       if ( wasOpen ) {  
        return;  
       }  
       // Pass empty string as value to search for, displaying all results  
       input.autocomplete( "search", "" );  
      });  
    },  
    _source: function( request, response ) {  
     var matcher = new RegExp( $.ui.autocomplete.escapeRegex(request.term), "i" );  
     response( this.element.children( "option" ).map(function() {  
      var text = $( this ).text();  
      if ( this.value && ( !request.term || matcher.test(text) ) )  
       return {  
        label: text,  
        value: text,  
        option: this  
       };  
     }) );  
    },  
    _removeIfInvalid: function( event, ui ) {  
     // Selected an item, nothing to do  
     if ( ui.item ) {  
      return;  
     }  
     // Search for a match (case-insensitive)  
     var value = this.input.val(),  
      valueLowerCase = value.toLowerCase(),  
      valid = false;  
     this.element.children( "option" ).each(function() {  
      if ( j$( this ).text().toLowerCase() === valueLowerCase ) {  
       this.selected = valid = true;  
       return false;  
      }  
     });  
     // Found a match, nothing to do  
     if ( valid ) {  
      return;  
     }  
     // Remove invalid value  
     this.input  
      .val( "" )  
      .attr( "title", value + " Select a value" )  
      .tooltip( "open" );  
     this.element.val( "" );  
     this._delay(function() {  
      this.input.tooltip( "close" ).attr( "title", "" );  
     }, 900 );  
     this.input.autocomplete( "instance" ).term = "";  
    },  
    _destroy: function() {  
     this.wrapper.remove();  
     this.element.show();  
    }  
   });  
  })( jQuery );  



Create a select box



Then you need to create a select dropdown element. This is being accomplished down here using a dynamic apex:selectList while passing in a List of SelectOptions and tracking the value of the selected option using a String from the Apex Controller.

Create your Select box Dropdown using a Dynamic VisualForce selectList Tag

  <div class="ui-widget">  
    <apex:selectList multiselect="false" size="1" title="Select box" value="{!selectBoxValue}" label="Duration" styleClass="largeInput comboboxSelectBox">                  
    <apex:selectOptions value="{!selectBoxList}"/>  
    </apex:selectList>  
 </div>  

Add a Variable to Apex Controller



This variable will be in your apex controller to store the value of the selectbox. This String will store the ID of the currently selected value.

Apex Controller Value

 
public String transactionDateRangeVal {get; set;}


Generate values for your select list



This Apex method in your controller will create the list of values for your select list. You will be returning a List of SelectOption objects back to your select box which will automatically generate the select box from that list which jQuery will convert into a combobox.

Apex Controller method to create a List of SelectOptions

 
    public List getSelectBoxList() {
        List options = new List<selectoption>();

        options.add(new SelectOption('Select Value','Select Label'));
        options.add(new SelectOption('Select Value','Select Label'));
        
        return options;
    }

Initialize your combobox



Initialize your combobox by using a unique class name in the apex:selectList. The class name comboboxSelectBox is used in this case. Why can't you use the id parameter? Because Salesforce uses the id parameter to create a dynamic id that it uses for it's built in functionality. You won't have access to it unless you override the value using javascript but that would break existing functionality native to Salesforce.

Initialize your SelectBox into a jQuery Combobox

 
  j$(function() {
    j$( ".comboboxSelectBox" ).combobox();
    j$( "#toggle" ).click(function() {
      j$( ".comboboxSelectBox" ).toggle();
    });
  }); 

Match the default Salesforce Look and Feel



Here is some CSS to override the default jQuery style and make it fit in with the look-and-feel of Salesforce. Off-the-shelf jQuery UI elements will clash pretty heavility with Salesforce UI elements so I highly recommend you use this code and modify it further to reach a more unified user experience.

CSS to help the jQuery Combobox look more like the Salesforce default Look and Feel

 
ul.ui-autocomplete  {
 overflow: auto;
    max-height: 300px;
}    

.custom-combobox {
    position: relative;
    display: inline-block;
  }
  .custom-combobox-toggle {
    position: absolute;
    top: 0;
    bottom: 0;
    margin-left: -1px;
    padding: 0;
    /* support: IE7 */
    *height: 1.4em;
    *top: 0.1em;
  }
  .custom-combobox-input {
    margin: 0;
    padding: 0.2em;
  }
.ui-state-default, .ui-widget-content .ui-state-default, .ui-widget-header .ui-state-default {
    background: white;
    border: 1px solid gray;
}

.ui-widget {
    font-family: Arial,Helvetica,sans-serif;
    color: #000;
    font-size: 1.023em;
}    

input.ui-state-default, input.ui-widget-content input.ui-state-default, input.ui-widget-header input.ui-state-default {
 width: 177px;
}      
    
a.ui-state-default, a.ui-widget-content a.ui-state-default, a.ui-widget-header a.ui-state-default {
 width: 20px;
    border-left: 0px solid gray;
    border-right: 1px solid gray;
    border-top: 1px solid gray;
    border-bottom: 1px solid gray;
}

.ui-corner-all, .ui-corner-bottom, .ui-corner-right, .ui-corner-br {
 border-bottom-right-radius: 0px; 
}
.ui-corner-all, .ui-corner-bottom, .ui-corner-left, .ui-corner-bl {
 border-bottom-left-radius: 0px; 
}
.ui-corner-all, .ui-corner-top, .ui-corner-right, .ui-corner-tr {
 border-top-right-radius: 0px;
}
.ui-corner-all, .ui-corner-top, .ui-corner-left, .ui-corner-tl {
 border-top-left-radius: 0px;
}    
Software Development Blogs - BlogCatalog Blog Directory

Friday, June 13, 2014

Tips for Migrating from Eclipse to IntelliJ - Re-learning shortcuts and other Tips



Migrating from Eclipse to IntelliJ:  Re-learning shortcuts and other Tips


As a long-time Eclipse user(Spring Tools Suite and Groovy and Grails Tools Suite), the transition to using IntelliJ was jarring in many ways.  Keyboard shortcuts are different, the layout is different and the way you do things is different.

It is worth it to go through with the transition.  Auto-complete and searching is better.  Logs and consoles are better.  The tooling is better.  There are plenty of articles out there that highlight the changes.  Most importantly though is that it is does everything you need well and is very fast.


Here are some things that will help with your transition:



How to Change the JDK




Setup the JDK locations

Here you will want to setup the location of the Java SDKs you have installed.

Ctrl+Shift+Alt+S -> Platform Settings -> SDKs:  Change JDK


Change the JDK path in IntelliJ
Update the JDK in the IntelliJ IDE

Setup the Project SDK

Then you will need to set the Project SDK

Then go to Project Settings -> Project and change the Project SDK


Set Project SDK in Project Structure
Set Project Java SDK for IntelliJ


Keyboard Shortcuts




Here is a mapping of Eclipse vs IntelliJ keyboard shortcuts.

Here are a couple of the most used:



  • ctrl+n:  Find a file by class name
  • ctrl+shift+f:  Search the entire project within files for a string
  • ctrl+s:  Save all files
  • ctrl+shift+N:  Find Resource

Grails Specific Shortcuts
  • ctrl+alt+G:  Open Grails Command line(Run Grails Target)


Here is a more comprehensive list:

EclipseIntelliJ IDEADescription
F4ctrl+hshow the type hierarchy
ctrl+alt+gctrl+alt+F7find usages
ctrl+shift+uctrl+f7finds the usages in the same file
alt+shift+rshift+F6rename
ctrl+shift+rctrl+shift+Nfind file / open resource
ctrl+shift+x, jctrl+shift+F10run (java program)
ctrl+shift+octrl+alt+oorganize imports
ctrl+octrl+F12show current file structure / outline
ctrl+shift+mctrl+alt+Vcreate local variable refactoring
syso ctrl+spacesout ctrj+jSystem.out.println(“”)
alt + up/downctrl + shift + up/downmove lines
ctrl + dctrl + ydelete current line
???alt + hshow subversion history
ctrl + hctrl + shift + fsearch (find in path)
“semi” set in window-> preferencesctrl + shift + enterif I want to add the semi-colon at the end of a statement
ctrl + 1 or ctrl + shift + lctrl + alt + vintroduce local variable
alt + shift + salt + insertgenerate getters / setters
ctrl + shift + fctrl + alt + lformat code
ctrl + yctrl + shift + zredo
ctrl + shift + cctrl + /comment out lines (my own IDEA shortcut definition for comment/uncomment on german keyboard layout on laptop: ctrl + shift + y)
ctrl + alt + hctrl + alt + h (same!)show call hierarchy
none ?ctrl + alt + f7to jump to one of the callers of a method
ctrl + shift + ialt + f8evaluate expression (in debugger)
F3ctrl + bgo to declaration (e.g. go to method)








Software Development Blogs - BlogCatalog Blog Directory

Friday, June 6, 2014

Salesforce Dynamically Populated List of Checkboxes in Visualforce and Apex



Dynamically Populated List of Checkboxes in Visualforce and Apex



Below you will find details on how to create a dynamic checkbox group on a custom Salesforce page using Apex and Visualforce.

These examples will leverage Visualforce specific tags and Apex specific functionality to accomplish things that you would normally need an external library such as jQuery to acheive.



Dynamic Array of Checkboxes


Dynamically build an array of checkboxes and keep track of which boxes are checked.  Checkboxes will be populated from a SOQL query from a custom object in Salesforce.  Selected options will be tracked and persisted if you re-render the checkboxes.



Visualforce


Command button to refresh list of checkboxes

  <apex:commandButton action="{!refresh}" reRender="customCheckboxPanel" status="loadingDetails">  

This is just an example.  A more practical use of this would be a onchange or onclick event such as if you had checkbox groups on multiple tabs.


Output panel that is refreshed to display dynamic list of checkboxes

  
<apex:outputpanel id="customCheckboxPanel" layout="block">  
                       <apex:actionStatus id="loadingDetails"   
                           startText="Loading..."   
                           stopText=""/>    
                             <br/>  
                             <apex:selectCheckboxes value="{!choices}" layout="pageDirection">  
                               <apex:selectOptions value="{!list}"/><br/>  
                             </apex:selectCheckboxes>  
</apex:outputpanel>  



Apex


This code will go in your controller.

You will have an array of strings that will contain each id of each selected option.

You will also need a method that retrieves the options via a SOQL queries and loads them into selectionOption objects

Choice Array and Get Select Options Method

 
//String array to keep track of the ids of choices  
public String[] choices { get; set; }
  
//List of select options to populate select boxes  
public List<SelectOption> getList() {  
     List<SelectOption> options = new List<SelectOption>();  
       for (Your_Custom_Object__c ow : [  
         SELECT Name,id FROM Your_Custom_Object__c]) {   
         options.add(new SelectOption(ow.id, ow.Name));   
       }    
     return options;   
}   

The id is being set as the value and the Name is being set as the displayed label.  Replace Your_Custom_Object__c with the name of the custom object you want to query.

You should now have a set of checkboxes. Checked options will automatically be tracked in the choices String array.


Checkbox Array Example
Check boxes populated with a SOQL query
Dynamically populated checkboxes




Software Development Blogs - BlogCatalog Blog Directory

Wednesday, June 4, 2014

Viewing DEBUG statements in Salesforce APEX Files using the Browser Developer's Console




How to view System Debug Statements in the Salesforce Dev Console





Use system debug statements in your Apex code to log the info you need.

 system.debug('results ' + results);   


Open up the page and execute the behavior you are trying to monitor using system debug statements.

Choose the Logs tab at the bottom of the console and double-click the most recent log for the page you are monitoring.

i.e. apex/yourpage


Select Apex log file
Select the Logs tab and open your log file

Once the log is open you can either check the "DEBUG ONLY" checkbox or check the "Filter" checkbox and filter on the string "USER_DEBUG" or any custom string you are searching for specifically.  Both options are at the bottom of the console.



Filter for USER_DEBUG events
Set the Filter to only display items containing "USER_DEBUG"

Viewing logs in the browser in your Salesforce Instance


If you are having trouble opening the logs in the Developer Console you can open the logs in a regular browser window.

Go to your Salesforce instance and click "Setup" in the top right corner

Then on the left hand menu, at the bottom click on debug logs:

View logs in a browser on your Salesforce instance
View logs in your Salesforce Instance

Then select the appropiate log, click view or download and you can manually search for DEBUG statements using the find command(ctrl+f).


Software Development Blogs - BlogCatalog Blog Directory