Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Separating two forms in the same view in ASP.Net MVC

I've merged the create account view and the log in view in the same view. So it's a view with two forms, but they get mixed when I submit. If I try to log in and there's an error that is displayed with:

Html.ValidationSummary()

both forms get the error. And I started to rename fields to loginPassword, createPassword, because otherwise when I submit and the password is missing, it's marked as missing on both side.

What would be the way to separate these two forms so they can work indenpendently on the same view/page?

like image 325
pupeno Avatar asked Jun 04 '09 20:06

pupeno


2 Answers

Ah yes, I've had to do exactly this before. The way I found was to set a flag in the ViewData detailing which form was posted and then I created my own extension method for ValidationSummary.

The code isn't with me right now so I'll try my best to do some air code for it now, it's obviously just an concept of how to do it so take it at face value.

To start with I would use the same setup as tvanfosson suggested with his 'EntryPageModel'.

View - note Html.MyValidationSummary

<% using(Html.BeginForm("NewAccount", "Account")) %>
<% { %>
    <%= Html.MyValidationSummary("NewAccountForm") %>

    <%= Html.TextBox("NewAccount.FirstName") %>
    <%= Html.TextBox("NewAccount.LastName") %>
    <%= Html.TextBox("NewAccount.Email") %>
    <%= Html.Password("NewAccount.Password") %>
    <%= Html.Password("NewAccount.ConfirmPassword") %>
<% } %>

<% using(Html.BeginForm("Login", "Account")) %>
<% { %>
    <%= Html.MyValidationSummary("LoginForm") %>

    <%= Html.TextBox("Login.Email") %>
    <%= Html.Password("Login.Password") %>
<% } %>

Controller - note ViewData["PostedForm"]

public class Account : Controller
{
    private EntryPageModel _viewModel;

    public ActionResult NewAccount(FormCollection formValues)
    {
        try
        {
            //binding and validation for _viewModel.NewAccount
        }
        catch
        {
            ViewData["PostedForm"] = "NewAccountForm";
            return View("RegisterAndLogin", _viewModel);
        }
    }

    public ActionResult Login(FormCollection formValues)
    {
        try
        {
            //binding and validation for _viewModel.Login
        }
        catch
        {
            ViewData["PostedForm"] = "LoginForm";
            return View("RegisterAndLogin", _viewModel); //You'll want to pass in a model
        }
    }
}

Custom html extension

namespace System.Web.Mvc
{
    public static class HtmlExtensions
    {
        public static string MyValidationSummary(this HtmlHelper html, string formName)
        {
            if (!string.IsNullOrEmpty(html.ViewData["PostedForm"])
                && (html.ViewData["PostedForm"] == formName))
            {
                return html.ValidationSummary();
            }

            return "";
        }
    }
}

HTHs, Charles

like image 73
Charlino Avatar answered Nov 15 '22 10:11

Charlino


I had to deal with the same problem. I found that there is no way to separate the validation messages using the built in ValidationSummary(). Here are two suggestions:

  1. Position the validation summary in an area where it could apply to both forms. For example, if the login and sign up forms are side by side, position the validation summary in a div centered above both forms. I found an example of this style on the Mahalo login page.
  2. In the appropriate controller action methods, add something to the ViewData indicating which action was called. In the view there will be a ValidationSummary for each form, but each will be conditionally rendered based on what you added to the ViewData.

Either way the form fields should be uniquely named.

I went with solution #1 because I was satisfied with the way I was able to get it to look. But if you need the validation summary to appear in two different locations depending on which form was submitted, go with #2.

like image 39
solidbeats Avatar answered Nov 15 '22 10:11

solidbeats