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

Quan Tran
Mar 4, 2019
  9754
(7 votes)

EPiServer.Forms show loading icon

When submission process takes a long time to complete, a loading icon should be shown just to let users know something is happening. It is easily done with EPiServer.Forms

  1. Create FormStyle.css file to write cutom style for form and put it under ~/ClientResources/Styles folder. 
.modal {
    display: none;
    position: fixed;
    z-index: 9999;
    top: 0;
    left: 0;
    height: 100%;
    width: 100%;
    background: rgba( 255, 255, 255, .8 ) url('http://i.stack.imgur.com/FhHRx.gif') 50% 50% no-repeat;
    margin: 0;
}

.loading .modal {
    overflow: hidden;
}

.loading .modal {
    display: block;
}

2. Create a file name FormScript.js and put it under ~/ClientResources/Scripts folder. We will hook into Form's events to show/hide loading icon

if (typeof $$epiforms !== 'undefined') {

    var $body = $("body");
    var $loadingDiv = $('<div class="modal"></div>');
    $body.append($loadingDiv);
    epi.EPiServer.Forms.AsyncSubmit = true;

    $$epiforms(document).ready(function myfunction() {
        // listen to event when form is about submitting
        $$epiforms(".EPiServerForms").on("formsStartSubmitting", function (data) {
            //var $formContainer = $('#' + data.workingFormInfo.Id);
            //$formContainer.addClass("loading");
            $body.addClass('loading');
        });

        // listen to event when form is successfully submitted
        $$epiforms(".EPiServerForms").on("formsSubmitted", function (data) {
            $body.removeClass('loading');
        });

        // formsSubmittedError
        $$epiforms(".EPiServerForms").on("formsSubmittedError", function (data) {
            $body.removeClass('loading');
        });
    });
}

3. Register external client resources that we just created above to EPiServer.Forms.

using System;
using System.Collections.Generic;
using EPiServer.Forms.Implementation;
using EPiServer.ServiceLocation;

/// <summary>
/// Register client resources to EPiServer.Forms
/// </summary>
[ServiceConfiguration(ServiceType = typeof(IViewModeExternalResources))]
public class ViewModeExternalResources : IViewModeExternalResources
{
    public virtual IEnumerable<Tuple<string, string>> Resources
    {
        get
        {
            var arrRes = new List<Tuple<string, string>>();
            arrRes.Add(new Tuple<string, string>("script", "/ClientResources/Scripts/FormScript.js"));
            arrRes.Add(new Tuple<string, string>("css", "/ClientResources/Styles/FormStyle.css"));

            return arrRes;
        }
    }
}

When form is submitting, the page will look like this

Note: If submission process does not take long we might not see the loading icon. In this case, debug on dev tools to see the result.

Mar 04, 2019

Comments

KennyG
KennyG Mar 4, 2019 02:57 PM

Wonder where you got this idea? :)

Quan Tran
Quan Tran Mar 5, 2019 07:26 AM

Hi KennyG,

From your post regarding Salesforce Marketing Automation :D

Parshant
Parshant Jun 2, 2025 07:18 AM

Hi Quan,

Thank you for the helpful article on showing a loading icon with Episerver Forms.

I attempted to implement the solution using the following package versions:

  • EPiServer.CMS Version 12.29.0

  • EPiServer.Forms Version 5.9.1

However, it seems that the JavaScript event listeners (formsNavigationNextStep and formsNavigationSubmit) are not being triggered at all in my setup. I’ve verified that the script is loading, but the events are never fired.

Has there been any change in the Forms module or event model that might cause this in the newer versions? I'd appreciate any insights or alternative approaches to achieve the loading indicator behavior.

Best regards,

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