A critical vulnerability was discovered in React Server Components (Next.js). Our systems remain protected but we advise to update packages to newest version. Learn More

Dac Thach Nguyen
Dec 25, 2018
  6499
(6 votes)

EPiServer Forms: How to render Forms in a dialog

In some real scenarios, we might need render an EPiServer Forms within a dialog instead of a page. This case will make user focus on the Form. Today I have tried to make the Form work with jQuery UI dialog. Here a some point I summarized to make it works (assume that you are working with Alloy solution).

Create a page type to render an ContentArea with a Form

[SiteContentType(GroupName = Global.GroupNames.News, GUID = "E5CCD734-81F2-4242-82BA-8D888504112B")]
public class SubcriblePage: SitePageData
{
    [Display(GroupName = SystemTabNames.Content, Order = 320)]
    public virtual ContentArea MainContentArea { get; set; }
}

Then create a page with the page type then dnd a Form into it, publish it (let say it url is: "/en/subcrible/".)

Create a zaror layout to render a page which display nothing but Forms (_Empty.cshtml):

@using System.Web.Optimization
@using EPiServer.Framework.Web.Mvc.Html
@model IPageViewModel<SitePageData>
<!DOCTYPE html>
<html lang="@Model.CurrentPage.LanguageBranch">
<head>
    @Styles.Render("~/bundles/css")
    @Scripts.Render("~/bundles/js")
    @Html.RequiredClientResources("Header")
</head>

<body>
    @RenderBody()
    @Html.RequiredClientResources("Footer")
</body>
</html>

Create a view to render for the page type (SubcriblePage)

@{ Layout = "~/Views/Shared/Layouts/_Empty.cshtml"; }
@using ILMTest
@model PageViewModel<SubcriblePage>

@Html.PropertyFor(x => x.CurrentPage.MainContentArea, new { })
<script>
    if (typeof $$epiforms !== 'undefined') {
        $$epiforms(document).ready(function myfunction() {
            $$epiforms(".EPiServerForms").on("formsSubmitted", function (event, param1, param2) {
                window.parent.$(window.parent.document.body).trigger("submitted");
            });
        });
    }
</script>

This razor view will render an ContentArea with the Form. Add the script will notify parent window to know when the form already submitted (we will close the dialog then).

Open the dialog with a Form (Using iframe which loaded the page alread created above)

<script type="text/javascript">
    var page = "/en/subcrible/";

    var $dialog = $('<div></div>')
        .html('<iframe style="border: 0px; overflow: hidden;" src="' + page + '" width="100%" height="100%"></iframe>')
        .dialog({
            autoOpen: false,
            modal: true,
            height: 450,
            width: 500,
            title: "Some title"
        });
    $dialog.dialog('open');

    $(document).on("submitted", "body", function () {
        setTimeout(function () {
            $dialog.dialog("close");
        }, 1000)
    });
</script>

And here is result:

Dec 25, 2018

Comments

Kane Made It
Kane Made It Jan 4, 2019 01:57 AM

As awesome as always captain Rocky :D

Luc Gosso (MVP)
Luc Gosso (MVP) Jan 23, 2019 03:03 PM

Hey Rocky, Good work, just a friendly comment:

$$epiforms(".EPiServerForms").on("formsSubmitted" is not enough

You have to check the event like this:

 $$epiforms(document).ready(function closeParentModal() {
            $$epiforms(".EPiServerForms").on("formsSubmitted", function (event) {
                if (event.isFinalizedSubmission && event.isSuccess)
                window.parent.$(window.parent.document.body).trigger("submitted");
            });
        });

Or else it will close when captcha is used and wrong or if use of "steps"

Br Luc Gosso

Luc Gosso (MVP)
Luc Gosso (MVP) Jan 23, 2019 03:08 PM

Another thing, the "subscribe" page needs to be a Episerver PageData as in your example else @Html.RequiredClientResources("Header") wont work.

Is there a way to get @Html.RequiredClientResources("Header") to work on an standard MVC view or a Razor "Webpage" 3 view?

@Html.RequiredClientResources("Header") seems to be needing a episerver context page, why is that? (Question to Forms team)

Please login to comment.
Latest blogs
Building an custom Optimizely Opal tool with OCP SDK

Recently I have been working on some custom Opal tools and when looking on hosting options it was a no brainer to utilise Optimizely's OCP platform...

JSpencer | Jan 8, 2026

Event Mechanism on Contact Creation in Optimizely Commerce 14

In Optimizely Commerce 14, there is no traditional event or callback exposed for customer contact creation or updates. Instead, contact lifecycle...

Francisco Quintanilla | Jan 7, 2026 |

A day in the life of an Optimizely OMVP - Introducing Webhook Management in OptiGraphExtensions v4 for Optimizely CMS 12

The OptiGraphExtensions add-on has just received a significant update that many in the Optimizely community have been waiting for: comprehensive...

Graham Carr | Jan 7, 2026

Climbing the Relevancy Ladder: Unlocking Vertex AI Search Tiers in Commerce Search v3

Author: Naveen Samala, Staff Software Engineering at Optimizely What If Your Search Could Predict What Each Customer Will Buy? Imagine a search...

Patrick Lam | Jan 6, 2026

Introducing MicroMediator: A Lightweight High-Performance Mediator for .NET

A lightweight, high-performance mediator pattern library for .NET. Learn why MicroMediator exists, how it compares, and how it fits cleanly into ma...

Andy Blyth | Jan 5, 2026 |

Triggering Opal Workflows When Publishing Content

Over the course of November, my colleagues at Netcel and I took part in Optimizely’s Opal Innovation Challenge. We were tasked to be inventive and ...

Mark Stott | Jan 5, 2026