Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

MVC - Submit button not working with multiple partial views

I'm new to MVC, so please go easy on me. I was handed a project that was started in MVC and have been told to add to it. I was fine until I got to a section that needed data from two different models. Now I'm stuck and my boss wants this done yesterday. Please help if you can.

I have a view with two partial views and a submit button. Each of the partial views use a different model. The views display information on the screen which the user can change. The submit button is then clicked. In the controller, I would like to access the data from both models (the values that the user entered on the screen). Right now, I can't even get the submit button to call the controller. That is the part I need immediate help with, but I will eventually need to know how to access both model's data from the controller.

Here's the basic idea of what I want to do:

enter image description here

This is my view: CreateContract.cshtml

<div class="container-fluid">
@using (Html.BeginForm("CreateContract", "CreateContract", FormMethod.Post, new { @class = "form-horizontal " }))
{
                <div id="PartialDiv">
            @{
        Html.RenderPartial("ApplicationPartialView", new CarmelFinancialWeb.Models.ModelApplication());
        Html.RenderPartial("ContractPartialView");
            }
        </div>
            <input id="btnCreateContract" type="submit" class="btn btn-primary" value="Save" name="CreateContract" />
}
    </div>

This is part of the controller CreateContractController.cs. This method is hit when the view opens and is working correctly.

        [AuthorizeAdmin]
    public ActionResult CreateContract(string ID)
    {
        ModelContract obj_Contract = new ModelContract();

        obj_Contract.BuyerName = "MOCS";

        return View(@"~/Views/CreateContract/CreateContract.cshtml", obj_Contract);
    }

This is part of the controller CreateContractController.cs. This method is not being hit when the submit button is clicked. I've tried including the string ID variable from the other method and both ModelContract and ModelApplication (and various combinations thereof), but I cannot get this method to be called.

        [AuthorizeAdmin]
    [HttpPost]
    public ActionResult CreateContract()
    {
         ModelApplication obj_App = new ModelApplication();
         return View(@"~/Views/CreateContract/CreateContract.cshtml", obj_App);

    }

These are the methods in the controller for the partial views. These aren't getting called either.

        public PartialViewResult ApplicationPartialView(string ID)
    {
        ModelApplication obj_App = new ModelApplication();

        if (ID != null && ID != "0" && ID != null && ID != "")
        {
            obj_App = objBllApplication.GetApplicationByID(int.Parse(ID));
        }

        return PartialView("CreateContractApplicationPartialView");
    }

    public PartialViewResult ContractContractPartialView()
    {
        ModelContract obj_Contract = new ModelContract();

        obj_Contract.DealerID = "MOCS";

        return PartialView("CreateContractContractPartialView");
    }
like image 720
boilers222 Avatar asked Oct 09 '14 15:10

boilers222


People also ask

Why submit button is not working in MVC?

Solution 1 Begin Form you indicate you are targeting action Login in controller Auth. In the above, Login is your Action and Auth is your controller. Action meaning it is the method of a controller. You need to change the above action from Index to Login and then your code should work (i didn't run it).

Can we return multiple partial views in MVC?

You can only return one value from a function so you can't return multiple partials from one action method. If you are trying to return two models to one view, create a view model that contains both of the models that you want to send, and make your view's model the new ViewModel.

Which function is used to handle multiple submit buttons?

You can very well use helpers such as TextBoxFor() and LabelFor() if you so wish. There are two submit buttons - one with name attribute set to save and the other with name of cancel.


1 Answers

There's a lot going on under the hood here which is beneficial for you to know, especially since you're new to this. First, a view can only have one model. The high-level reason is that it's actually rendered via a generic class that the chosen model fills in as it's type. You can somewhat cheat, as you are here, by using partial views, but you still have to get a model instance into those. It's seems you're trying to do that by creating actions in your controller to represent those partials, but these are effectively useless. They are never being called. Html.Partial or Html.RenderPartial will just render the specified view, either with the same model as the calling view, by default, or the object passed in to those methods as the model (second parameter). It does not go back to the controller.

In MVC, there is something called "child actions" which work as you seem to want partials to here. By using Html.Action or Html.RenderAction instead, you can call this actions on your controller that return partial views. Two things there, though:

  1. If you're going to return a partial view (instead of a full-fledged view), then you should decorate the action with [ChildActionOnly]. Otherwise, the actions are exposed to direct URL access from the browser, which would render the partial view alone, without any layout.

  2. Child actions can only be used for GET-style requests. You can't POST to a child action.

It's actually best for things like this, to only use child actions to render separate areas of a form if those individual areas of the form will be posted to separate locations. Take for example a combo page where you have both a login or signup concept. You can use child actions to render each individual group of fields, but the login portion should POST to a login action and the signup portion should posted to a signup action. You wouldn't POST everything from both forms to the same action.

In your particular scenario, partial views are actually the way to go, but you just need to tweak the model of your main view to be a view model that contains both sub-models. For example:

public class MyAwesomeViewModel // name doesn't matter
{
    public ModelApplication Application { get; set; }
    public ModelContract Contract { get; set; }
}

Then, in your main view:

@model Namespace.To.MyAwesomeViewModel

...

@Html.Partial("ApplicationPartialView", Model.Application)
@Html.Partial("ContractPartialView", Model.Contract)

Finally, your POST action would take this view model as a parameter:

[HttpPost]
public ActionResult CreateContract(MyAwesomeViewModel model)
{
    ...
}
like image 190
Chris Pratt Avatar answered Nov 09 '22 20:11

Chris Pratt