November Happy Hour will be moved to Thursday December 5th.

Use key fom key/value selection fom input insted of value as placeholder

Vote:
 

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

#200506
Jan 14, 2019 15:31
Vote:
 

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.

#200528
Edited, Jan 15, 2019 5:15
Vote:
 

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

#200534
Edited, Jan 15, 2019 10:03
Vote:
 

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.

#200536
Edited, Jan 15, 2019 10:22
Vote:
 

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.

#200537
Jan 15, 2019 10:43
Vote:
 

Thank you Quan!

That did the trick. I will implement youre no JS solution as well (better safe than sorry) :)

Best regards
/Jesper

#200538
Jan 15, 2019 11:05
This topic was created over six months ago and has been resolved. If you have a similar question, please create a new topic and refer to this one.
* You are NOT allowed to include any hyperlinks in the post because your account hasn't associated to your company. User profile should be updated.