Home » FormRender

Category Archives: FormRender

Specify Which Sitecore Web Forms for Marketers Form To Render Via the Query String

Today I saw a post in one of the SDN forums asking how one could go about building a page in Sitecore that can render a Web Forms for Marketers (WFFM) form based on an ID passed via the query string.

I built the following WFFM FormRenderer as a “proof of concept” to accomplish this — this solution assumes the ID we are passing is the ID of the form, and not some other ID (or guid):

using System;
using System.Web;

using Sitecore.Data.Items;
using Sitecore.Diagnostics;
using Sitecore.Form.Core.Configuration;
using Sitecore.Form.Core.Renderings;

namespace Sitecore.Sandbox.Form.Core.Renderings
{
    public class DetectIDFormRenderer : FormRender
    {
        protected override void OnInit(System.EventArgs e)
        {
            string detectedFormId = GetDetectedFormId();
            if (IsValidFormId(detectedFormId))
            {
                FormID = detectedFormId;
            }
            
            base.OnInit(e);
        }

        private static string GetDetectedFormId()
        {
            return HttpContext.Current.Request["formId"];
        }

        private static bool IsValidFormId(string id)
        {
            return !string.IsNullOrWhiteSpace(id) 
                    && IsID(id) 
                    && IsFormId(id);
        }
        
        private static bool IsID(string id)
        {
            Sitecore.Data.ID sitecoreID;
            return Sitecore.Data.ID.TryParse(id, out sitecoreID);
        }

        private static bool IsFormId(string id)
        {
            Item item = StaticSettings.ContextDatabase.GetItem(id);
            return item != null && item.TemplateID == IDs.FormTemplateID;
        }
    }
}

The FormRenderer above grabs the specified form’s ID via a query string parameter, ascertains whether it’s truly an ID, and determines whether it is an ID of a WFFM Form in Sitecore — these are done via the IsID and IsFormId methods.

If the supplied form ID is valid, we save it to the FormID property defined in the base FormerRender class. Otherwise, we flow through to the “out of the box” logic.

Now it’s time to register the above class in Sitecore.

I duplicated the “out of the box” Form Webcontrol under /sitecore/layout/Renderings/Modules/Web Forms for Marketers, renamed the item to something appropriate, and updated the code-defining fields to point to our new FormRender above:

Detect-ID-Form-FormRenderer

I decided to reuse an existing page item with a WFFM form — I didn’t want to step through ‘Insert Form’ wizard so that I could save time — and swapped out the “out of the box” Form Webcontrol with the new one we created above:

webcontrol-switch

I ensured we had a default form set just in case of query string manipulation, or in the event the form cannot be found by the given ID:

default-form-is-set

I published everything, and navigated to my form page:

no-form-specified

I then specified the empty guid:

invalid-form-specified

I manipulated the query string again, but this time passing a valid form ID:

valid-form-specified

I then changed the form ID again but with another valid form ID:

another-valid-form-specified

If you have any suggestions around making this better, or ideas for a different solution, please drop a comment.

Advertisement

Add JavaScript to the Client OnClick Event of the Sitecore WFFM Submit Button

A SDN forum thread popped up a week and a half ago asking whether it were possible to attach a Google Analytics event to the WFFM submit button — such would involve adding a snippet of JavaScript to the OnClick attribute of the WFFM submit button’s HTML — and I was immediately curious how one would go about achieving this, and whether this were possible at all.

I did a couple of hours of research last night — I experimented with custom processors of pipelines used by WFFM — but found no clean way of adding JavaScript to the OnClick event of the WFFM submit button.

However — right before I was about to throw in the towel for the night — I did find a solution on how one could achieve this — albeit not necessarily a clean solution since it involves some HTML manipulation (I would opine using the OnClientClick attribute of an ASP.NET Button to be cleaner, but couldn’t access the WFFM submit button due to its encapsulation and protection level in a WFFM WebControl) — via a custom Sitecore.Form.Core.Renderings.FormRender:

using System.IO;
using System.Linq;
using System.Web.UI;

using Sitecore.Form.Core.Renderings;

using HtmlAgilityPack;

namespace Sitecore.Sandbox.Form.Core.Renderings
{
    public class AddOnClientClickFormRender : FormRender
    {
        private const string ConfirmJavaScriptFormat = "if(!confirm('Are you sure you want to submit this form?')) {{ return false; }} {0} ";

        protected override void DoRender(HtmlTextWriter output)
        {
            string html = string.Empty;
            using (StringWriter stringWriter = new StringWriter())
            {
                using (HtmlTextWriter htmlTextWriter = new HtmlTextWriter(stringWriter))
                {
                    base.DoRender(htmlTextWriter);
                }

                html = AddOnClientClickToSubmitButton(stringWriter.ToString());
            }

            output.Write(html);
        }

        private static string AddOnClientClickToSubmitButton(string html)
        {
            if (string.IsNullOrWhiteSpace(html))
            {
                return html;
            }

            HtmlNode submitButton = GetSubmitButton(html);
            if (submitButton == null && submitButton.Attributes["onclick"] != null)
            {
                return html;
            }

            submitButton.Attributes["onclick"].Value = string.Format(ConfirmJavaScriptFormat, submitButton.Attributes["onclick"].Value);
            return submitButton.OwnerDocument.DocumentNode.InnerHtml;
        }

        private static HtmlNode GetSubmitButton(string html)
        {
            HtmlNode documentNode = GetHtmlDocumentNode(html);
            return documentNode.SelectNodes("//input[@type='submit']").FirstOrDefault();
        }

        private static HtmlNode GetHtmlDocumentNode(string html)
        {
            HtmlDocument htmlDocument = CreateNewHtmlDocument(html);
            return htmlDocument.DocumentNode;
        }

        private static HtmlDocument CreateNewHtmlDocument(string html)
        {
            HtmlDocument htmlDocument = new HtmlDocument();
            htmlDocument.LoadHtml(html);
            return htmlDocument;
        }
    }
}

The FormRender above uses Html Agility Pack — which comes with Sitecore — to retrieve the submit button in the HTML that is constructed by the base FormRender class, and adds a snippet of JavaScript to the beginning of the OnClick attribute (there is already JavaScript in this attribute, and we want to run our JavaScript first).

I didn’t wire up a Google Analytics event to the submit button in this FormRender — it would’ve required me to spin up an account for my local sandbox instance, and I feel this would’ve been overkill for this post.

Instead — as an example of adding JavaScript to the OnClick attribute of the WFFM submit button — I added code to launch a JavaScript confirmation dialog asking the form submitter whether he/she would like to continue submitting the form. If the user clicks the ‘Cancel’ button, the form is not submitted, and is submitted if the user clicks ‘OK’.

I then had to hook this custom FormRender to the WFFM Form Rendering — /sitecore/layout/Renderings/Modules/Web Forms for Marketers/Form — in Sitecore:

form-rendering

I then saved, published, and navigated to a WFFM test form. I then clicked the submit button:

confirmation-box

As you can see, I was prompted with a JavaScript confirmation dialog box.

If you have any thoughts on this implementation, or know of a better way to do this, please drop a comment.

Until next time, have a Sitecorelicious day! 🙂