Web Forms for Marketers にはメールフィールドはありますが、メール確認フィールドを持つメールフィールドは用意されていません。今回はメール確認用のテキストボックスをもつカスタムフィールドの定義を作成します。

検証環境は次の通り

  • Sitecore CMS 6.6 Update 6
  • Web Forms for Marketers 2.3

ちなみに今回の元ネタはhttp://sitecoresolutions.blogspot.jp/2012/01/web-forms-for-marketers-email.htmlを参考にしています。

方針としてWFFMに標準で用意されているパスワード - 確認 複合フィールドの定義とASCXファイルを流用して 電子メール - 確認 カスタムフィールドを作成していきます。

1. メール - 確認 フィールドの作成

パスワード - 確認 (Password-Confirm) 複合フィールドを複製して メール - 確認 (Mail-Confirm) カスタム複合フィールドを定義します。下図のようにコンテンツエディター上で  /sitecore/system/Modules/Web Forms for Marketers/Settings/Field Types/Complex/Password-Confirmation を選択してカスタム配下にアイテムをコピーしてください。今回は 名前を Email-Confirm, 表示名を 電子メール - 確認 としました。

後で使用するので、電子メール - 確認アイテム  配下の 電子メールと確認の定義アイテムの ID をメモしておいてください。

次に Email-Confirm アイテムを選択します。 コンテンツタブの Validation フィールドで下図のように電子メールの検証を追加します。User Controlフィールドのascx を PassworddConfirmation.ascx から EmailConfirmation.ascx に変更します。下図のようにフィールドの値は  /sitecore modules/web/Web Forms for Marketers/UI/UserControl/EmailConfirmation.ascx になります。 

以上でフィールドの定義が完了です。

2. EmailConfirm.ascx の作成

Website\sitecore modules\Web\Web Forms for Marketers\UI\UserControl配下のPasswordConfirmation.ascx を コピーして EmailConfirm.ascx というファイルを作成します(下図参照)。

EmailConfirmation.ascx ファイルをメモ帳で開きます。大文字と小文字を区別するにチェックを入れて Password を Email, password を email に置換します。大文字、小文字を区別せずに置換するとあとでコンパイルが面倒になるので注意してください。下図では Password を Email に置換しています。

下図では password を email に置換しています。置換後、ascxファイル内の TextBox コントロールのマークアップで TextMode="Email" となっている箇所を削除します(置換前は TextMode="Password" となっていた場所になります)。

変種が終わるとascxファイルは次のようになっているとはずです。

<%@ Control Language="C#" AutoEventWireup="true" Inherits="Sitecore.Form.UI.UserControls.EmailConfirmation" %>
<%@ Register TagPrefix="wfmcustom" Namespace="Sitecore.Form.Web.UI.Controls" Assembly="Sitecore.Forms.Custom" %>
<%@ Register TagPrefix="wfmcore" Namespace="Sitecore.Form.Web.UI.Controls" Assembly="Sitecore.Forms.Core" %>
<%@ Register TagPrefix="wfmsystem" Namespace="Sitecore.Form.Core.Controls" Assembly="Sitecore.Forms.Core" %>
<%@ Register TagPrefix="wfmvalidator" Namespace="Sitecore.Form.Validators" Assembly="Sitecore.Forms.Core" %>
<%@ Register TagPrefix="wfmvalidatorex" Namespace="Sitecore.Form.Core.Validators"
  Assembly="Sitecore.Forms.Core" %>
<div>
  <asp:Panel ID="emailBorder" CssClass="scfConfirmEmailBorder" runat="server">
    <wfmcustom:Label ID="emailTitle" AssociatedControlID="email" runat="server" CssClass="scfConfirmEmailLabel"
      Text="Email" />
    <asp:Panel ID="emailPanel" CssClass="scfConfirmEmailGeneralPanel" runat="server">
      <asp:TextBox MaxLength="256" AutoCompleteType="Disabled" CssClass="scfConfirmEmailTextBox email.1"
        ID="email" runat="server">            
      </asp:TextBox>
      <asp:Label ID="emailHelp" CssClass="scfConfirmEmailUsefulInfo" Style="display:none"
        runat="server" />
    </asp:Panel>
  </asp:Panel>
</div>
<div>
  <asp:Panel ID="confirmationBorder" CssClass="scfConfirmEmailBorder" runat="server">
    <wfmcustom:Label ID="confirmationTitle" runat="server" CssClass="scfConfirmEmailLabel"
      AssociatedControlID="confirmation" Text="Confirmation" />
    <asp:Panel ID="confirmationPanel" CssClass="scfConfirmEmailGeneralPanel" runat="server">
      <asp:TextBox ID="confirmation"  MaxLength="256" CssClass="scfConfirmEmailTextBox confirmation.1"
        runat="server" AutoCompleteType="Disabled" />
      <asp:Label ID="confimationHelp" CssClass="scfConfirmEmailUsefulInfo" Style="display:none"
        runat="server" />
    </asp:Panel>
  </asp:Panel>
</div>

 

ascx ファイルの準備ができました。コードビハインドファイルを作成していきます。下図のように作成した EmailConfirmation.ascx ファイルを サイトコア拡張用のWebアプリケーションプロジェクトに追加してください。

 

ソリューションエクスプローラー上で EmailConfirmation.ascx の一つ上のフォルダを右クリック → Add → New Item をクリックします。ファイルのテンプレートにClassを選択し、 EmailConfirmation.ascx.cs というファイル名で新規作成します。

コードビハインドファイルが作成しました。コードを記述する前に必要なdll参照を追加します。下図のように bin フォルダに配置されている Sitecore.Forms.Core.dll と Sitecore.Forms.Custom.dll をプロジェクトの参照に追加します。WFFMのパッケージをインストールしていないと サイトコアのWebサイトのbinフォルダに前述のdllがないので注意してください。参照の追加で Sitecore.Forms.Core.dll を追加。忘れずにプロパティ画面で ローカルコピーを FALSE に変更します。

次のようにEmailConfirmation.ascx.cs のソースを編集します。名前空間やクラス名は EmailConfirmation.ascx の Controlディレクティブで指定した

クラス、名前空間に適宜書き換えてください。いままでの説明通り作成していけば名前空間やクラス名は下記ソースを修正する必要はありません。ただし、_emailId は最初に作成した 電子メールの定義アイテムの ID, _confirmId には 確認 の定義アイテムの ID (GUID) を設定してください。

using Sitecore.Form.Core.Attributes;
using Sitecore.Form.Core.Configuration;
using Sitecore.Form.Core.Controls;
using Sitecore.Form.Core.Controls.Data;
using Sitecore.Form.Core.Utility;
using Sitecore.Form.Core.Visual;
using Sitecore.Form.Web.UI.Controls;
using Sitecore.StringExtensions;
using System;
using System.ComponentModel;
using System.Web.UI;
using System.Web.UI.WebControls;

namespace Sitecore.Form.UI.UserControls
{
    public class EmailConfirmation : ValidateUserControl, IHasTitle
    {
        protected Panel emailBorder;
        protected Sitecore.Form.Web.UI.Controls.Label emailTitle;
        protected Panel emailPanel;
        protected TextBox email;
        protected System.Web.UI.WebControls.Label emailHelp;
        protected Panel confirmationBorder;
        protected Sitecore.Form.Web.UI.Controls.Label confirmationTitle;
        protected Panel confirmationPanel;
        protected TextBox confirmation;
        protected System.Web.UI.WebControls.Label confimationHelp;

        private string _emailId = "{AD7FDA7B-0870-4D3A-92B7-9F8CC331363F}";
        private string _confirmId = "{501E504C-13D0-45E5-91EE-7D7C558E54FC}";

        public override string ID
        {
            get
            {
                return this.email.ID;
            }
            set
            {
                this.email.ID = value;
                this.emailTitle.AssociatedControlID = value;
                base.ID = value + "border";
            }
        }
        [Localize, VisualCategory("Appearance"), VisualFieldType(typeof(TextAreaField)), VisualProperty("Email Help:", 200)]
        public string EmailHelp
        {
            get
            {
                return this.emailHelp.Text;
            }
            set
            {
                this.emailHelp.Text = value;
                if (!string.IsNullOrEmpty(this.emailHelp.Text))
                {
                    this.emailHelp.Style.Remove("display");
                    return;
                }
                this.emailHelp.Style["display"] = "none";
            }
        }
        [Localize, VisualCategory("Appearance"), VisualFieldType(typeof(TextAreaField)), VisualProperty("Confirm Email Help:", 500)]
        public string ConfirmationHelp
        {
            get
            {
                return this.confimationHelp.Text;
            }
            set
            {
                this.confimationHelp.Text = value;
                if (!string.IsNullOrEmpty(this.confimationHelp.Text))
                {
                    this.confimationHelp.Style.Remove("display");
                    return;
                }
                this.confimationHelp.Style["display"] = "none";
            }
        }
        [VisualFieldType(typeof(CssClassField)), VisualProperty("Css Class:", 600), DefaultValue("scfEmailConfirmation")]
        public new string CssClass
        {
            get
            {
                return base.Attributes["class"];
            }
            set
            {
                base.Attributes["class"] = value;
            }
        }
        [Localize, VisualFieldType(typeof(EditField)), VisualProperty("Email Title:", 190), DefaultValue("Email")]
        public string EmailTitle
        {
            get
            {
                return this.emailTitle.Text;
            }
            set
            {
                this.emailTitle.Text = value;
            }
        }
        [Localize, VisualFieldType(typeof(EditField)), VisualProperty("Confirm Email Title:", 300), DefaultValue("Confirm Email")]
        public string ConfirmationTitle
        {
            get
            {
                return this.confirmationTitle.Text;
            }
            set
            {
                this.confirmationTitle.Text = value;
            }
        }
        [VisualCategory("Validation"), VisualFieldType(typeof(SelectPredefinedValidatorField)), VisualProperty("Validation:", 790), DefaultValue("")]
        public string PredefinedValidator
        {
            get;
            set;
        }
        [VisualCategory("Validation"), VisualFieldType(typeof(RegexField)), VisualProperty("Regular Expression:", 800), DefaultValue("")]
        public string RegexPattern
        {
            get;
            set;
        }
        [VisualCategory("Validation"), VisualProperty("Maximum Length:", 2000), DefaultValue(256)]
        public int MaxLength
        {
            get
            {
                return this.email.MaxLength;
            }
            set
            {
                this.email.MaxLength = value;
                this.confirmation.MaxLength = value;
            }
        }
        [VisualCategory("Validation"), VisualProperty("Minimum Length:", 1000), DefaultValue(0)]
        public int MinLength
        {
            get;
            set;
        }
        public override ControlResult Result
        {
            get
            {
                return new ControlResult(this.ControlName, this.email.Text, "{0}".FormatWith(new object[]
                {
                    this.email.Text
                }));
            }
        }
        protected override Control ValidatorContainer
        {
            get
            {
                return this.emailBorder;
            }
        }
        protected override Control InnerValidatorContainer
        {
            get
            {
                return this.emailPanel;
            }
        }
        public string Title
        {
            get
            {
                if (!string.IsNullOrEmpty(this.EmailTitle) && !string.IsNullOrEmpty(this.ConfirmationTitle))
                {
                    return string.Join("-", new string[]
					{
						this.EmailTitle,
						this.ConfirmationTitle
					});
                }
                return string.Empty;
            }
            set
            {
            }
        }
        public EmailConfirmation()
        {
            this.CssClass = "scfEmailConfirmation";
        }
        public override bool SetValidatorProperties(BaseValidator validator)
        {
            base.SetValidatorProperties(validator);
            object obj = null;
            if (validator is ICloneable)
            {
                obj = ((ICloneable)validator).Clone();
            }
            validator.ErrorMessage = validator.ErrorMessage.FormatWith(new object[]
			{
				this.EmailTitle,
				this.MinLength,
				this.MaxLength,
				this.ConfirmationTitle
			});
            validator.Text = validator.Text.FormatWith(new object[]
			{
				this.EmailTitle,
				this.MinLength,
				this.MaxLength,
				this.ConfirmationTitle
			});
            validator.ToolTip = validator.ToolTip.FormatWith(new object[]
			{
				this.EmailTitle,
				this.MinLength,
				this.MaxLength,
				this.ConfirmationTitle
			});
            validator.CssClass += string.Join(string.Empty, new string[]
			{
				" confirmationControlId.",
				this.confirmation.ID
			});
            if (obj != null && obj is BaseValidator)
            {
                BaseValidator baseValidator = (BaseValidator)obj;
                baseValidator.ErrorMessage = baseValidator.ErrorMessage.FormatWith(new object[]
				{
					this.ConfirmationTitle,
					this.MinLength,
					this.MaxLength,
					this.EmailTitle
				});
                baseValidator.Text = baseValidator.Text.FormatWith(new object[]
				{
					this.ConfirmationTitle,
					this.MinLength,
					this.MaxLength,
					this.EmailTitle
				});
                baseValidator.ToolTip = baseValidator.ToolTip.FormatWith(new object[]
				{
					this.ConfirmationTitle,
					this.MinLength,
					this.MaxLength,
					this.EmailTitle
				});
                baseValidator.ID += "confirmation";
                baseValidator.ControlToValidate = this.confirmation.ID;
                if (validator.Attributes["inner"] == "1")
                {
                    this.confirmationPanel.Controls.Add(baseValidator);
                }
                else
                {
                    this.confirmationBorder.Controls.Add(baseValidator);
                }
            }
            return true;
        }
        protected override void OnLoad(EventArgs e)
        {
            base.OnLoad(e);
            string str = string.Join(string.Empty, new string[]
			{
				" fieldid.",
				this.FieldID,
				"/",
				this._confirmId
			});
            TextBox expr_41 = this.email;
            expr_41.CssClass += string.Join(string.Empty, new string[]
			{
				" fieldid.",
				this.FieldID,
				"/",
				this._emailId
			});
            TextBox expr_90 = this.confirmation;
            expr_90.CssClass += str;
            MarkerLabel markerLabel = (MarkerLabel)WebUtil.FindFirstOrDefault(this.ValidatorContainer, (Control c) => c is MarkerLabel);
            if (markerLabel != null)
            {
                MarkerLabel markerLabel2 = (MarkerLabel)markerLabel.Clone();
                markerLabel2.ID = markerLabel.ID + "confirmationmarker";
                this.confirmationBorder.Controls.Add(markerLabel2);
            }
        }
    }
}

上記ソースは PasswordConfirmation のソースの PasswordをEmail, passwordをemail に大文字小文字区別して 置換後、 一部ソースを修正したものになっています。

具体的には _emailId, _confirmId フィールドを追加して使っています。 前述したように _emailId は 電子メールアイテムのID, _confirmId は確認アイテムのIDを設定してください。 IDはアイテムを作成した環境ごとに独自のIDになっているはずです。 そのほか Resultプロパティの定義も変更しています。

3. 動作確認

動作確認をしてみます。Form の編集画面でフィールドを追加すると  下図のように カスタムグループ配下に作成した カスタムフィールドタイプ"電子メール - 確認"が表示されるようになります。

フィールドを配置してフォームをプレビューすると 下図のように 電子メール入力フィールド用のテキストボックスとメール確認用のテキストボックスが表示されるようになります。

電子メールと確認用の電子メールのテキストボックスに異なるテキストを入力すると 適切なエラーメッセージを表示してくれます。

フォームレポートを表示すると 入力した 電子メールアドレスが記録されていることが確認できます。

4. まとめ

説明は以上となります。今回は パスワード - 確認(Password-Confirm) 定義フィールドとPassword-Confirm.ascx ファイルを複製してメール確認のテキストボックスをもつフィールドタイプを作成しました。本来はカスタムのフィールドを1から作成すべきかもしれませんが、元ネタのサイトを参考にすることでメール確認のテキストボックスを持つカスタム電子メールフィールドを作成できました。