Quan Tran
Mar 4, 2019
visibility 10442
star star star star star
(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,

error Please login to comment.
Latest blogs
Surviving a Dirty Feed. Part 3: Error Handling and Event Batching

Committing a 250,000-row Optimizely catalog import row by row, returning a per-row failure report, and coalescing catalog events into one per batch.

Stanisław Szołkowski | Oct 16, 2026 |

Building UI Extensions for Optimizely SaaS CMS

Introduction Developers have been extending the functionality of Optimizely PaaS CMS for years using addons built in C# and deployed as NuGet...

Mark Stott | Oct 15, 2026

Cheapskate AI Translator: Because Translation Should Not Require a Second Mortgage

There is a particular kind of software project that begins with a detailed architecture document, a product roadmap, and a carefully assembled...

Linh Doan Cuu | Oct 15, 2026

Computed Fields in CMS 13 Content Contracts with Optimizely Graph

Content Contracts in Optimizely CMS 13 allow different content types to share a common structure when querying Optimizely Graph. But what if the...

Mardy | Oct 14, 2026