WebForms For Marketers: Allow selection of existing forms

WFFM. The marmite of Sitecore modules. It’s possibly one of the most commonly used of Sitecore modules but we all love to hate this module. Despite its rough edges, we battle on. I have to admit that I had not used this module in some time; until using it with Sitecore 8 in its MVC guise the last time was over 2 years ago in webforms (ASP.Net, not Sitecore :p).

As improved as it is working with MVC, one thing that frustrated me was creating a bunch of forms only to find that there was a gazillion copies now littered across the site. Why? Because when you add an MVC Form rendering onto the page the only options presented to you is to either create a blank a form or to duplicate an existing one.

wffm-form-selector

I am assuming that reason for force copying of forms is to allow Goals to be set and each form to be tracked separately. The problem with having so many copies of a single form is that it makes it very difficult to maintain. You no longer have a single source, so something as simple as adding a new field means also having to add it to all the copies. This is my third Sitecore 8 solution using WFFM, and I got annoyed seeing so many copies, so here’s an overridden control to solve that.

Updated Form Selector

Make a copy of InsertFormWizard.xml from /sitecore/shell/Applications/Modules/Web Forms for Marketers and drop it into /sitecore/shell/Override folder

Update the file. Change the Codebeside tag to point to our implementation:

<WizardForm Application="Modules/Web Forms for Marketers/Insert Form Wizard" 
            CodeBeside="MyProject.Custom.WFFM.UI.InsertFormWizard, MyProject.Custom">

Add a new RadioButton to allow selection for existing forms:

<Border Margin="10px">
  <Radiobutton ID="ChooseExistingForm" Name="ChooseOperation" Value="existing" />
</Border>

We’ll also add a bit of JS to disable the input boxes, not strictly necessary but it makes it less confusing for the users:

<script type="text/javascript" runat="server">
  $j('input[name="ChooseOperation"]').change(function() {
    if (this.value == "existing") {
      $j("#EbFormName").attr("disabled", "disabled");
    } else {
      $j("#EbFormName").removeAttr("disabled");
    }
  });
</script>

Now let’s wire up the code behind. We want to check if the Existing Form option has been selected and if so vary the page shown as required, namely ignoring the Analytics page since we don’t want to let the user change it from this screen (i.e. use the form exactly as it is set up, analytics options can still be changed from the form item itself). The rest of the code is to either change the text or a single overridden method to set the selected form value and some helper functions. There’s less code than there seems…

using System;
using System.Text;
using Sitecore;
using Sitecore.Data.Items;
using Sitecore.Globalization;
using Sitecore.Web.UI.HtmlControls;
using Sitecore.Web.UI.Sheer;

namespace MyProject.Custom.WFFM.UI
{
    public class InsertFormWizard : Sitecore.Forms.Shell.UI.InsertFormWizard
    {
        protected Radiobutton ChooseExistingForm;

        protected override void Localize()
        {
            base.Localize();
            this.ChooseExistingForm.Header = "Select an existing form";
        }

        protected override bool ActivePageChanging(string page, ref string newpage)
        {
            if (newpage == "SelectPlaceholder" && page == "SelectForm" && this.ChooseExistingForm.Checked)
                newpage = string.IsNullOrEmpty(base.Placeholder) ? "SelectPlaceholder" : "ConfirmationPage";

            if (this.ChooseExistingForm.Checked && newpage == "AnalyticsPage")
                newpage = "ConfirmationPage";

            bool flag = base.ActivePageChanging(page, ref newpage);
            if (newpage == "ConfirmationPage" && this.ChooseExistingForm.Checked)
            {
                base.ChoicesLiteral.Text = RenderFormSelection();
            }
            return flag;
        }

        private string RenderFormSelection()
        {
            Item source = ExistingFormSelection();

            StringBuilder stringBuilder = new StringBuilder();
            stringBuilder.Append("<fieldset class='scfGroupSection' >");
            stringBuilder.Append("<legend>FORM</legend>");
            stringBuilder.Append("<p>Using existing form: " + source.Paths.FullPath + "</p>");
            return stringBuilder.ToString();
        }

        protected override void ActivePageChanged(string page, string oldPage)
        {
            base.ActivePageChanged(page, oldPage);
            if (page == "ConfirmationPage" && this.ChooseExistingForm.Checked)
            {
                this.NextButton.Header = "Confirm";
            }
        }

        protected override void OnNext(object sender, EventArgs formEventArgs)
        {
            if (this.NextButton.Header == "Confirm" && this.ChooseExistingForm.Checked)
            {
                this.SaveExistingFormSelection();
                SheerResponse.SetModified(false);
                this.Next();
                return;
            }
            base.OnNext(sender, formEventArgs);
        }

        private void SaveExistingFormSelection()
        {
            Item source = ExistingFormSelection();
            this.ServerProperties[this.newFormUri] = source.Uri.ToString();
            Registry.SetString("/Current_User/Dialogs//sitecore/shell/default.aspx?xmlcontrol=Forms.FormDesigner", "1250,500");
            SheerResponse.SetDialogValue(source.ID.ToString());
        }

        private Item ExistingFormSelection()
        {
            string queryString = Sitecore.Web.WebUtil.GetQueryString("la");
            Language result = Context.ContentLanguage;
            if (!string.IsNullOrEmpty(queryString))
                Language.TryParse(Sitecore.Web.WebUtil.GetQueryString("la"), out result);

            Item source = this.FormsRoot.Database.GetItem(this.multiTree.Selected, result);
            return source;
        }
    }
}

You will need to add reference to Sitecore.Kernel and Sitecore.WFFM to your project.

Not much to it the end. You can find the all the code in this Github Gist: https://gist.github.com/jammykam/92377635a06ac86d627a

You now have this lovely dialog:

wffm-updated-form-selector

This works for MVC solutions and tested with Sitecore 8 update-3, unfortunately I did not try for webforms solutions and am assuming that the old FormID droplink field still works so there is no need for this since the existing solution allows you to select pre-existing forms. I also did not use the Resource Manager/Translation methods since we have a single language site and I was being lazy 🙂

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s