All posts by zylean

Visualforce: Button Action With Javascript Not Compatible in Lightning

Recently, we were working on a project to convert the existing visualforce page to support the Lightning experience. An issue that I encountered was the command button with javascript action was no longer working in the Lightning experience mode. This was due to the change mentioned in this post. Below is an example:

<apex:form>
    ...
    <apex:actionFunction action="{!doPassParam}" name="passparam" rerender="mypanel" status="status">
        <apex:param name="selectedRecordId" value="" assignTo="{!selectedRecordId}"/>
    </apex:actionFunction>
    ...
    ...
    ...
    <apex:commandButton value="Submit" action="javascript:passparam('{!recordId}')" rerender="mypanel" style="margin-left: 5px" styleClass="slds-button slds-button--neutral slds-not-selected"/>
</apex:form>

The code above shows that we would like to pass a parameter to the controller via actionFunction when the user clicks the button. This will allow it to work in classic mode. However, it will throw an error saying “The page is not supported in Lightning experience” when we try to repeat in the Lightning experience mode.

To get around this issue, use javascript to set the value to a hidden input field. The hidden input field will act as a place holder to submit the value to the controller.

<apex:form>
    <script type="text/javascript">
        function setField(fieldId, fieldValue){
            document.getElementById(fieldId).value = fieldValue;
        }
    </script>
    ...
    ...
    <apex:commandButton value="Next Level" action="{!doPassParam}" onclick="setField('{!$Component.hiddenvaluefield}', '{!recordId}')" rerender="mypanel" style="margin-left: 5px" styleClass="slds-button slds-button--neutral slds-not-selected" status="reloadStatus"/>
    <apex:inputHidden value="{!selectedRecordId}" id="hiddenvaluefield" />
</apex:form>

Note that now the command button will invoke the onclick function first before invoking the doMyAction action.

WDCi Christmas Charity 2016

On 16th and 17th December, our team in Kuala Lumpur has organised a charity event. We have visited an old folks home and a few orphanages. The purpose of this event is to make them feel warmth and love in this Christmas season. We have taken some footages of us preparing for the charity and spending great time with everyone from the homes.

Enjoy and Merry Christmas šŸ˜€

The New RIO Inventory 3.2

Hello folks, thanks for your support with RIO Inventory all these years. We are pleased to present to you our latest release, version 3.2. You asked and we delivered, this release now has the following important features:

  • Inventory batching
  • Serialised inventory
  • Picking slips
  • Ability to transfer inventory between warehouses

These features allow you to manage your inventory better in Salesforce, especially when it comes to multiple warehouses inventory management. Feel free to take a look at thisĀ pageĀ for more details on how this can help with your daily inventory management.

If you are new, don’t worry. You can always installĀ the appĀ into your sandbox or developer instance via AppExchange and feel theĀ zen.

For more other goodies in 3.2, please visit ourĀ release notes.Ā  Want new features?Ā  Please let us know, you can contact us at support@wdcigroup.net.

Salesforce: Check Null/Empty Value of A Field

In Salesforce, it is very common that we build formula field, validation rule or workflow rules to act on the data of a field and sometimes we would like to validate on an empty value. In Salesforce formula editor, there are two functions: ISBLANK() and ISNULL(). The question here is, which is the correct one that we should use?

ISNULL()

This is an old function that works with most of the field types except Text, Text Area and Long Text. (reference)

ISBLANK()

This is a new function that Salesforce introduce to support the empty field validation on Text fields. It also works with other field types. According to Salesforce documentation, it is recommended to use this function instead. (reference)

Please note that if you are referencing a formula field with the option “Treat blank fields as zeroes”, the formula field will give value zero and won’t be considered as null.

Above is how you can validate an empty field in formula editor. How can we achieve the same in Apex?

Text Fields

There are a few options to validate empty text fields in Apex:

Use String.isBlank() method. This will return true if the text field is empty.
Compare the text field to an empty string, e.g, Account.Name == ”. You shouldn’t use NULL as text field in Salesforce is never considered NULL. Note that String variable can still be considered NULL.

Checkbox Fields

This can be compared by using TRUE or FALSE. This is because an unchecked checkbox field is considered as FALSE instead of NULL.

Other Fields

You should compare the field value to a NULL.

WDCi Is Hiring in Caloundra

Who are we?

  • We are an IT consulting firm that specialise in the Salesforce.com platform.
  • We do Architecture, Implementation, Product Development and Support.
  • In addition to Salesforce we deliver Data Integration and Data Migration services using Dell’s Boomi platform.
  • We have offices in Sydney, Caloundra and Kuala Lumpur. We are hiring in Caloundra.

Who are we hiring?

  • Support Engineer (s) – 1 x graduate level, 1 x with some experience.
  • A graduate Developer – ideal for a new IT graduate looking for a development role.

How do I apply?

Questions?

  • Send us an Email or visit our office upstairs in the Suncity Centre at 74 Bulcock St.

Salesforce: Visualforce CommandButton to Bypass Validation/Required Fields

In Visualforce apex:CommandButton component, there is an attribute called “immediate” that allows us to invoke the controller action bypassing the validation rules associated with the fields (especially those that mark with required=”true”) in a visualforce page. I have been using this attribute alongside with the cancel button which does not required any input from users. Until recently, I noticed that the attribute no longer working as expected in one of my visualforce page development. For example:

<apex:page standardController="Account" extensions="AccountExt" standardStylesheets="true" applyBodyTag="false" docType="html-5.0" title="My Wizard">
	<apex:form id="theform" >
		<apex:pageBlockButtons >
			<apex:commandButton value="Cancel" action="{!cancel}" immediate="true"/>
			<apex:commandButton value="Search" action="{!doSearch}" />
		</apex:pageBlockButtons >
		
		<apex:pageBlockSection title="Test">
			<apex:inputfield value="{!account.Type__c}" required="true"/>
		</apex:pageBlockSection>
	</apex:form>
</apex:page>

After some research, I realised this is actually related to the behavior in HTML 5 (doctType=”html-5.0″) where it will automatically validate all the required fields that I have in a form. So, how can we overcome this?

Option 1 (Form level)

You can set an HTML 5 attribute called html-novalidate=”novalidate” at the form level. However, this will disable the validation for all buttons. You should only use this if you have your own validation logic implementation in the controller/extension class.

<apex:form id="theform" html-novalidate="novalidate" >

Option 2 (Button level)

You can have the similar attribute next to the command button to disable the validation on the button specifically.

<apex:commandButton value="Cancel" action="{!cancel}" immediate="true" html-formnovalidate="formnovalidate" />

This is a better option to go for as we do not need to worry about implementing the additional logic to validate the user input.

Salesforce Apex: Namespace and Field Name in AggregateResult

In Salesforce SOQL, we can use the aggregate function to summarize data in query. When an aggregate function is used, Salesforce will return the result as AggregateResult object and we can retrieve the value by calling AggregateResult.get(‘field name’). For example:

for(AggregateResult ar : [select count(Id), Business_Type__c from Account group by Business_Type__c]){
	system.debug(ar.get('expr0'));		//get the value of count(id)
	system.debug(ar.get('Business_Type__c'));	//get the grouped by field value
}

However, things get a little bit tricky when you have a namespace in the Salesforce instance and you have custom field in the SOQL. The sample query will still work, but you will get an error saying “Invalid aggregate result field” when you are trying to retrive the value of custom field.

To overcome this, you can choose to:

Option 1

Prepend the custom field with a namespace, for instance,

system.debug(ar.get('namespace__Business_Type__c'));	//get the grouped by field value

Option 2

Use alias in the SOQL to represent a custom field in query result.

for(AggregateResult ar : [select count(Id), Business_Type__c businesstype from Account group by Business_Type__c]){
	...
	system.debug(ar.get('businesstype'));	//get the grouped by field value
}

Personally, I would prefer to use Option 2 as I don’t have to hard code the namespace in all the SOQL.

Boomi: SAP Integration Tips

This guide is not to help you to build a brilliant integration, but it gives you an important head start if you are integrating to SAP by using the Boomi SAP Connector.

Installation

  1. Before the installation, please make sure that you have installed the Java JDK (not JRE) in the server although Boomi Atom installer will download the Java JRE into the Atom installation directory (e.g, C:/Boomi Atomsphere/Atom – WDCi Atom/jre) if you do not have one in the server. Unfortunately, the Java JRE is not sufficient to run the SAP connector.
  2. You need to create a JAVA_HOME environment variable to point to the Java JDK directory and also include the JAVA_HOME/bin into the global path environment variable.
  3. After the installation, you will need to download the additional SAP library from the official site (service.sap.com/connectors > SAP Java Connector > Tools & Services) and extract the content into the <Boomi atom installation folder>/userlib/sapjco folder (e.g, C:/Boomi Atomsphere/Atom – WDCi Atom/userlib/sapjco).
  4. Once the above is done, please restart the Atom service in order for the changes to take effect.

Notes: If you would like to use SAP IDoc Listener (for real time integration), Boomi SAP connector requires a database (for tracking purpose) and you will need to download the required JDBC driver and place in the userlib/ folder.

Operation Profile

After importing the operation, please make sure that the date data type field has the correct date format in both Request and Response profile. The format used by the connector is:

  • Date = yyyy-MM-dd
  • Time = HH:mm:ss

Failing to configure the date in the Request profile would cause the connector to always returns all data from SAP.

Get Operation

Mostly, you will query the data by using last updated date time. The date/time format for the query operation is:

  • Date = yyyy-MM-dd (this is different from the format being used in SAP BAPI Tester, dd.MM.yyyy)
  • Time = HH:mm:ss

Send Operation

If you are sending information to SAP via a BAPI operation, it is best to double check with the SAP developer to see if they require Boomi SAP Connector to send “Commit Transaction” as part of the BAPI call. If yes, please make sure that the “Commit Transaction” option is checked in the SAP operation.

Salesforce Visualforce Page View State

Have you ever encountered the “Maximum view state size limit” error on the Visualforce page that you developed even though you only capture very little information (e.g, like 3 input fields)?

Maximum view state size limit (135KB) exceeded. Actual view state size for this page was xxx.xxKB

The way that the view state works is that it is not only holdingĀ the value of the field that you capture on the page, but it also holds the value of any accessible objects/variables that you have declared in the controller/extension. For example, if you have an object list (e.g, List<Account>) and the list is holding a lot of records, you might encounter the view state size limit error even though you are not displaying result in the page.

Salesforce has a good explanation on Visualforce View State that gives you a good start if you are troubleshooting the issue. As a good developer, you should also follow the best practice guideĀ to develop a performance optimized Visualforce page.