MK Partners Apex Code

Required Field and Custom Error Messages in visualForce

Putting extra time into your user interface is the difference between a programmer and a hero. A good user interface has an intuitive layout that is consistent with existing standards, is simple to use, and never leaves a user wondering what they should be doing.

One easy way to improve a user interface is by providing required field indicators and adding custom error messages. An easy to understand error message will not only teach users the correct process but also reduce your number of end-user support cases.

In visualForce you can use the REQUIRED tag on inputs to ensure that your users fill out a field, but the resulting error message isn’t always friendly and it wreaks havoc with any dynamic rendering on the page. Instead, you can make the input look required and use some simple Apex logic to enforce it.

In the below code, we have a single input on the page and make it look required with some nicely styled outputPanels. The style is actually salesforce.com’s native style so you don’t need to worry about needing any css. When the user clicks Save, if the input is empty, they get a nice error message that explains exactly what they need to do to proceed.

<apex:page controller="sample_Controller">
	<apex:pageMessages />
	<apex:pageBlockSection>
		<apex:pageBlockButtons>
			<apex:commandButton value="Save" action="{!save}" />
		</apex:pageBlockButtons>
		<apex:pageBlockSectionItem>
			<apex:outputLabel value="Required Field" />
			<apex:outputPanel styleClass="requiredInput" layout="block" >
				<apex:outputPanel styleClass="requiredBlock" layout="block"/>
				<apex:inputText value="{requiredFieldName}" />
			</apex:outputPanel>
		</apex:pageBlockSectionItem>
	</apex:pageBlockSection>
</apex:page>

public class sample_Controller {
	public void save(){
		if ( requiredFieldName == null || requiredFieldName == '' ){
			ApexPages.addMessage(new ApexPages.Message(ApexPages.Severity.ERROR, 'Please enter a value in the Required Field box in order to save this record.'));
		}
	}
}

Webinar: VMForce is coming for Spring and Java developers

Salesforce.com is holding two tech talks on the upcoming VMForce functionality. The first webinar introduces VMWare’s Spring framework to existing force.com developers. The second webinar introduces force.com to existing java developers.

Whichever fits you best, you can register at developerforce.com.

Gmail: Rich Text Signatures now available

The Gmail team at Google just added the ability to use rich-text in your email signature! This is a long awaited feature and one that makes Gmail even more suited for business email.

Rich Text Signatures [The Official Gmail Blog]

Force.com Sites Best Practice: Truncate Field Values

Force.com allows you to create text fields that store up to 32,000 characters. This sounds like a lot, but time and time again, we find that our clients (or their customers) want to type huge amounts of data into a single field. When you’re using the native user interface, force.com gives you a nice and easy to understand error message. But, when you’re using Visualforce or force.com Sites, the messaging isn’t always as pretty.

There’s a very simple work around though. You can specify in Apex that field values that are too long should be truncated. Thus ensuring that the record is saved nicely, without requiring you to write a lot of logic and custom error messages. It’s not always ideal, but error pages are even less ideal.

Here’s how the code would look for setting truncation on an Account:

Database.DMLOptions  dml  =  new  Database.DMLOptions();
dml.allowFieldTruncation  =  true;
Account a = new Account();
a.setOptions(dmo);

New force.com Sites powered Contact Us page

MK Partners is proud to announce that we have a new Contact Us page on our website. Our former Contact Us page was a web-to-lead form that submitted new leads directly into our salesforce org. It was very good at what it did, but we really needed a more powerful page.

Our new Contact Us page is powered by force.com Sites and it does much more than just enter leads into salesforce. The new page dynamically changes the questions on the screen based on why you are contacting us. If you’re contacting us for product support it you have to fill out questions related to the issue. If you’re contacting us for sales you have to fill out questions related to your project. But wait, there’s more, not only do the questions on the screen change, but the resulting record in salesforce changes too. Support inquiries turn into cases and sales inquiries turn into leads!

We fell this upgrade is is long overdue for us, not only because we are such proponents of using force.com Sites but also because it improves our efficiency and helps us respond faster to support requests.

If you’re interested in having MK Partners create a custom force.com Sites powered page for your website, fill out our Contact Us form at http://www.mkpartners.com/contact

Spring cleaning old integrations

Jesper Joergensen posted some interesting info last week about a new endpoint for the API that is currently available. The new endpoint is https://login.salesforce.com and according to Jesper will reduce your authentication time slightly.

While you’re at it, you may want to update your SOQL queries to take advantage of some of the new Aggregate Functions.

Check out the full post at http://blog.sforce.com/sforce/2010/02/new-api-login-endpoint.html

Developer Friendly APIs

There’s a great post by Alex Lucas at CallingShotgun.net about what companies can do to make their API’s more developer friendly. Salesforce.com stands well against the list, take a look:

www.callingshotgun.net

Apex Maps Keys are case sensitive

I use Maps a lot when I write code, usually to help me reduce the number of times I have to do queries. Normally they work just fine and I don’t pay attention to the little details like the case of the text used in its keys. The other day though, I was getting some really weird results from my code. The code was being used to dedupe incoming records against existing ones. I started by compiling the unique IDs for the new records, then queried existing records with the same ids, and then created a map of the Unique Id to existing record. Pretty straightforward simple stuff, right.

Well, for some reason my code didn’t work for one record. Since it was one record I knew it had to be data related, but a quick glance at the new record and the existing one didn’t yield any differences. A more thorough glance though revealed one letter that was lowercase where it should’ve been uppercase. It didn’t seem like that could be the problem, after all, text == TEXT results in TRUE. Well, it turns out that map.containsKey() is case sensitive and there’s no attribute that can be set to change this.

The solution is pretty simple, before putting a key into the map you use either string.touppercase() or string.tolowercase() to standardize the keys. Then when you use map.containsKey(), you use the same method to standardize the string you’re looking for.
After figuring this out myself, I found a post about it over at The Silver Lining. Sure wish it were in the developer docs!

Saying goodbye to s-Controls

Hopefully, you already know that s-Controls are being phased out at the end of 2009. Most of us haven’t worked with s-Controls, since Apex was released. With Apex and VisualForce, there’s very little that can’t be done in salesforce.com that we used to do with s-Controls.

The few things that are hard to do can usually be accomplished by using a custom button/link to run some javascript and then some javascript first then pass it off to Apex/VisualForce. A good example of this is a custom button on a related list. With s-Controls we could pass which records had the checkbox checked in the related list. When VisualForce came out, we lost this ability and forced the user to navigate to an additional page with the same list and check the boxes there.

There is a javascript workaround though, it involves having the custom button on the related list run some code that looks like this:

{!REQUIRESCRIPT(&quot;/soap/ajax/17.0/connection.js&quot;)}
{!REQUIRESCRIPT(&quot;/soap/ajax/17.0/apex.js&quot;)}
var records = {!GETRECORDIDS($ObjectType.Lead)};
if ( records.length &gt; 0 )
{
var success = sforce.apex.execute(&quot;ApexClassName&quot; , &quot;ApexMethodName&quot;,
{
listIds:records
}
);
window.location.href=window.location.href;
}
else
{
alert('Please select one or more records');
}

Have you migrated your s-Controls yet? (Don’t worry, your existing ones aren’t going anywhere yet, you just wont be able to create new ones).

Batch Apex and Custom Settings Force.com Tech Talk

Taggart Matthiesen delivered an amazing tech talk last week on Batch Apex and Custom Settings functionality. Not only did he demonstrate some basic Batch Apex functionality but also gave some promising insight into the future of Apex (safeharbor applies of course).

Some of the big news items included:

  • Increasing the max size of collections to whatever the heap will support
  • Being able to schedule Batch Apex (currently in pilot)
  • Being able to do a mixed DML operation with custom settings

Great job Taggart, thanks for the extremely informative and educational session.

The webinar was recorded, so you can check it out here if you missed it:
http://wiki.developerforce.com/index.php/Tech_Talk:_Whats_New_in_Apex_Code

Let us know in the comments what you plan on using Batch Apex for!