Quickstart: Creating Custom Web-To-Case Forms Using Visualforce and Sites

Available in: Salesforce Classic

This is part of Developing with the Service Cloud.

Use Case

The Web-To-Case feature provides an easy way for Service & Support customers to create a form on their web site that collects some field values and automatically creates a Case within salesforce.com. However, sometimes customers have more complex requirements for what their web form should look like and how the case creation process should happen. Sometimes additional information is needed that needs to be cross-referenced to related records with salesforce.com. Other times developers just want more fine-grained control over to web form to case process. This is a perfect use case for Visualforce and Force.com Sites.

Background

Visualforce is a web framework for delivering user interfaces on top of the Force.com platform. It allows developers to deliver any kind of user interface including but not limited to HTML, AJAX and/or Flash. A Visualforce page contains static content but also dynamic content driven by the associated logic and data. These pages are optionally associated with Apex classes that allow you to provide the logic to read and write data to and from the page. Standard uses of Visualforce pages are for collecting data, displaying data, or creating interactive workflows and applications.

Visualforce alone allows these custom dynamic web pages to be delivered to your employees as part of the salesforce.com application, but with Force.com Sites, these pages can now be delivered onto the public internet for all web visitors to interact with. With Force.com Sites you create a site within your salesforce.com organization and nominate certain Visualforce pages to be delivered publicly. All the same Visualforce functionality is available but now these pages can be delivered to anybody on the web.

When we're building our own web form to collect case records, we're actually not using Web-To-Case at all, we're hand-rolling our own Web-To-Case. Here we're going to be employing the use of Visualforce to create the form and Force.com Sites to expose it to the internet. To start, we'll need to create a Visualforce page that contains a form. We'll use both standard HTML tag as well as some special Visualforce tags for the form and the input elements. We'll also attach an Apex controller class to the page which will implement the logic to actually create the case record and deal with any errors in that process. Finally, we'll have enabled that page within Force.com Sites to make it available to anyone on the web.

Sample Code: Simple Case Web Form

In this web form, we add an additional feature that the Web-To-Case doesn't do automatically, cross-referencing the Case to an account based on account number. In the form below, we ask the user for their account number in addition to the other regular fields. When the Submit Case button is clicked, the submitCase method on the associated controller class will be called. Within that logic, the account ID is looked up based on the account number and the resulting value is assigned to the AccountId field of the case object, thereby attaching the case to that account.

Obviously this web form could be modified to include any number of additional lookups, fields, or scenarios. This sample is intended to provide a starting point. To learn more about building web forms with Visualforce and sites, consult the Further Reading section at the bottom of this page.

Visualforce page code:

<apex:page controller="SubmitCaseController">

	<h1>Submit New Case</h1>
	
	<apex:form >
		<apex:pageMessages />
		<table>
			<tr>
				<th>Your Name:</th>
				<td><apex:inputText value="{!c.SuppliedName}"/></td>
			</tr>
			<tr>
				<th>Your Email:</th>
				<td><apex:inputText value="{!c.SuppliedEmail}"/></td>
			</tr>
			<tr>
				<th>Your Account Number:</th>
				<td><apex:inputText required="true" value="{!acctNum}"/></td>
			</tr>
			<tr>
				<th>Title:</th>
				<td><apex:inputText required="true" value="{!c.Subject}"/></td>
			</tr>
			<tr>
				<th>Your Problem:</th>
				<td><apex:inputTextArea required="true" rows="5" value="{!c.Description}"/></td>
			</tr>
			<tr>
				<td><apex:commandButton value="Submit Case" action="{!submitCase}"/></td>
			</tr>
		</table>
	</apex:form>

</apex:page>

Controller class code:

public class SubmitCaseController {
	
	public Case c { get; set; }
	
	public String acctNum { get; set; }
	
	public SubmitCaseController() {
		c = new Case();
	}
	
	public PageReference submitCase() {
		List<Account> accts = [SELECT Id FROM Account WHERE AccountNumber = :acctNum];
		if (accts.size() != 1) {
			ApexPages.Message msg = new ApexPages.Message(ApexPages.Severity.FATAL, 'Invalid account number');
			ApexPages.addMessage(msg);
			return null;
		} else {
			try {
				c.AccountId = accts.get(0).Id;
				
				// now look for an associated contact with the same email
				Contact cnt = [SELECT Id FROM Contact WHERE AccountId = :c.AccountId AND Email = :c.SuppliedEmail LIMIT 1];
				if (cnt != null) 
					c.ContactId = cnt.Id;
					
				// Specify DML options to ensure the assignment rules are executed
				Database.DMLOptions dmlOpts = new Database.DMLOptions();
				dmlOpts.assignmentRuleHeader.useDefaultRule = true;
				c.setOptions(dmlOpts);

				// Insert the case
				INSERT c;
				return new PageReference('/thanks');
			} catch (Exception e) {
				ApexPages.addMessages(e);
				return null;
			}
		}
	}
}

Further Reading