Copied to clipboard

Flag this post as spam?

This post will be reported to the moderators as potential spam to be looked at


  • David 29 posts 200 karma points
    Jul 08, 2020 @ 16:37
    David
    0

    I am in the process of creating a data driven multi step form, which returns the same view(template) each time the "Next/Previous" buttons are clicked.

    However, when clicking "Next" (submit) I get the following:

    enter image description here

    Here is the main view (template) that will always be returned each time "next/previous" is clicked. (see below)

      @inherits Umbraco.Web.Mvc.UmbracoViewPage<SchemeWizardStepsViewModel>
    @using QuoteBeater.ViewModels;
    
    @{
        Layout = "quoteBeater.cshtml";
    } 
    <section>
            <div class="container">
                <h1>@Model.Scheme.SchemeName</h1>
    
                <div class="wizard-steps">
                    @foreach (var wizardStep in Model.Steps.OrderBy(x => x.WizardStep))
                    {
                        if (wizardStep.WizardStep == Model.CurrentWizardStep)
                        {
                            <span class="wizard-step active">@wizardStep.GroupName</span>
                        }
                        else
                        {
                            <span class="wizard-step">@wizardStep.GroupName</span>
                        }
                    }
                </div>
    
                @for (int i = 0; i < Model.Steps.OrderBy(x => x.WizardStep).ToList().Count; i++)
                {
                    if (Model.Steps[i].WizardStep == Model.CurrentWizardStep)
                    {
                        WizardStepViewModel wizardStepViewModel = Model.Steps[i];
                        @Html.EditorFor(model => wizardStepViewModel, "WizardStepEditor", new { id = "wizStepID" + Model.Steps[i].WizardStep.ToString() })
                        break;
                    }
                }
    
            </div>
        </section>
    

    Here is the view with "beginUmbracoForm" and the questions (used with Html.EditorFor)

    @model WizardStepViewModel
    @using QuoteBeater.ViewModels;
    @using QuoteBeater.Website.Models;
    @using QuoteBeater.Controllers;
    @using System.ComponentModel;
    @using System.Linq;
    
    
    @using (Html.BeginUmbracoForm("HandleWizardStepAction", "QuoteForm"))
    {
        @Html.HiddenFor(x => x.GroupId, new { @id = "GroupID" })
        @Html.HiddenFor(x => x.GroupName)
        @Html.HiddenFor(x => x.IsValidStep)
        @Html.HiddenFor(x => x.WizardStep)
        @Html.HiddenFor(x => x.FinalWizardStep)
    
    
        @Html.AntiForgeryToken()
        @Html.ValidationSummary()
    
        <h3>@Model.GroupName</h3>
    
        for (int i = 0; i < Model.Questions.Count; i++)
        {
            //Questions Render Here
        }
    
        <div class="text-left">
            @if (Model.WizardStep > 1)
            {
                <input type="submit" id="previousSubmit" name="submitButton" class="btn btn-primary btn-lg" value="Previous" formnovalidate />
            }
            @if (Model.WizardStep == Model.FinalWizardStep)
            {
                <input type="submit" name="submitButton" class="btn btn-success btn-lg" value="Finish" />
            }
            else
            {
                <input type="submit" id="nextSubmit" name="submitButton" class="btn btn-primary btn-lg" value="Next" />
            }
        </div>
    

    Here is my model

    public class SchemeWizardStepsViewModel : PublishedContentWrapped
        {
    
            public SchemeWizardStepsViewModel(IPublishedContent content) : base(content) { }
    
            public Scheme Scheme { get; set; }
            public int NumberOfWizardSteps { get; set; }
            public int CurrentWizardStep { get; set; }
            public List<WizardStepViewModel> Steps { get; set; }
    
    
            public void PersistAnswers(int currentWizardStep, WizardStepViewModel currentWizardStepViewModel)
            {
                for (int i = 0; i < Steps.Count; i++)
                {
                    if (Steps[i].WizardStep == currentWizardStep)
                    {
                        List<QuestionViewModel> questions = Steps[i].Questions;
    
                        for (int j = 0; j < questions.Count; j++)
                        {
    
                            //check for nulls
                            if (questions[j] != null)
                            {
                                var answer = currentWizardStepViewModel.Questions.FirstOrDefault(f => f.Question.ID == questions[j].Question.ID).Answer;
    
                                if (answer != null)
                                {
    
                                    questions[j].Answer.AnswerValue = answer.AnswerValue;
                                }
    
                            }
                        }
                    }
                }
    
    
            }
        }
    

    Here is my Controller

    namespace QuoteBeater.Controllers
    {
        public class QuoteFormController : RenderMvcController
        {
    
            public static LogicInstance instance = _Code.SiteSingleton.LogicInstance_ServiceSingleton.Instance;
            public static TeledynamicsWebsiteContext context = instance.GetWebsiteContext(ConfigurationManager.ConnectionStrings["teledynamicsWebsiteDBContext"].ToString());
    
    
            public static ContentModel contentModel { get; set; }
    
            public QuoteFormController() { }
    
            public override ActionResult Index(ContentModel model)
            {
    
                contentModel = model;
                string schemeType = "Private";
    
                ModelState.Clear();
    
                Scheme scheme = context.Schemes_GetAll().FirstOrDefault(x => x.SchemeName.ToLower().Contains(schemeType.ToLower()));
                List<SchemeGroup> schemeGroups = context.Schemes_GetSchemeGroups(scheme.ID);
                List<Question> schemeQuestions = context.Schemes_GetSchemeQuestions(scheme.ID);
    
                foreach (var item in schemeGroups.OrderBy(o => o.Group.ID))
                {
                    List<QuestionViewModel> questionViewModels = new List<QuestionViewModel>();
                    List<Question> groupQuestions = schemeQuestions.Where(f => f.Group.ID == item.Group.ID).ToList();
    
                    for (int i = 0; i < groupQuestions.Count; i++)
                    {
                        questionViewModels.Add(new QuestionViewModel(contentModel.Content) { Question = groupQuestions[i], Answer = new AnswerViewModel(contentModel.Content) { QuestionID = groupQuestions[i].ID } });
                    }
    
                    WizardStepViewModel wizardStepViewModel = new WizardStepViewModel(contentModel.Content)
                    {
                        GroupId = item.Group.ID,
                        GroupName = item.Group.GroupName,
                        Questions = questionViewModels,
                        WizardStep = wizardStep,
                        FinalWizardStep = schemeGroups.Count
                    };
    
                    foreach (var questionViewModel in wizardStepViewModel.Questions)
                    {
    
                    }
    
                    schemeSteps.Add(wizardStepViewModel);
                    wizardStep++;
                }
    
                schemeWizardStepsViewModel.Scheme = scheme;
                schemeWizardStepsViewModel.CurrentWizardStep = 1;
                schemeWizardStepsViewModel.Steps = schemeSteps;
    
                //Persist data here...
                Session["CurrentWizardStep"] = schemeWizardStepsViewModel.CurrentWizardStep;
                Session["SchemeWizardStepViewModel"] = schemeWizardStepsViewModel;
    
                return View("~/Views/quoteForm.cshtml", schemeWizardStepsViewModel);
    
            }
    
    
            [HttpPost]
            [ValidateAntiForgeryToken]
            public ActionResult HandleWizardStepAction(WizardStepViewModel wizardStepViewModel, string submitButton)
            {
                //http://www.binaryintellect.net/articles/c69d78a3-21d7-416b-9d10-6b812a862778.aspx
                //https://stackoverflow.com/questions/442704/how-do-you-handle-multiple-submit-buttons-in-asp-net-mvc-framework
                switch (submitButton)
                {
                    case "Next":
                        return (MoveToNextWizardStep(wizardStepViewModel));
                    case "Previous":
                        return (MoveToPreviousWizardStep(wizardStepViewModel));
                    case "Finish":
                        return (FinishWizard(wizardStepViewModel));
                    default:
                        // If they've submitted the form without a submitButton, 
                        // just return the view again.
                        return (View());
                }
            }
    
    
            [HttpPost]
            [ValidateAntiForgeryToken]
            public ActionResult MoveToNextWizardStep(WizardStepViewModel wizardStepViewModel)
            {
                SchemeWizardStepsViewModel schemeWizardStepsViewModel = (SchemeWizardStepsViewModel)Session["SchemeWizardStepViewModel"];
                return View("~/Views/quoteForm.cshtml", schemeWizardStepsViewModel);
            }
    
    
            [HttpPost]
            [ValidateAntiForgeryToken]
            public ActionResult MoveToPreviousWizardStep(WizardStepViewModel wizardStepViewModel)
            {
                ModelState.Clear();
                SchemeWizardStepsViewModel schemeWizardStepsViewModel = (SchemeWizardStepsViewModel)Session["SchemeWizardStepViewModel"];
                return View("~/Views/quoteForm.cshtml", schemeWizardStepsViewModel);
            }
    
    
            [HttpPost]
            public ActionResult FinishWizard(WizardStepViewModel wizardStepViewModel)
            {
                return  View("~/Views/quoteForm.cshtml");
            }
    
        }
    }
    

    I am not inheriting from "surfacecontroller" and instead using "rendermvccontroller" due to if i used surface, I always faced errors about not being able to bind the models builder model to my custom model.

    Can anyone suggest where I am going wrong?

Please Sign in or register to post replies

Write your reply to:

Draft