Thursday, January 12, 2017

Sitecore WFFM 2.5 customizing field output HTML with web forms

Working on a Sitecore 7.5 instance, along with web forms for marketers 2.5, I came across a requirement to implement Bootstrap styling across the form fields. Because the site wasn't running on MVC it wasn't as simple as editing the views for each field type (found in "/Website/Views/Form/EditorTemplates").

Instead I needed to create my own version of each field type I was editing and change how the field was output. For example with the single line of text field, it is defined in Sitecore under: /sitecore/system/Modules/Web Forms for Marketers/Settings/Field Types/Simple Types. As you can see it then references a DLL and Class:


This class inside the DLL looks like:
using Sitecore.Form.Core.Attributes;
using Sitecore.Form.Core.Visual;
using System;
using System.ComponentModel;
using System.ComponentModel.Design;
using System.Web.UI;
using System.Web.UI.WebControls;

namespace Sitecore.Form.Web.UI.Controls
{
  [Designer("System.Windows.Forms.Design.ParentControlDesigner, System.Design", typeof (IDesigner))]
  public class SingleLineText : RegexInputControl
  {
    private static readonly string baseCssClassName = "scfSingleLineTextBorder";

    [VisualCategory("Validation")]
    [VisualProperty("Maximum Length:", 2000)]
    [DefaultValue(256)]
    public int MaxLength
    {
      get
      {
        return this.textbox.MaxLength;
      }
      set
      {
        this.textbox.MaxLength = value;
      }
    }

    [VisualProperty("Minimum Length:", 1000)]
    [DefaultValue(0)]
    [VisualCategory("Validation")]
    public int MinLength { get; set; }

    [DefaultValue("scfSingleLineTextBorder")]
    [VisualProperty("CSS Class:", 600)]
    [VisualFieldType(typeof (CssClassField))]
    public new string CssClass
    {
      get
      {
        return base.CssClass;
      }
      set
      {
        base.CssClass = value;
      }
    }

    public SingleLineText(HtmlTextWriterTag tag)
      : base(tag)
    {
      this.MaxLength = 256;
      this.MinLength = 0;
      this.CssClass = SingleLineText.baseCssClassName;
    }

    public SingleLineText()
      : this(HtmlTextWriterTag.Div)
    {
    }

    protected override void OnInit(EventArgs e)
    {
      this.textbox.CssClass = "scfSingleLineTextBox";
      this.help.CssClass = "scfSingleLineTextUsefulInfo";
      this.generalPanel.CssClass = "scfSingleLineGeneralPanel";
      this.title.CssClass = "scfSingleLineTextLabel";
      this.textbox.TextMode = TextBoxMode.SingleLine;
      this.Controls.AddAt(0, (Control) this.generalPanel);
      this.Controls.AddAt(0, (Control) this.title);
      this.generalPanel.Controls.AddAt(0, (Control) this.help);
      this.generalPanel.Controls.AddAt(0, (Control) this.textbox);
    }
  }
}
The OnInit method is then where the field it actually output, and this is where changes can be made to affect the output of the field (CSS classes and div nesting). The following example is a replacement class which outputs single line text like a bootstrap field.
using Sitecore.Form.Core.Attributes;
using Sitecore.Form.Core.Visual;
using Sitecore.Form.Web.UI.Controls;
using System;
using System.ComponentModel;
using System.ComponentModel.Design;
using System.Web.UI;
using System.Web.UI.WebControls;

namespace MyProject.WFFM.Controls
{
    [Designer("System.Windows.Forms.Design.ParentControlDesigner, System.Design", typeof(IDesigner))]
    public class SingleLineText : RegexInputControl
    {
        private static readonly string baseCssClassName = "form-group";

        [VisualCategory("Validation")]
        [VisualProperty("Maximum Length:", 2000)]
        [DefaultValue(256)]
        public int MaxLength
        {
            get
            {
                return this.textbox.MaxLength;
            }
            set
            {
                this.textbox.MaxLength = value;
            }
        }

        [VisualProperty("Minimum Length:", 1000)]
        [DefaultValue(0)]
        [VisualCategory("Validation")]
        public int MinLength { get; set; }

        [DefaultValue("form-group")]
        [VisualProperty("CSS Class:", 600)]
        [VisualFieldType(typeof(CssClassField))]
        public new string CssClass
        {
            get
            {
                return base.CssClass;
            }
            set
            {
                base.CssClass = value;
            }
        }

        public SingleLineText(HtmlTextWriterTag tag)
          : base(tag)
        {
            this.MaxLength = 256;
            this.MinLength = 0;
            this.CssClass = SingleLineText.baseCssClassName;
        }

        public SingleLineText()
          : this(HtmlTextWriterTag.Div)
        {
        }

        protected Panel titlePanel;

        protected override void OnInit(EventArgs e)
        {
            this.textbox.CssClass = "scfSingleLineTextBox";
            this.help.CssClass = "scfSingleLineTextUsefulInfo";
            this.generalPanel.CssClass = "field-responsive";
            this.title.CssClass = "control-label";
            this.textbox.TextMode = TextBoxMode.SingleLine;
            this.Controls.AddAt(0, (Control)this.generalPanel);
            this.titlePanel = new Panel();
            this.titlePanel.CssClass = "label-responsive";
            this.titlePanel.Controls.AddAt(0, (Control)this.title);
            this.Controls.AddAt(0, (Control)this.titlePanel);
            this.generalPanel.Controls.AddAt(0, (Control)this.help);
            this.generalPanel.Controls.AddAt(0, (Control)this.textbox);
        }
    }
}
This might not work for all cases, but serves as a base for how to edit the output of fields inside WFFM (in a web forms site).

No comments:

Post a Comment