Hi Jesper,
When javascript is enabled on browser, the process to replace placeholders with submission data is in ParagraphTextElementBlock.ascx file (on Alloy site -> modules -> _protected -> EPiServer.Forms -> Views -> ParagraphTextElementBlock.ascx).
You can custom the javacript code of that file to replace with key instead of value. Here is what I did and it works
1) Create a new JS function (right under the script tag) to get list option key/value of a selection/choice element
function getListKeyValueForField(fieldName, isChoiceElement) {
var list = {};
if (isChoiceElement) { // choice element
$('input[name=' + fieldName + ']').each(function () {
var choiceText = $(this).parent()[0].innerText;
var choiceValue = this.value;
list[choiceValue] = choiceText;
});
} else { // selection element
$('select[name=' + fieldName + '] option:not(:disabled)').each(function () {
list[this.value] = this.text;
});
}
return list;
}
2) Right under the if statement if(value == null || value === undefined) {//} of existing javascript code add these lines of code
if(value == null || value === undefined) {
value = "";
}
debugger;
if (elementInfo.type === "EPiServer.Forms.Implementation.Elements.ChoiceElementBlock") {
var listKeyVal = getListKeyValueForField(fieldName, true);
value = listKeyVal[value];
} else if (elementInfo.type === "EPiServer.Forms.Implementation.Elements.SelectionElementBlock") {
var listKeyVal = getListKeyValueForField(fieldName, false);
value = listKeyVal[value];
}
I tested and it works. Hope this help.
Hi Quan,
Thanks for the suggestion, I have tryed to update the script as you sugested but due to the files being in a .zip file (EPiServer.Forms.zip) and unzipping and zipping the files with changes gives me an error.
The error states "Unable to find a module by assembly 'EPiServer.Forms, Version=4.17.0.0, Culture=neutral, PublicKeyToken=8fe83dea738b45b7' Parameternamn: moduleAssembly". I guessing EPi has some sort of procedure to check the .zip file like checksum?
I have looked at the AlloyDemoKit and ParagraphTextElementBlock.ascx is in a .zip file there as well. How have you solved this?
Best regards
/Jesper
Hi Jesper,
You don't have to zip the files. Just put your new .ascx file under EPiServer.Forms/Views/ElementBlocks folder (this folder is automatically created when you install Forms). Remember to edit anything in webconfig file or restart server to load the new .ascx view (prevent server from caching). In javascipt code, use debugger; so that you can debug on the client side. (See the updated code above).
Also I'm trying to implement the logic on server side. I will be back when i'm done.
Hi,
When Javascript is disabled, the process to replace placeholders takes place on server side. Create a custom FormParagraphTextService to replace selected value with selected text
using EPiServer.Forms.Core;
using EPiServer.Forms.Core.Internal;
using EPiServer.Forms.Core.Models;
using EPiServer.Forms.EditView.Models.Internal;
using EPiServer.Forms.Helpers.Internal;
using EPiServer.Forms.Implementation;
using EPiServer.Forms.Implementation.Elements;
using EPiServer.Forms.Internal;
using EPiServer.ServiceLocation;
using System.Collections.Generic;
using System.Linq;
using System.Web;
public class CustomFormParagraphTextService : FormParagraphTextService
{
Injected<FormRepository> _formRepository;
Injected<PlaceHolderService> _placeHolderService;
public override string RenderTextWithPlaceHolders(string paragraphText, HttpRequestBase requestBase, Submission submissionData, FormIdentity formIdentity)
{
var container = formIdentity.GetFormBlock();
// get the friendlyname of all field in form
var friendlyNames = _formRepository.Service.GetFriendlyNameInfos(container, typeof(IExcludeInSubmission), typeof(IExcludeInSubmissionSummary));
var allFormElements = container.Form.Steps.SelectMany(st => st.Elements);
var choiceAndSelectionElements = allFormElements.Where(x => x.SourceContent is ChoiceElementBlock || x.SourceContent is SelectionElementBlock);
foreach (var element in choiceAndSelectionElements)
{
// available options that is configured in edit mode (for both Choice and Selection element)
List<OptionItem> availableOptions;
var fieldName = element.SourceContent.GetElementName();
if (element.SourceContent is ChoiceElementBlock)
{
availableOptions = (element.SourceContent as ChoiceElementBlock).GetItems()?.ToList();
}
else
{
availableOptions = (element.SourceContent as SelectionElementBlock).GetItems()?.ToList();
}
// get the selected value from submission data
var selectedValue = submissionData.Data[fieldName]?.ToString();
if (!string.IsNullOrWhiteSpace(selectedValue))
{
// get the selected option and replace selected key by selected value
var selectedOption = availableOptions.FirstOrDefault(x => string.Equals(x.Value, selectedValue, System.StringComparison.OrdinalIgnoreCase));
submissionData.Data[fieldName] = selectedOption?.Caption;
}
}
var placeHolders = _placeHolderService.Service.GetFriendlyNamePlaceHolders(requestBase, submissionData, friendlyNames, false);
return _placeHolderService.Service.Replace(System.Net.WebUtility.HtmlDecode(paragraphText), placeHolders, true);
}
}
And register dependency
.AddTransient<FormParagraphTextService, CustomFormParagraphTextService>();
Please try this approach and it should work.
Thank you Quan!
That did the trick. I will implement youre no JS solution as well (better safe than sorry) :)
Best regards
/Jesper
Hi,
In the end of a multi step form before post we whant to show the user the selections he/she made.
This we can solve with placeholders for most cases but for select key/value selections the placeholder shows the value and not the key.
The values in our form are codes that is gibrish to the user.
Is there a way to add a custom placeholder between steps or some another way to get around this?
Best regards
/Jesper