Question

So, I am creating an Admin page that I would like to put multiple forms on. So, I tried doing it using a Partial View and RenderAction.

My Admin Index View:

@model Rad.ViewModels.AdminViewModel
@{
ViewBag.Title = "Admin";
}

<h2>Admin</h2>

<div>
@{ Html.RenderAction("AddProduct"); }
</div>

My Partial View:

@model Rad.ViewModels.AdminAddProductViewModel

@using (Html.BeginForm("AddProduct", "Admin"))
{
<h1>@Html.LabelFor(model => model.Name)</h1>
@Html.TextBoxFor(model => model.Name)
@Html.ValidationMessageFor(model => model.Name)
<input type="submit" value="Add"/>
}

My Admin Controller:

public class AdminController : Controller
{
    //
    // GET: /Admin/
    public ActionResult Index()
    {
        return View();
    }

    public ActionResult AddProduct()
    {
        return PartialView();
    }

    [HttpPost]
    public ActionResult AddProduct(AdminAddProductViewModel data)
    {
        if (ModelState.IsValid)
        {

        }
        return View("Index");
    }
}

The issue is with the HttpPost version of AddProduct. If I keep it as return View("Index"), it gets into an infinite loop. But, if I return PartialView(data), it correctly shows the error, but does not have the Index view around it. So, it only shows the Partial View. Is there a way to have multiple forms on the one page and return the server-side validation to the page?

Was it helpful?

Solution

Ok, I was able to resolve this issue:

Admin Main Index Page:

@model Rad.ViewModels.AdminViewModel
@{
ViewBag.Title = "Admin";
}

<h2>Admin</h2>

<div>
@Html.Partial("AddProduct", Model.AddProduct)
</div>

Add Product Partial View:

@model Rad.ViewModels.AdminAddProductViewModel

@using (Html.BeginForm("AddProduct", "Admin"))
{
<h1>@Html.LabelFor(model => model.Name)</h1>
@Html.TextBoxFor(model => model.Name)
@Html.ValidationMessageFor(model => model.Name)
<input type="submit" value="Add"/>
}

Simple AdminAddProductViewModel:

public class AdminAddProductViewModel
{
    [DisplayName("Add Product:")]
    [Required]
    [StringLength(50)]
    [RegularExpression(@"^[a-zA-Z0-9\s]+$")]
    public string Name { get; set; }
}

Containing AdminViewModel:

public class AdminViewModel
{
    public AdminAddProductViewModel AddProduct { get; set; }

    public AdminViewModel()
    {
        AddProduct = new AdminAddProductViewModel();
    }
}

Admin Controller:

public ActionResult Index()
    {
        AdminViewModel data = new AdminViewModel();
        return View(data);
    }

    [HttpGet]
    public ActionResult Index(AdminViewModel data)
    {
        return View(data);
    }

    [HttpPost]
    public ActionResult AddProduct(AdminAddProductViewModel data)
    {
        AdminViewModel admin = new AdminViewModel();
        admin.AddProduct = data;
        if (ModelState.IsValid)
        {

        }
        return View("Index", admin);
    }

Now, I know I was talking about multiple forms and only show one form here, but if you want to add another form to this, just create another partial view, another sub-viewmodel, and add that sub-viewmodel to the AdminViewModel.

OTHER TIPS

Did you try ajax.beginform()? Name the div around the partial view and set UpdateTargetId to that name.

Then the query will replace the old div.

Don't forget to reference java script libraries for ajax!

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top