In Sitecore 9 we can easily extend Sitecore Forms module to execute custom JavaScript code when the form, created in Sitecore is submitted by the users. This can work with multi-page forms with next and back buttons as well:
All the source code from this article is available on Github.
Implementation
First we need a field, where we can enter our custom JavaScript code. Let’s start with creating a new template with Form Submit Script multi-line text field, in /sitecore/templates/Foundation/Forms Custom Script/Custom Scripts
:
Then go to /sitecore/templates/System/Forms/Fields/Button
and assign Custom Scripts template to the base templates:
Next we need to extend a view model class representing submit button in Sitecore Forms. We create a new class inheriting from Sitecore.ExperienceForms.Mvc.Models.Fields.ButtonViewModel
and add support for our new field:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
using Sitecore; using Sitecore.Data.Items; using Sitecore.Diagnostics; using Sitecore.ExperienceForms.Mvc.Models.Fields; namespace Sc.FormsCustomScripts.Models { public class CustomScriptButtonViewModel : ButtonViewModel { public string FormSubmitScript { get; set; } protected override void InitItemProperties(Item item) { Assert.ArgumentNotNull(item, nameof(item)); base.InitItemProperties(item); FormSubmitScript = StringUtil.GetString((object)item.Fields["Form Submit Script"]); } protected override void UpdateItemFields(Item item) { Assert.ArgumentNotNull(item, nameof(item)); base.UpdateItemFields(item); item.Fields["Form Submit Script"]?.SetValue(FormSubmitScript, false); } } } |
After deploying our code to Sitecore, we can use new class in Sitecore Forms setting item: /sitecore/system/Settings/Forms/Field Types/Structure/Submit Button
in Model Type field:
Finally we need to modify the view file responsible for rendering the button in Sitecore Forms \Views\FormBuilder\FieldTemplates\Button.cshtml
:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 |
@using Sitecore.ExperienceForms.Mvc.Constants @model Sc.FormsCustomScripts.Models.CustomScriptButtonViewModel @{ var cssClass = Model.CssClass; if (Model.NavigationStep < 0) { var classes = Model.CssClass.Split(' '); if (!classes.Contains("cancel", StringComparer.OrdinalIgnoreCase)) { if (!string.IsNullOrEmpty(Model.CssClass)) { cssClass += " "; } cssClass += "cancel"; } } } <input value="@Html.DisplayTextFor(t => Model.Title)" type="submit" class="@cssClass" name="@Html.Name(Model.ItemId)" data-sc-field-key="@Model.ConditionSettings.FieldKey" /> @Html.Hidden(AttributeNames.NavigationButtons, Model.ItemId) @Html.Hidden(Model.ItemId, Model.NavigationStep) <script type="text/javascript"> (function ($) { var $inputEl = $("input[name='@Html.Name(Model.ItemId)']"); var $formEl = $inputEl.closest('form'); if ($inputEl.length == 0 || $formEl.length == 0) { return; } $inputEl.click(function () { $("input[type=submit]", $formEl).removeAttr("clicked"); $(this).attr("clicked", "true"); }); @if (Sitecore.Context.Site.Name != "shell") { if (!string.IsNullOrWhiteSpace(Model.FormSubmitScript)) { <text> $formEl.on("submit", function () { if ($inputEl.attr('clicked')) { @Html.Raw(Model.FormSubmitScript) } }); </text> } } })(jQuery) </script> |
In our js code, first we get the submit button and its form element and check if we are not in Sitecore Forms Editor mode (we don’t want to call our js while editing). Then check, if a form submission was triggered by correct button (important for forms with multiple pages and buttons). Finally we attach handler to the form submit event, which executes JavaScript code, loaded from the Sitecore field.
If we want to call js function from external file in our Form Submit Script field, we can reference this file in the form item in Scripts field (the file needs to be copied to \sitecore modules\Web\ExperienceForms\scripts\
folder):