X
Closing this message and/or accessing our website tells us you are happy to receive all cookies on the ClearPeople website.
However, if you would like to, you can change your cookies settings at any time.
This article describes a Sitecore customisation.

This article describes a Sitecore customisation with the following sections:

  1. Motivation: Describes the reasons to implement the customisation.
  2. Usage: Describes how to use the customisation.
  3. Implementation: Describes the main details of the implementation and provides the relevant source code.
  4. Technical Details: Records the Sitecore version on which the customisation was implemented along with the version of any related module.

Motivation

A WFFM form is required to display data which needs to be provided automatically by the website without letting the user update it. This information needs to be available to the SendMail save action and stored in the form’s analytics as a form field. The OOTB functionality of Sitecore’s WFFM does not support fields that are read only to the user and displayed as a label, as shown next:

WFFM

Please notice that the styles shown above belong to the web where this solution has been applied. Other site (with OOTB styling) may look different.


Usage

After deploying the “ReadOnly TextBox” customisation a new filed type is available to all WFFM forms. Its name is “ReadOnly TextBox”.


WFFM


Any value set on this field will be displayed on the form as a read-only field, it will be stored on the form’s analytics (if enabled) and will be available to any save action such as “Send Email”. The field’s value can be set in three diverse ways. The most standardised way is by using the field’s rules. Any rule can be used to determine the field’s value. Alternatively, the field supports values passed directly in the URL query string and also on a session variable. To do so the field’s attribute named “Parameter” needs to be filled with the name of a parameter to be found either on the URL query string or on the Session. If the parameter is found its value will be automatically stored on the field.


WFFM


Implementation

Implementing a new WFFM field data type requires a class to support the required logic and a Sitecore item definition that tells WFFM about the existence of the new type and how to find its associated class (implementation). In this case, the class will be called “ReadOnlyTextBox” and will derive from “Sitecore.Form.Web.UI.Controls.SingleLineText”.



public class ReadOnlyTextBox : SingleLineText


There are two key elements on the new field type. The first one is the label that will display the fields value without letting the user edit it. It will be implemented as a “System.Web.UI.WebControls.Label” and named “displayedValue”.



protected System.Web.UI.WebControls.Label displayedValue = new System.Web.UI.WebControls.Label();


The second key element is the property “Text” which needs to be overwritten in order to update our new “displayedValue”.



        [Localize, VisualProperty("Default Value:", 100), DefaultValue("")]
        public override string Text
        {
            get
            {
                return base.Text;
            }

            set
            {
                displayedValue.Text = HttpUtility.HtmlEncode(value);
                base.Text = value;
            }
        }


The attributes on the property definition are necessary to support “Rules” as a way to set the field’s value. The two additional ways to provide the field’s value are supported by the following “ParameterName” property:



        [VisualCategory("Appearance")]
        [VisualFieldType(typeof(EditField)), Localize]
        [VisualProperty("Parameter:", 100)]
        public string ParameterName { get; set; }


The “ParameterName” property will receive the value provided by the form’s designer on the field’s attribute exposed on the form’s designer UI as “Parameter”. This value, if provided, will be used to search on the URL query string or on the session variables for the value to be displayed on the field. This logic is implemented on the method “DoRender”:



protected override void DoRender(HtmlTextWriter writer)
        {
            this.textbox.Attributes["type"] = "hidden";
            if (!this.Page.IsPostBack && !string.IsNullOrWhiteSpace(this.ParameterName))
            {
                var queryStringValue = this.Page.Request.QueryString[this.ParameterName];
                if (!String.IsNullOrEmpty(queryStringValue))
                {
                    this.Text = this.Page.Request.QueryString[this.ParameterName].ToString();
                }
                else
                {
                    var sessionValue = (string)HttpContext.Current.Session[this.ParameterName];
                    if (!String.IsNullOrEmpty(sessionValue))
                    {
                        this.Text = sessionValue;
                    }
                }

            }

            base.DoRender(writer);
        }


The rest of the class’ members are just scaffolding. The hole class code is next: File: Web\WFFM\FieldTypes\Custom\ReadOnlyTextBox.cs



using System;
using System.Web;
using System.Web.UI;
using Sitecore.Form.Core.Attributes;
using Sitecore.Form.Core.Visual;
using Sitecore.Form.Web.UI.Controls;
using System.ComponentModel;
using System.Web.UI.WebControls;

namespace Website.WFFM.FieldTypes.Custom
{
    public class ReadOnlyTextBox : SingleLineText
    {

        protected System.Web.UI.WebControls.Label displayedValue = new System.Web.UI.WebControls.Label();


        [Localize, VisualProperty("Default Value:", 100), DefaultValue("")]
        public override string Text
        {
            get
            {
                return base.Text;
            }

            set
            {
                displayedValue.Text = HttpUtility.HtmlEncode(value);
                base.Text = value;
            }
        }

        [VisualCategory("Appearance")]
        [VisualFieldType(typeof(EditField)), Localize]
        [VisualProperty("Parameter:", 100)]
        public string ParameterName { get; set; }

        protected override void DoRender(HtmlTextWriter writer)
        {
            this.textbox.Attributes["type"] = "hidden";
            if (!this.Page.IsPostBack && !string.IsNullOrWhiteSpace(this.ParameterName))
            {
                var queryStringValue = this.Page.Request.QueryString[this.ParameterName];
                if (!String.IsNullOrEmpty(queryStringValue))
               {
                    this.Text = this.Page.Request.QueryString[this.ParameterName].ToString();
                }
                else
                {
                    var sessionValue = (string)HttpContext.Current.Session[this.ParameterName];
                    if (!String.IsNullOrEmpty(sessionValue))
                    {
                        this.Text = sessionValue;
                    }
                }

            }

            base.DoRender(writer);
        }

        protected override void OnInit(EventArgs e)
        {

            this.textbox.CssClass = "scfSingleLineTextBox";
            this.help.CssClass = "scfSingleLineTextUsefulInfo";
            this.generalPanel.CssClass = "scfSingleLineGeneralPanel";
            this.title.CssClass = "scfSingleLineTextLabel";
            //this.displayedValue.CssClass = "cp-readonly";

            this.textbox.TextMode = TextBoxMode.SingleLine;

            this.Controls.AddAt(0, this.generalPanel);
            this.Controls.AddAt(0, this.title);
            this.generalPanel.Controls.AddAt(0, this.displayedValue);
            this.generalPanel.Controls.AddAt(0, this.help);
            this.generalPanel.Controls.AddAt(0, this.textbox);
        }

        public override string ID
        {
            get
            {
                return base.ID;
            }
            set
            {
                this.displayedValue.ID = value + "_readonly_text";
                base.ID = value;
                this.displayedValue.AssociatedControlID = this.textbox.ID;
            }
        }

        public ReadOnlyTextBox(HtmlTextWriterTag tag) : base(tag)
              {
        }
        public ReadOnlyTextBox() : this(HtmlTextWriterTag.Div)
              {
        }
    }
}


Once the class above is implemented and deployed, Sitecore needs to know about its existence and how to find it. This is provided by adding a new Sitecore item named “ReadOnly TextBox” in the “master” database under “/sitecore/system/Modules/Web Forms for Marketers/Settings/Field Types/Custom”. This item must me of template “/sitecore/templates/Web Forms for Marketers/Field Type” ({ECF6562F-91E7-4D79-B416-0DB3C2DBF67B}). Within the new item “ReadOnly TextBox” the following fields need to be provided:

  • Assembly: it must contain the name of the DLL where the “ReadOnlyTextBox” class is implemented.
  • Class: Full qualified name of the “ReadOnlyTextBox” class.

wffm


As usual, once the item is created it needs to be published to “web” (or any other public facing database) in order to work properly.


Technical Details

The provided code has been tested for the following Sitecore versions:

  • Sitecore: 8.0 rev. 150812
  • WFFM: 8.0 rev. 150625

Author bio

Benjamin Moles
Benjamin Moles
.NET Developer
I'm a passionate .NET and SQL developer. I've worked with a broad variety of technologies and I am currently contributing to the success of ClearPeople's Sitecore projects. Beside IT stuff, I love to spend time with family and play with remote-controlled helicopters.

Comments


comments powered by Disqus

Related Articles

Sign up to our Newsletter

Every now and then, we'd like to send you information that delivers, develops and promotes our products and services that are relevant to you. Submitting your details tells us that you're OK with this and you also agree to our Privacy & Cookies policy. You can, of course, opt out of these communications at any time.