0

I am trying to make a small project in mvc4 but I get this problem. I want to make a registration form. The user must fill the first form and when he clicks into next all datas will be sent to an other View within a model called User( without saving in data base) and after he fills at least three available times, it will be register whole information (first and second form).enter image description here

the problem is how to get the data of the first view which is sent to the second view.

class User {
FName
 LName
....
 List<AvailableDate> dts;
 }
Lamloumi Afif
  • 8,941
  • 26
  • 98
  • 191
monther zlatan
  • 156
  • 1
  • 14
  • http://stackoverflow.com/questions/11140502/asp-net-mvc-how-to-pass-data-between-incomplete-forms-wizard – Zaki Jan 30 '14 at 11:23
  • You can save data in session as well. Check this post http://stackoverflow.com/questions/14138872/how-to-use-sessions-in-an-asp-net-mvc-4-application – xurca Jan 30 '14 at 11:42

5 Answers5

1

Since your form will be posted and you have a model, you can forward it to the next view.

[HttpPost]
public ActionResult FirstRegistration(FirstRegistrationModel model)
{
    if (ModelState.IsValid)
    {
        SecondRegistrationModel secondModel = new SecondRegistrationModel();
        MapFirstToSecond(model, secondModel);

        return View("SecondRegistration", secondModel);
    }
    else
    {
        return View(model);
    }
}
Andrei V
  • 7,306
  • 6
  • 44
  • 64
1

One solution would be to pass the Model from the first view, via a post, onto the second view.

e.g.

Say you have a model which represents your form

public class FormOne
{
    property string FName { get; set; }
    property string LName { get; set; }
    property string Location { get; set; }
    property string Login { get; set; }
    property string Password { get; set; }
}

Then on your FormOneView have the form

@using(Html.BeginForm("FormTwoView", "ControllerName")){

@* form inputs which match the FormOne model *@

}

You Post this to your FormTwo view, then pass the object into the view.

public ActionResult FormTwoView(FormOne formOne){

    Return View("FormTwoView", formOne);

}

In your FormTwoView you can tell it to accept the FormOne class

@model Namespace.FormOne

Then within your FormTwoView you can access the properties and values from FormOne

Tim B James
  • 20,084
  • 4
  • 73
  • 103
  • hi James my problem is to get the data of the first form when I click the save in the second form. because when Icick save I just get data (date and duration) – monther zlatan Jan 30 '14 at 12:47
  • You can access all the values from the @Model object on the 2nd form. Output these values into matching hidden inputs, e.g. Then when you post all the values from the second form, you will have all these values. – Tim B James Jan 30 '14 at 12:50
  • An alternate method is just to cache the data from FormOne and then access it from the FormTwo Action. So you could either store the object in the cache, or store it as a session variable. – Tim B James Jan 30 '14 at 13:36
1

As Andrei and Tim mentioned, you can post the data from the first form and pass them to the second form. This will mean that when the second form is submitted, the data from form one and form two should be posted to the action method. There are, however, other options.

You could still post the data to the FirstRegistration action method on POST but this time save it to TempData. Upon posting the second form, you can retrieve the data from TempData. This will remove the need for passing the data from FormOne to FormTwo. More info on TempData on MSDN. Just a word of warning that TempData is shortlived and gets purged right after the subsequent request. So if there is a chance user might make a request between the first and the second one, then the data is gone.

Another option is to use Session. It'll be the same as using TempData but you will decide how long the data can last.

Another option would be the save the data on HTML5 session storage or local storage (supported by all major browsers).

Hossein
  • 1,090
  • 1
  • 8
  • 24
1

Here goes my solution. This is a working sample which will traverse the same user model between steps. It uses Model binding concept. More refinement to code is required, with proper validations, Datatime handling etc. At the end of last step, you should see completed filled model, which you can save it.

Model -

public class User
{
    public string Fname { get; set; }
    public string Lname { get; set; }

    public List<AvailabilityDates> Dates { get; set; }
}

public class AvailabilityDates
{
    public DateTime? date { get; set; }
}

Controller Actions -

public class UserController : Controller
{
    public ActionResult Index()
    {
        User u = new User();
        return View(u);
    }

    public ActionResult FirstStep(User u)
    {
        u.Dates = new List<AvailabilityDates>();
        u.Dates.Add(new AvailabilityDates() { date = null });
        u.Dates.Add(new AvailabilityDates() { date = null });
        return View(u);
    }

    public ActionResult LastStep(User u)
    {
        // Do your stuff here
        return null;
    }
}

Index view -

@model MVC.Controllers.User

@{
    ViewBag.Title = "Index";
}

<h2>Index</h2>

@using (Html.BeginForm("FirstStep", "User", FormMethod.Post))
{

    @Html.LabelFor(model => model.Fname, new { @class = "control-label col-md-2" })
    @Html.EditorFor(model => model.Fname)
    @Html.ValidationMessageFor(model => model.Fname)

    @Html.LabelFor(model => model.Lname, new { @class = "control-label col-md-2" })
    @Html.EditorFor(model => model.Lname)
    @Html.ValidationMessageFor(model => model.Lname)

    <input type="submit" value="Create" class="btn btn-default" />
}

FirstStep View -

@model MVC.Controllers.User

@{
    ViewBag.Title = "FirstStep";
}

<h2>FirstStep</h2>

@using (Html.BeginForm("LastStep", "User", FormMethod.Post))
{
    @Html.HiddenFor(model => model.Fname);
    @Html.HiddenFor(model => model.Lname);

    for (int i = 0; i < Model.Dates.Count; i++)
    {
        @Html.LabelFor(model => Model.Dates[i].date, new { @class = "control-label col-md-2" })
        @Html.EditorFor(model => Model.Dates[i].date)
        @Html.ValidationMessageFor(model => Model.Dates[i].date)
    }
    <input type="submit" value="Create" class="btn btn-default" />
}

Output -

enter image description here

I would also suggest you to look into some JQuery good wizard controls -

ramiramilu
  • 17,044
  • 6
  • 49
  • 66
1

I may use the below logic stores the data in hidden field and submit

public class RegistrationViewModel
{
 public BasicInfo Form1{get;set;}
 public RegistrationInfo Form2{get;set;}
 public string JsonBasicInfo {get;set;}

}

When user fill the first form data, click submit, save the user filled data in JSON format and pass it to another view

public ShowNext(RegistrationViewModel model)
{
  var prevFormData=model.Form1
  model.JsonBasicInfo =JsonConvert.SerializeObject(model.BasicInfo);
  return View("RegistrationInfo", model);  
}

In RegistrationInfo.cshtml

 @model RegistrationViewModel

   @@Html.TextBoxFor(m=>m.Form2.UserName)

   //All registration related html helpers
   @Html.HiddenFor(m=>m.JsonBasicInfo)

Finally when you submit, Registration Form

public ActionResult SaveComplete(RegistrationViewModel model)
{
 model.BasicInfo=JsonConvert.DeserializeObject<BasicInfo>(model.JsonBasicInfo);
 //save whole data
}
Murali Murugesan
  • 22,423
  • 17
  • 73
  • 120