using System;
using System.Linq;
using System.Web.Mvc;
using Umbraco.Web.Mvc;
namespace My_Site_Core
{
public class ApplicationFormController : SurfaceController
{
[ChildActionOnly]
public ActionResult ApplicationForm(ApplicationModel model)
{
model = model ?? new ApplicationModel();
if (model.Previous)
model.StepIndex--;
if (model.Next)
model.StepIndex++;
return View(model);
}
[HttpPost]
public ActionResult FormSubmit(ApplicationModel model)
{
//ignore validation or saving data when going backwards
if (model.Previous)
return CurrentUmbracoPage();
var validationStep = string.Empty;
switch (model.StepIndex)
{
case 0:
validationStep = "PersonalInfoStep";
break;
case 1:
validationStep = "PersonalStatementStep";
break;
case 2:
validationStep = "WorkExperienceStep";
break;
}
//remove all errors except for the current step
foreach (var key in ModelState.Keys.Where(k => k.StartsWith(string.Format("{0}.", validationStep)) == false))
{
ModelState[key].Errors.Clear();
}
if (!ModelState.IsValid)
{
return CurrentUmbracoPage();
}
//Its the final step, do some saving
if (model.StepIndex == 2)
{
//TODO: Do something with the form data
TempData.Add("CustomMessage", "Your form was successfully submitted at " + DateTime.Now);
return RedirectToCurrentUmbracoPage();
}
return CurrentUmbracoPage();
}
}
}
Model
using System.ComponentModel.DataAnnotations;
namespace My_Site_Core
{
public class ApplicationModel
{
public ApplicationModel()
{
StepIndex = 0;
PersonalInfoStep = new PersonalInfoStep();
PersonalStatementStep = new PersonalStatementStep();
WorkExperienceStep = new WorkExperienceStep();
}
public bool Previous { get; set; }
public bool Next { get; set; }
public int StepIndex { get; set; }
public PersonalInfoStep PersonalInfoStep { get; set; }
public PersonalStatementStep PersonalStatementStep { get; set; }
public WorkExperienceStep WorkExperienceStep { get; set; }
}
public class PersonalInfoStep
{
[Required]
public string Forename { get; set; }
[Required]
public string Surname { get; set; }
[Display(Name = "Preferred Forename")]
public string PreferredForename { get; set; }
[Display(Name = "Preferred Surname")]
public string PreferredSurname { get; set; }
[Required]
//[RegularExpression("[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+.[a-zA-Z0-9-.]+", ErrorMessage = "Not a valid Email")]
public string Email { get; set; }
}
public class PersonalStatementStep
{
public int EventId { get; set; }
public int NumberOfTickets { get; set; }
}
public class WorkExperienceStep
{
[Display(Name = "Final Step Test")]
public string FinalStepTest { get; set; }
}
}
Form Partial
@model My_Site_Core.ApplicationModel
@using My_Site_Core
@if (TempData.ContainsKey("CustomMessage"))
{
<div>Hooray! - @TempData["CustomMessage"]</div>
}
else
{
using (Html.BeginUmbracoForm<ApplicationFormController>("FormSubmit", null, new Dictionary<string, object> { { "id", "ApplicationForm" }, { "class", "application-form" } }, FormMethod.Post))
{
<p>Step is: @Model.StepIndex</p>
switch (Model.StepIndex)
{
case 0:
<h4 class="mb-3">Personal Details</h4>
<div class="form-row">
<div class="col">
@Html.LabelFor(m => Model.PersonalInfoStep.Forename)
@Html.ValidationMessageFor(m => Model.PersonalInfoStep.Forename, "", new { @class = "text-danger" })
@Html.EditorFor(m => Model.PersonalInfoStep.Forename)
</div>
<div class="col">
@Html.LabelFor(m => Model.PersonalInfoStep.Surname)
@Html.ValidationMessageFor(m => Model.PersonalInfoStep.Surname, "", new { @class = "text-danger" })
@Html.EditorFor(m => Model.PersonalInfoStep.Surname)
</div>
</div>
<div class="form-row">
<div class="col match">
@Html.LabelFor(m => Model.PersonalInfoStep.PreferredForename, "Preferred Forename")
<div class="fieldNote">Leave blank if the same as your legal first name.</div>
@Html.ValidationMessageFor(m => Model.PersonalInfoStep.PreferredForename, "", new { @class = "text-danger" })
@Html.EditorFor(m => Model.PersonalInfoStep.PreferredForename)
</div>
<div class="col match">
@Html.LabelFor(m => Model.PersonalInfoStep.PreferredSurname, "Preferred Surname")
<div class="fieldNote">Leave blank if the same as your legal first name.</div>
@Html.ValidationMessageFor(m => Model.PersonalInfoStep.PreferredSurname, "", new { @class = "text-danger" })
@Html.EditorFor(m => Model.PersonalInfoStep.PreferredSurname)
</div>
</div>
<div class="form-row">
<div class="col">
@Html.LabelFor(m => m.PersonalInfoStep.Email)
@Html.ValidationMessageFor(m => Model.PersonalInfoStep.Email, "", new { @class = "text-danger" })
@Html.EditorFor(m => Model.PersonalInfoStep.Email)
</div>
</div>
@Html.EditorFor(x => Model.PersonalStatementStep, "Hidden", "PersonalStatementStep")
//This here is the issue, soemthing about making the values for quesitons in WorkExpecienceStep hidden is killing it. Personal Statement Step works fine
//Issue is nothing to do with buttons
@Html.EditorFor(x => Model.WorkExperienceStep, "Hidden", "WorkExperienceStep")
break;
case 1:
<h4 class="mb-3">Personal Statement</h4>
@Html.LabelFor(m => Model.PersonalStatementStep.EventId)
@Html.EditorFor(m => Model.PersonalStatementStep.EventId)
@Html.ValidationMessageFor(m => Model.PersonalStatementStep.EventId)<br />
<p>see me case 1</p>
@Html.LabelFor(m => Model.PersonalStatementStep.NumberOfTickets)
@Html.EditorFor(m => Model.PersonalStatementStep.NumberOfTickets)
@Html.ValidationMessageFor(m => Model.PersonalStatementStep.NumberOfTickets)
@Html.EditorFor(x => Model.PersonalInfoStep, "Hidden", "PersonalInfoStep")
@Html.EditorFor(x => Model.WorkExperienceStep, "Hidden", "WorkExperienceStep")
break;
case 2:
<h4 class="mb-3">Work Experience</h4>
@Html.LabelFor(m => Model.WorkExperienceStep.FinalStepTest)
@Html.EditorFor(m => Model.WorkExperienceStep.FinalStepTest)
@Html.ValidationMessageFor(m => Model.WorkExperienceStep.FinalStepTest)
@Html.EditorFor(x => Model.PersonalInfoStep, "Hidden", "PersonalInfoStep")
@Html.EditorFor(x => Model.PersonalStatementStep, "Hidden", "PersonalStatementStep")
break;
}
<input type="hidden" name="StepIndex" value="@Model.StepIndex" />
<button type="submit" name="Previous" value="True">Previous</button>
<button type="submit" name="Next" value="True">Next</button>
}
}
And what I am facing, is that upon submitting the first step of the form, the hidden required fields are stopping the form being submitted, as the controller cannot even get to the point where these fields are marked as not required.
If anyone can help me get this working ill be very grateful! :-)
Multi Step Form Implementation
Hi guys, ive been following this post https://umbraco.com/blog/creating-multi-step-forms-using-a-surfacecontroller/ and its going kind of well, but ive hit a hitch now.
I have the following:
Controller:
Model
Form Partial
View
Hidden Fields View
And what I am facing, is that upon submitting the first step of the form, the hidden required fields are stopping the form being submitted, as the controller cannot even get to the point where these fields are marked as not required.
If anyone can help me get this working ill be very grateful! :-)
Kieron, peace be upon those who follow guidance.
I was able to go through the 3 steps form successfully and got the final message by using your code and made some changes.
Changes:
@Html.Action("ShowOrderForm", "ApplicationForm")
.ApplicationForm
in the controller toShowOrderForm
to allow post hit the function again by using .Partial won't.Thanks for looking! I wasn't too far away by the looks of it! :-D
Appreciate the help.
is working on a reply...