ASP.NET MVC Wizard AJAX Partial Views and how to save the model.

0 Answers 37 Views
Form Wizard
Joshua
Top achievements
Rank 1
Joshua asked on 20 Feb 2024, 02:56 AM | edited on 22 Feb 2024, 10:43 PM

After a long day, I finally got all the validation working as I intend it.  The question I now have is how do I pass the model back and forth between each step?   My basic setup is I have Business.cshtml that has my Wizard on it.  For each step of the wizard I then  retrieve the correct PartialView and render to the step.  What I am unsure of how to do is how do you pass the model back and forth.  I made the assumption using '@Url.Action("_BusinessFinancial", "Onboard",Model)' in the javascript would work but I am just not 100% how to save the model between each step and reuse it.

 

Here is my Business.cshtml

 


@using Kendo.Mvc.UI
@model Reverberate.BLL.Model.Form.Application.BusinessOnboarding.BusinessOnboardingModel

@{
    ViewBag.Title = "Business Onboarding";
    Layout = "~/Views/Shared/_Layout.cshtml";
}

<style>
    .wide {
        width: 95%;
    }

    .field-validation-error {
        color: red;
    }
</style>


<!-- Wizard -->
@(Html.Kendo().Wizard()
        .Name("wizard")
        .Events(ev => ev.Select("onSelect"))
        .Events(ev => ev.Done("onDone"))
        .LoadOnDemand(true)
        .HtmlAttributes(new { @novalidate = "" })
        .ReloadOnSelect(false)
        .Steps(s =>
        {
            s.Add<Reverberate.BLL.Model.Form.Application.BusinessOnboarding.BusinessOnboardingModel>()
            .Title("Business Profile")
            .ContentUrl(Url.Action("_BusinessProfile", "Onboard", Model))
            .Buttons(b =>
            {
                b.Next().Text("Next");
            });

            s.Add<Reverberate.BLL.Model.Form.Application.BusinessOnboarding.BusinessOnboardingModel>()
            .Title("Business Financial")
            .ContentUrl(Url.Action("_BusinessFinancial", "Onboard", Model))
            .Buttons(b =>
            {
                b.Previous().Text("Back");
                b.Next().Text("Next");
            });
            s.Add<Reverberate.BLL.Model.Form.Application.BusinessOnboarding.BusinessOnboardingModel>()
            .Title("Business Address")
            .ContentUrl(Url.Action("_BusinessAddress", "Onboard", Model))
            .Buttons(b =>
            {
                b.Previous().Text("Back");
                b.Done().Text("Submit");
            });
        })
    )

<script type="text/javascript">
    var dataPartial1;
    var dataPartial2;
    var currentStep;

    function onSelect(e) {
        var form, contentUrl;
        if (e.step.options.index < currentStep) {
        }
        else {
            if (e.step.options.index == 1) {
                form = $('#frmPartialBusinessProfile');
                dataPartial1 = form.serialize();
                contentUrl = '@Url.Action("_BusinessFinancial", "Onboard",Model)';
            }
            else if (e.step.options.index == 2) {
                form = $('#frmPartial2');
                dataLesions = form.serialize();
                contentUrl = '@Url.Action("_BusinessAddress", "Onboard",Model)';
            }
            if (!form.valid()) {
                e.preventDefault();
            }
            else {
                e.step.options.contentUrl = contentUrl;
            }
        }
        currentStep = e.step.options.index;
    }

    function onNextStep(e) {
        if (e.step.options.index == 2) {
            openDoc();
        }
    }

    function onDone(e) {

        var form = $('#frmMain');

        if (form.valid()) {
            form.submit();
        }

    }

    var onAddMainSuccess = function (result) {

        if (result.error) {
            alert(result.error);
        }
    };

</script>

 

Here is my Onboard controller


using Kendo.Mvc.UI;
using Reverberate.Services;
using Kendo.Mvc.Extensions;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using Reverberate.Model;

namespace CallCenterWebsiteHelper.Controllers
{
    public class OnboardController : Controller
    {
        // GET: Campaign
        private List<SelectListItem> StatesSelectList()
        {
            var slStates = new List<SelectListItem>();
            var states = new Reverberate.BLL.General.StaticDataSet.Geographic().States();
            for (int i = 0; i < states.Count; i++)
                slStates.Add(new SelectListItem() { Text = states[i], Value = states[i] });
            return slStates;
        }
        private List<SelectListItem> BusinessTypesSelectList()
        {
            var sl = new List<SelectListItem>();
            var list = new Reverberate.BLL.General.StaticDataSet.BusinessInformation().BusinessTypeList();
            for (int i = 0; i < list.Count; i++)
                sl.Add(new SelectListItem() { Text = list[i], Value = list[i] });
            return sl;
        }

        public ActionResult Business()
        {
            ViewBag.States = StatesSelectList();
            ViewBag.BusinessTypeList = BusinessTypesSelectList();
            var model = new Reverberate.BLL.Model.Form.Application.BusinessOnboarding.BusinessOnboardingModel();
            model.BusinessProfileModel = new Reverberate.BLL.Model.Form.Application.BusinessOnboarding.BusinessProfileModel();
            model.BusinessFinancialModel = new Reverberate.BLL.Model.Form.Application.BusinessOnboarding.BusinessFinancialModel();
            return View("Business",model);
        }
        public ActionResult _BusinessProfile(Reverberate.BLL.Model.Form.Application.BusinessOnboarding.BusinessOnboardingModel viewModel)
        {
            ViewBag.States = StatesSelectList();
            ViewBag.BusinessTypeList = BusinessTypesSelectList();
            return PartialView("_BusinessProfile",viewModel);
        }
        public ActionResult _BusinessFinancial(Reverberate.BLL.Model.Form.Application.BusinessOnboarding.BusinessOnboardingModel viewModel)
        {
            ViewBag.States = StatesSelectList();
            ViewBag.BusinessTypeList = BusinessTypesSelectList();
            return PartialView("_BusinessFinancial", viewModel);
        }
        public ActionResult _BusinessAddress(Reverberate.BLL.Model.Form.Application.BusinessOnboarding.BusinessOnboardingModel viewModel)
        {
            ViewBag.States = StatesSelectList();
            ViewBag.BusinessTypeList = BusinessTypesSelectList();
            return PartialView("_BusinessAddress", viewModel);
        }
        /*
        public ActionResult BusinessProfile()
        {

            return PartialView("_BusinessProfile");
        }*/
    }
}


 

here is my two partial views

_busiessprofile


@using Kendo.Mvc.UI
@model Reverberate.BLL.Model.Form.Application.BusinessOnboarding.BusinessOnboardingModel
@using (Html.BeginForm(null, null, FormMethod.Post, new { @id = "frmPartialBusinessProfile", @name = "frmPartialBusinessProfile" }))
{
    <div style="width: 45%; float: left; border: 1px solid black" id="BusinessInfoEntry">
        <h3>Business Profile</h3>
        <fieldset>
            <legend></legend>
            <ol>
                <li>
                    @Html.LabelFor(m => m.BusinessProfileModel.BusinessName)
                    <br />
                    @Html.TextBoxFor(m => m.BusinessProfileModel.BusinessName, new { maxlength = 200, @class = "wide" })
                    @Html.ValidationMessageFor(m => m.BusinessProfileModel.BusinessName)
                </li>
                <li>
                    @Html.LabelFor(m => m.BusinessProfileModel.FederalTaxId)
                    <br />
                    @Html.TextBoxFor(m => m.BusinessProfileModel.FederalTaxId, new { maxlength = 20 })
                    @Html.ValidationMessageFor(m => m.BusinessProfileModel.FederalTaxId)
                </li>
                <li>
                    @Html.LabelFor(m => m.BusinessProfileModel.BusinessStartDate)
                    <br />
                    @Html.TextBoxFor(m => m.BusinessProfileModel.BusinessStartDate, new { @type = "date", @class = "form-control datepicker", @Value = Model == null || Model.BusinessProfileModel.BusinessStartDate == null ? null : Model.BusinessProfileModel.BusinessStartDate.ToString("yyyy-MM-dd") })
                    @Html.ValidationMessageFor(m => m.BusinessProfileModel.BusinessStartDate)
                </li>
                <li>
                    @Html.LabelFor(m => m.BusinessProfileModel.Industry)
                    <br />
                    @Html.TextBoxFor(m => m.BusinessProfileModel.Industry, new { maxlength = 200, @class = "wide" })
                    @Html.ValidationMessageFor(m => m.BusinessProfileModel.Industry)
                </li>
                <li>
                    @Html.LabelFor(m => m.BusinessProfileModel.Sector)
                    <br />
                    @Html.TextBoxFor(m => m.BusinessProfileModel.Sector, new { maxlength = 200, @class = "wide" })
                    @Html.ValidationMessageFor(m => m.BusinessProfileModel.Sector)
                </li>
                <li>
                    @Html.LabelFor(m => m.BusinessProfileModel.StateOfFormation)
                    <br />
                    @Html.DropDownListFor(m => m.BusinessProfileModel.StateOfFormation, new SelectList(ViewBag.States, "Value", "Text"), "Select State", htmlAttributes: new { @class = "form-control", id = "StateOfFormationList" })
                    @Html.ValidationMessageFor(m => m.BusinessProfileModel.StateOfFormation)
                </li>
                <li>
                    @Html.LabelFor(m => m.BusinessProfileModel.EmployeeCount)
                    <br />
                    @Html.TextBoxFor(m => m.BusinessProfileModel.EmployeeCount, new { @type = "number", @class = "wide" })
                    @Html.ValidationMessageFor(m => m.BusinessProfileModel.EmployeeCount)
                </li>
                <li>
                    @Html.LabelFor(m => m.BusinessProfileModel.BusinessStructure)
                    <br />
                    @Html.DropDownListFor(m => m.BusinessProfileModel.BusinessStructure, new SelectList(ViewBag.BusinessTypeList, "Value", "Text"), "Select Business Structure", htmlAttributes: new { @class = "form-control", id = "BusinessStructureList" })
                    @Html.ValidationMessageFor(m => m.BusinessProfileModel.BusinessStructure)
                </li>
            </ol>
        </fieldset>
    </div>
}


 

_BusinessFinancial.cshtml


@using Kendo.Mvc.UI
@model Reverberate.BLL.Model.Form.Application.BusinessOnboarding.BusinessOnboardingModel

<h2>Business Financial</h2>
<div style="width: 90%; border: 1px solid silver" id="BusinessInfoEntry">
    <fieldset>
        <legend></legend>
        <ol>
            <li>
                @Html.LabelFor(m => m.BusinessFinancialModel.CreditCardProcessor)
                @Html.TextBoxFor(m => m.BusinessFinancialModel.CreditCardProcessor, new { maxlength = 200, @class = "wide" })
                @Html.ValidationMessageFor(m => m.BusinessFinancialModel.CreditCardProcessor)
            </li>
            <li>
                @Html.LabelFor(m => m.BusinessFinancialModel.CreditCardMonthlyVolume)
                @Html.TextBoxFor(m => m.BusinessFinancialModel.CreditCardMonthlyVolume, new { maxlength = 20 })
                @Html.ValidationMessageFor(m => m.BusinessFinancialModel.CreditCardMonthlyVolume)
            </li>
            <li>
                @Html.LabelFor(m => m.BusinessFinancialModel.GrossMonthlySales)
                @Html.TextBoxFor(m => m.BusinessFinancialModel.GrossMonthlySales, new { @type = "date", @class = "form-control datepicker", @Value = Model == null || Model.BusinessProfileModel.BusinessStartDate == null ? null : Model.BusinessProfileModel.BusinessStartDate.ToString("yyyy-MM-dd") })
                @Html.ValidationMessageFor(m => m.BusinessFinancialModel.GrossMonthlySales)
            </li>
            <li>
                @Html.LabelFor(m => m.BusinessFinancialModel.AnnualRevenue)
                @Html.TextBoxFor(m => m.BusinessFinancialModel.AnnualRevenue, new { maxlength = 200, @class = "wide" })
                @Html.ValidationMessageFor(m => m.BusinessFinancialModel.AnnualRevenue)
            </li>
        </ol>
    </fieldset>
    <br />
</div>

 

 

 

here are the  three models


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Reverberate.BLL.Model.Form.Application.BusinessOnboarding
{
    public class BusinessOnboardingModel
    {
        public BusinessProfileModel BusinessProfileModel { get; set; }

        public BusinessFinancialModel BusinessFinancialModel { get; set; }

    }
}



using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Reverberate.BLL.Model.Form.Application.BusinessOnboarding
{
    public class BusinessProfileModel
    {
        public BusinessProfileModel() { }

        [Required(ErrorMessage = "The business name is required.")]
        [DisplayName("*Business Name")]
        [StringLength(250)]
        public string BusinessName { get; set; }

        [DisplayName("*Federal Tax Id / SSN")]
        [StringLength(15, ErrorMessage = "Please enter a valid federal tax id or SSN")]
        [Required(ErrorMessage = "Please enter the federal tax id or SSN")]
        public string FederalTaxId { get; set; }

       

        [DisplayName("*Business Start Date")]
        [Required(ErrorMessage = "Please enter the business start date")]
        public DateTime BusinessStartDate { get; set; }

        [Required(ErrorMessage = "The industry is required.")]
        [DisplayName("*Industry")]
        [StringLength(500)]
        public string Industry { get; set; }

        [Required(ErrorMessage = "The sector is required.")]
        [DisplayName("*Sector")]
        [StringLength(500)]
        public string Sector { get; set; }


        [DisplayName("*State of Formation")]
        [Validation.InputValidation.ValidState(ErrorMessage = "This does not appear to be a valid US State.")]
        [Required(ErrorMessage = "The State of Formation is required.")]

        public string StateOfFormation { get; set; }
        

        [DisplayName("*No of Employees")]
        [Validation.InputValidation.ValidState(ErrorMessage = "Number of Employees.")]
        [Required(ErrorMessage = "Please Supply the number of employees.")]
        public int EmployeeCount { get; set; }


        [Validation.InputValidation.ValidBusinessType(ErrorMessage = "Please enter a valid business structure")]
        [Required(ErrorMessage = "The business structure required.")]
        [DisplayName("*Business Structure")]
        public string BusinessStructure { get; set; }
    }
}



using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Reverberate.BLL.Model.Form.Application.BusinessOnboarding
{
    public class BusinessProfileModel
    {
        public BusinessProfileModel() { }

        [Required(ErrorMessage = "The business name is required.")]
        [DisplayName("*Business Name")]
        [StringLength(250)]
        public string BusinessName { get; set; }

        [DisplayName("*Federal Tax Id / SSN")]
        [StringLength(15, ErrorMessage = "Please enter a valid federal tax id or SSN")]
        [Required(ErrorMessage = "Please enter the federal tax id or SSN")]
        public string FederalTaxId { get; set; }

       

        [DisplayName("*Business Start Date")]
        [Required(ErrorMessage = "Please enter the business start date")]
        public DateTime BusinessStartDate { get; set; }

        [Required(ErrorMessage = "The industry is required.")]
        [DisplayName("*Industry")]
        [StringLength(500)]
        public string Industry { get; set; }

        [Required(ErrorMessage = "The sector is required.")]
        [DisplayName("*Sector")]
        [StringLength(500)]
        public string Sector { get; set; }


        [DisplayName("*State of Formation")]
        [Validation.InputValidation.ValidState(ErrorMessage = "This does not appear to be a valid US State.")]
        [Required(ErrorMessage = "The State of Formation is required.")]

        public string StateOfFormation { get; set; }
        

        [DisplayName("*No of Employees")]
        [Validation.InputValidation.ValidState(ErrorMessage = "Number of Employees.")]
        [Required(ErrorMessage = "Please Supply the number of employees.")]
        public int EmployeeCount { get; set; }


        [Validation.InputValidation.ValidBusinessType(ErrorMessage = "Please enter a valid business structure")]
        [Required(ErrorMessage = "The business structure required.")]
        [DisplayName("*Business Structure")]
        public string BusinessStructure { get; set; }
    }
}

 


using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Reverberate.BLL.Model.Form.Application.BusinessOnboarding
{
    public class BusinessFinancialModel
    {
        public BusinessFinancialModel() { }

        [DisplayName("Credit Card Processor")]
        [StringLength(250)]
        public string CreditCardProcessor { get; set; }

        [DisplayName("Credit Card Monthly Volume")]
        public decimal CreditCardMonthlyVolume { get; set; }

        [DisplayName("Gross Monthly Sales")]
        public decimal GrossMonthlySales { get; set; }

        [DisplayName("AnnualRevenue")]
        public decimal AnnualRevenue { get; set; }


    }
}

 

As recommend in my other question here: I have created a sample project.   In this project there is an Index.cshtml which has my original structure.  With regards to the index.cshtml there are two things, one - I am not sure why validation doesn't occur on the original page load, I have to reload the page to force page validation and also on the done command there isn't any validation occuring.

 


I created ind.cshtml when I trying the recomemnded solution for the question here: https://www.telerik.com/forums/using-wizard---how-do-you-validate-a-form-when-step-includes-partial-view#5789804 and I am getting `

Severity Code Description Project File Line Suppression State
Error CS1660 Cannot convert lambda expression to type 'string' because it is not a delegate type 6_Views_Home_Index2.cshtml M:\Code\Development\WizardPartialExample\WizardPartialExample\WizardPartialExample\Views\Home\Index2.cshtml 19 Active`

 

 

No answers yet. Maybe you can help?

Tags
Form Wizard
Asked by
Joshua
Top achievements
Rank 1
Share this question
or