Programmatically set step's contentId

1 Answer 230 Views
RadioGroup Wizard
Richard
Top achievements
Rank 3
Iron
Iron
Iron
Richard asked on 07 Feb 2023, 05:52 PM

Good afternoon,

I'm trying to find a way to programmatically set the content id for the next step in a wizard based on a radiogroup choice on the previous step.

I'm basing it on the Accepted answer from Mihaela on this post:

https://www.telerik.com/forums/skipping-diabled-steps-in-wizard-doasn-t-work

Incidentally, the required validation on the radiogroup in the example doesn't seem to work - you can click next to step 2 without choosing an option.

Rather than disable steps and jump to a different next step, I'd like to set the content for the next step based on the selected option.

On the select event for the wizard form I've tried the following:

                    var wizard = e.sender;
                    var radioValue = $("input[name='uploadType']:checked").val();
                    if (radioValue == "1") {
                        //e.sender.insertAt(3, { title: "Upload File(s)", contentId: "uploadFile" });
                        wizard.steps()[3].contentId = "uploadFile";
                    }
                    else {
                        //e.sender.insertAt(3, { title: "Choose File(s)", contentId: "chooseFile" });
                        wizard.steps()[3].contentId = "chooseFile";
                    }
                    e.preventDefault();
                    wizard.select(3);

I've used the syntax from this question:

https://www.telerik.com/forums/programmatically-enable-or-disable-wizard-buttons

$("#wizard").data("kendoWizard").steps()[1].buttons()[1].enable(true);

This assumes that e.sender on the wizard select event is the equivalent of $("#wizard").data("kendoWizard").

I have two templates with partial views which are used dependent on the radiogroup selected value:

<script type="text/x-kendo-template" id="uploadFile">
    @await Html.PartialAsync("_UploadFile")
</script>

<script type="text/x-kendo-template" id="chooseFile">
    @await Html.PartialAsync("_UploadChoose")
</script>

The insertAt method works by inserting a step with the desired content, but I don't want to insert multiple new steps.

Can what I want to do be achieved?  Can the content be set programmatically?

I did also wonder if it was possible to have the conditional logic (e.g. if (radiogroup value == 1) in the kendo template, but this also didn't seem to work.

Kind regards,

Richard

1 Answer, 1 is accepted

Sort by
0
Accepted
Alexander
Telerik team
answered on 10 Feb 2023, 04:31 PM

Hi Richard,

Thank you for reaching out.

Based on my current understanding of the case, the desired outcome is dynamically changing the given step's content prior to a RadioGroup selection. Am I assuming correctly?

Generally, the Wizard is simply a component that displays content in sequential, stepwise order. Each step of the Telerik UI for ASP.NET Core Wizard has content, which is an HTML structure displayed within the widget. However, the component itself does not expose such functionality to decide what type of content to be displayed in the different steps, but the content could be loaded from the server and the server might return different views/content based on a condition. I recommend you review the following article. It demonstrates how to load content from a remote resource by using AJAX: 

Wizard Loading Content with AJAX Demo - Open the "View Source" tab to observe the Wizard's configuration

That being said, integration of such functionality would involve a significant amount of alteration to the currently implemented scenario on your end which may cause further disruption down the line.

Regardless, a possible approach to achieve the desired outcome would be to:

  • Omit the current inline template scripts that involve partial views.
  • Specify a step with empty content by default. The following step will act as a container for either of the specified partial views that need to be loaded:
.Steps(s =>
{
    s.Add()
        .Title("Choose Route")
        .Content(" ")
        .Buttons(b =>
        {
            b.Next();
        });
})
  • Set the .ReloadOnSelect() API configuration of the component explicitly to "true". This would ensure that the partial views are changed each time the step is persisted through user interaction:
.ReloadOnSelect(true)
  • Add an additional field within the Wizard Model that will be used to further determine which PartialView would be loaded (highlighted in blue):
public class TransactionViewModel
{
    public string Type
    {
        get;
        set;
    }
	
   // Additional fields
}
  • Integrate an initial step, particularly for the previously defined "Type" field. For the purposes of the demonstration, I have utilized a RadioGroup editor:
.Steps(s =>
{
    s.Add()
    .Title("File Type")
    .Form(f => f
        ...
        .Items(items =>
        {
            items.Add()
                .Field("Type")
                .Label(l => l.Text("Is Individual:"))
                .Editor(e => e.RadioGroup()
                          .Items(items =>
                          {
                              items.Add().Label("Choose").Value("Choose");
                              items.Add().Label("Upload").Value("Upload");
                          })
                );
        })
    )
    .Buttons(b =>
    {
        b.Next();
    });
    ...
})
  • Within the select event, based on the step that includes the aforementioned radio group, explicitly specify an endpoint that will be used for loading either of the partial views (highlighted in orange):
<script>
    function onFormSelect(e) {
        // Get the current step's index
        var stepIndex = e.step.options.index;
        // Get the current step's container element
        var container = e.sender.currentStep.element;
        if (stepIndex == 1){
            var selectedType = $("#Type").data("kendoRadioGroup").value(); // Get the selected value of the radio group.
            e.sender._steps[1].options.contentUrl = "@Url.Action("Load_Step","Home")" + "?type=" + selectedType; // Dynamically set a remote endpoint and pass the selected type.
        }
        if (stepIndex == 2) {
            var selectedType = $("#Type").data("kendoRadioGroup").value(); 
            if(selectedType == "Choose"){ // Based on the RadioGroup selection, employ validation.
                 // Instantiate a validator for the container element
                 $(container).kendoValidator({
                    validationSummary: {
                        container: "#route-summary"
                    }
                 });
            
                 // Get the validator's reference
                 var validator = $(container).data("kendoValidator");
                 // Validate given input elements.
                 console.log(validator);
                 if (!validator.validate()) {
                     // Prevent the wizard's navigation.
                     e.preventDefault();
                 }
            }
        }
    }
</script>

Where the specified endpoint would look something as follows:

public IActionResult Load_Step(string type)
{
    if (type == "Choose")
    {
        return PartialView("_ChoosePartial");
    }
    return PartialView("_UploadPartial");
}

Note that this would require omission of the Deferred initialization within the partial views as contrary to my last reply, the content will be loaded in an asynchronous manner.

The aforementioned suggestion would produce the following result whilst preserving the validation (when needed) as demonstrated in the following screencast.

For your convenience, I am also attaching a runnable sample in case you experience any difficulties during the development process. Feel free to further modify the sample as per your requirements.

It is important to mention that due to the custom nature of the approach, any further enhancements or alterations would fall within the developer's hands to further implement based on his requirements and needs.

I hope this helps during your endeavors.

Kind Regards,
Alexander
Progress Telerik

Love the Telerik and Kendo UI products and believe more people should try them? Invite a fellow developer to become a Progress customer and each of you can get a $50 Amazon gift voucher.

Richard
Top achievements
Rank 3
Iron
Iron
Iron
commented on 22 Feb 2023, 02:11 PM

Hi Alexander,

Many thanks for your answer - it is exactly what I wanted. Just one thing:

I left the type (kendoRadioGroup) as a partial view as I could include a span for an invalid message - I think the built-in invalid message when using the form on the step, as per your example, looks a bit untidy as the message appears inside the RadioGroup.

This looks neater:

Many thanks again for all your advice.

Kind regards,

Richard

Tags
RadioGroup Wizard
Asked by
Richard
Top achievements
Rank 3
Iron
Iron
Iron
Answers by
Alexander
Telerik team
Share this question
or