8

I have a Sitecore 8.1 WFFM form in an MVC form rendering, with a save action that takes a few seconds to complete. After submitting the form, the user just sees the form page they submitted with no message to show that it is processing, until the server finishes the save actions and redirects to the success page or shows the success message. This seems to be the same regardless of whether the Is Ajax Mvc Form checkbox is selected or not for the WFFM form.

During this wait the user might try resubmitting the form again, which I need to prevent.

Example code for a slow save action is:

    using System;
    using System.Configuration;
    using Sitecore.Data;
    using Sitecore.WFFM.Abstractions.Actions;
    using Sitecore.WFFM.Actions.Base;

    namespace Sitecore.Custom.Forms.SaveActions
    {
        public class SlowSaveAction : WffmSaveAction
        {
            public override void Execute(ID formId, AdaptedResultList adaptedFields, ActionCallContext actionCallContext = null, params object[] data)
            {
                System.Threading.Thread.Sleep(8000);
            }
        }
    }

I have tried editing the default FormViewModel.cshtml with javascript to disable the submit button after the form is submitted (which works in pre-mvc versions of WFFM), but because the mvc form is dynamically reloaded after clicking submit, the button is immediately reset to enabled.

I have also looked in the Sitecore.Forms.Mvc.ViewModels.FormViewModel model for any value that might identify that the form is submitted and validation passed, but couldn't find anything.

Is there some way to disable the submit button whilst the form is processing? Or perhaps as an alternative, hide the button and show a 'processing' message?

5

I think it is still better to do via Javascript. You should be able to disable(hide button) on submit.

mvc form is dynamically reloaded after clicking submit, the button is immediately reset to enabled

I was not able to find JS code (wffm.js) that immediately reset button to enabled. Form is dynamically changed only on formSubmitError and formSubmitSuccess

$scw('#' + targetId).html(res);
$scw('#' + targetId).html(xhr.responseText);

It means that button could be enabled only when you receive response from server(form actions either succeed or failed).

But there is present code

e.preventDefault()

that could block execution of your JS code that makes button disabled. If my assumption is right you should force your code to be executed before WFFM submit event.

As a last resort WFFM scripts are not uglified and minimized, so you can easily modify them. Scripts are located here: sitecore modules\Web\Web Forms for Marketers\mvc\wffm.js. But you should remember about your modification when you will update WFFM module.

1

For future developers, the following was my attempt at this by directly editing the file Anton mentioned (sitecore modules\Web\Web Forms for Marketers\mvc\wffm.js). Please do note this change in a shared wiki so future WFFM upgrades are also 'fixed' in the same way.

Complete excerpt:

$scw(form).submit(function (e) {
          $scw("input[type=submit]").attr("disabled", "disabled");      
          if ($scw(this).valid()) {

            var headersList = {
              "X-RequestVerificationToken": $scw(form).find('[name=__RequestVerificationToken]').val(),
              "X-Requested-With": "XMLHttpRequest"
            };

            if (notExternalSite) {
              $scw.ajax({
                url: this.action,
                type: this.method,
                processData: false,
                contentType: false,
                headers: headersList,
                data: new FormData(form.get(0)),
                success: function (res) {
                  self.formSubmitSuccess(form, res);
                  $scw("input[type=submit]").removeAttr("disabled");         
                },
                error: function (xhr, status, exception) {
                  self.formSubmitError(form, xhr, status, exception);
                  $scw("input[type=submit]").removeAttr("disabled");     
                }
              });

            } else {

              var formIdInput = form.find("input[id=" + form.attr("id") + "_Id]");
              var formItemIdInput = form.find("input[id=" + form.attr("id") + "_FormItemId]");
              var hostUrl = getFxmHost() + "/form/process?" + formIdInput.attr("name") + "=" + formIdInput.attr("value") + "&"
                  + formItemIdInput.attr("name") + "=" + formItemIdInput.attr("value");
              $scw.ajax({
                url: hostUrl,
                type: 'POST',
                dataType: "json",
                processData: false,
                contentType: false,
                data: new FormData(form.get(0)),
                success: function (res) {
                  self.formSubmitSuccess(form, res);
                  $scw("input[type=submit]").removeAttr("disabled");     
                },
                error: function (xhr, status, exception) {
                  self.formSubmitError(form, xhr, status, exception);
                  $scw("input[type=submit]").removeAttr("disabled");     
                },
                xhrFields: {
                  withCredentials: true
                }
              });

            }
            e.preventDefault();
          }
          else {
            $scw("input[type=submit]").removeAttr("disabled");     
          }
        });

Notice the addition and removal of the disabled attribute on submit buttons.

$scw("input[type=submit]").attr("disabled", "disabled"); $scw("input[type=submit]").removeAttr("disabled");

The else at the end was my own additional to ensure it was removed on a form validation failure.

else {
    $scw("input[type=submit]").removeAttr("disabled");     
}

I'd argue this could be done better by targeting the specific submit button in the form instead of all submit buttons, but this solution worked for my use case. I encourage others to either edit mine to target that forms submit button or create a new answer.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.