Introduction
In my opinion the WebForms for Marketers module is one of the nicest Sitecore modules out there. It’s beautifully designed and serves its purpose well. It comes bundled with a number of actions (which are executed after you submit), but one action is missing - an action which redirects the user to another page after the form has been submitted.
I was interested in how it works to set up a new action and thus I set out to create this action myself. Apart from just letting you download the package (here) I will explain what I did, step by step, because over and over again I find that certain XAML features are not documented and maybe this post will help some of you.
Let’s have a look at what we need to create this action:
- An item for the action itself and a corresponding class
- An editor window that allows the user where to redirect to
Obviously we also need to have the Web Forms for Marketers module installed and we need a valid license for it.
Creating the action and class
To create a new action, we need to create a .NET class in our solution, plus an item in the content tree under /sitecore/system/Modules/Web Forms for Marketers/Settings/Actions. The item is easily created and doesn’t need a lot of configuration for now, apart from the class and assembly names (these depend on your solutions setup).
Our class could look like this:
public class RedirectAction : ISubmit
{
public void Submit(ID formid, Sitecore.Form.Core.Client.Data.Submit.AdaptedResultList fields)
{
Sitecore.Data.Database curDB = Sitecore.Context.Database;
Sitecore.Data.Items.Item redItem = curDB.GetItem("sitecore/content/home");
Sitecore.Context.Item = redItem;
}
}
The class is implementing the ISubmit interface and overrides the Submit method. All this class does at the moment is redirect the user to /sitecore/content/home. Simple, but for now this is exactly what we want.
That’s it. Once the solution is compiled, the action can now be added to any form and after the form has been filled out, the user will be redirected to /sitecore/content/home.
Extending the solution with parameters
Currently the redirection path is hardcoded and we want to give our users the ability to choose a path for themselves (and a different one for each form).
To do this we need to implement an XML control which serves as the property window for our action. The property window is called when the user presses "Edit" in the action editor.
To enable the "Edit" button, we first need to tell Sitecore what to do when the button is pressed. We do this by filling out the "Editor" field on the redirect action item itself, pointing the editor to control:pickItem (see below). This will automatically call and display the Sitecore XML Control pickItem (it is important that the XML node of the control is called pickItem, e.g. <control …><pickItem>…</pickItem></control>, but more about this in a second).
Now we have to create the pickItem control itself. I placed the pickItem.xml file into C:\inetpub\wwwroot\<yoursite>\WebSite\sitecore\shell\Applications\Modules\Web Forms for Marketers\Dialogs\Action Editor and the codebeside class myItemPickDialog.cs into C:\inetpub\wwwroot\<yoursite>\WebSite\starterkit. The locations don’t really matter though.
pickItem.xml:
<?xml version="1.0" encoding="utf-8" ?>
<control xmlns:def="Definition" xmlns="http://schemas.sitecore.net/Visual-Studio-Intellisense">
<pickItem>
<Stylesheet runat="server" Src="Content Manager.css" DeviceDependant="true"/>
<FormDialog Icon="Applications/32×32/exchange.png" Header="Pick Item" Text="Select the item that you want to redirect to." OKButton="OK">
<DataContext ID="TreePickerDataContext" />
<CodeBeside Type="Sitecore.Starterkit.starterkit.MyItemPickDialog, Sitecore.Starterkit"/>
<TreePicker ID="treepicker1" />
</FormDialog>
</pickItem>
</control>
This is our pickItem control. As we can see, it’s a standard XML Control Form Dialog with just one extra control - TreePicker. A TreePicker control is a dropdown which displays a tree once the arrow in the right is clicked. In addition we need to add a DataContext control and a reference to our codebeside file (full class name, assembly).
myItemPickDialog.cs:
public class MyItemPickDialog : DialogForm
{
protected TreePicker treepicker1;
protected DataContext TreePickerDataContext;
protected override void OnLoad(EventArgs args)
{
// If this is not a postback…
if (!Context.ClientPage.IsEvent)
{
// initialise DataContext
TreePickerDataContext.DataViewName = "Master";
// set root node for DataContext - only content items in this case
Database mdb = Sitecore.Context.ContentDatabase;
TreePickerDataContext.Root = mdb.GetItem("/sitecore/content").ID.ToString();
treepicker1.DataContext = TreePickerDataContext.ID;
}
// without calling this, the OK and Cancel buttons will NOT work
base.OnLoad(args);
}
protected override void OnOK(object sender, EventArgs args)
{
// add the current value of the treepicker to the parameters collection and close dialog
NameValueCollection nvParams = new NameValueCollection();
nvParams.Add("redirectItem", treepicker1.Value);
string result = ParametersUtil.NameValueCollectionToXml(nvParams);
SheerResponse.SetDialogValue(result);
base.OnOK(sender, args);
}
protected override void OnCancel(object sender, EventArgs args)
{
base.OnCancel(sender, args);
}
}
This class initialises the FormDialog by first registering all the controls and then (in the OnLoad method) sets the DataContext for the TreePicker control. At the end it calls the OnLoad method of its parent class, initialising the whole form. This is necessary, otherwise the Ok and Cancel buttons will not work (yes, I found out the hard way
).
The only really interesting method here is OnOk. This method is called, when the OK button on the form is clicked and stores the TreePicker selection (the item to which we want to redirect) into a NameValueCollection with they name "redirectItem", which is later accessible by the form action itself.
The result is the beautiful form shown above, all rendered using Sitecore’s Sheer UI.
Now that we have the information on where to redirect to, we need to rewrite our RedirectAction class to actually not redirect to /sitecore/content/home anymore, but to whatever item the user has picked.
public class RedirectAction : ISubmit
{
// Sitecore will automatically initialise this string for us
public string redirectItem { get; set; }
public void Submit(ID formid, Sitecore.Form.Core.Client.Data.Submit.AdaptedResultList fields)
{
Sitecore.Data.Database curDB = Sitecore.Context.Database;
Sitecore.Data.ID redirectItemID = Sitecore.Data.ID.Parse(redirectItem);
Sitecore.Data.Items.Item redItem = curDB.GetItem(redirectItemID);
Sitecore.Context.Item = redItem;
}
}
This is very basic - if you know that Sitecore automatically initialises the redirectItem string. We specified the name earlier in the myItemPickDialog’s OnOK method, remember? So once you know this, it’s a piece of cake.
Conclusion
The conclusion is, as always with Sitecore - everything is possible. You can obviously write any kind of form action you like, from a redirect action over an SMS action to a workflow trigger action. As long as you can do it in .NET, you can do it in Sitecore.
I want to thank Igor Zhukovsky, who initially developed the Web Forms module and was very helpful during my little coding exercise. I also want to thank Yan Sklyarenko for facilitating the contact with Igor.
Links of Interest
Sitecore Developer Network - My First Sheer/UI App
Sitecore Developer Network - Publishing Queue Viewer (great advanced Sheer UI/XAML tutorial)

http://byfiles.storage.live.com/y1pcDEaDnCYfdx6ULvSVQM_Oxn8ABZFn-mOnW9qP7KJp5acMPH61E_9LP1k3Uk9EEra