html.netrazorasp.net-mvc-5html.beginform

MVC Razor - form values empty when submitted from outside the form


I building a MVC (Razor) project, and I have a view (ViewA) with a partial view (ViewB) inside. The partial view has a form (@BeginForm)

Here is the form:

@model MT_Contacts.Models.ContactInfo
<table>
    <tr>
        <td style="width: 35%;" colspan="2">
            @if (!string.IsNullOrEmpty(Model?.Name))
            {
                @(Html.Raw(Model.Name))
                <br />
            }
            @if (!string.IsNullOrEmpty(Model?.Address1))
            {
                @(Html.Raw(Model.Address1))
                <br />
            }
            @if (!string.IsNullOrEmpty(Model?.Address2))
            {
                @(Html.Raw(Model.Address2))
                <br />
            }
            @if (!string.IsNullOrEmpty(Model?.Address3))
            {
                @(Html.Raw(Model.Address3))
                <br />
            }
            @if (!string.IsNullOrEmpty(Model?.ZipAndCity))
            {
                @(Html.Raw(Model.ZipAndCity))
                <br />
            }
            @if (!string.IsNullOrEmpty(Model?.Country))
            {
                @(Html.Raw(Model.Country))
                <br />
            }
        </td>
    </tr>
    @if (!string.IsNullOrEmpty(Model?.Phone))
    {
        <tr><td style="width: 35%;">Telefon</td><td>: @Html.Raw(Model.Phone) </td></tr>
    }

    @using (Html.BeginForm("SaveInfoChanges", "ContactInfoBox", FormMethod.Post, new { id = "EditContactInfoForm" }))
    {
        @Html.HiddenFor(model => model.Name)
        @Html.HiddenFor(model => model.Address1)
        @Html.HiddenFor(model => model.Address2)
        @Html.HiddenFor(model => model.ZipAndCity)
        @Html.HiddenFor(model => model.Country)
        @Html.HiddenFor(model => model.Phone)
        <tr>
            <td colspan="2">
                <table>
                    <tr>
                        <td>Address3</td>
                        <td>
                            @Html.TextBoxFor(model => model.Address3, new { placeholder = "test placeholder", style = "width:300px" })
                        </td>
                    </tr>
                    <tr>
                        <td style="text-align: right">
                            <input id="submitbtn" type="submit" value="Save" />
                        </td>
                    </tr>
                </table>
            </td>
        </tr>
    }
</table>

As a test, I am just trying to edit the Address3 property. When using the submit input inside the form, everything works fine. But I need it to be outside the form, in the main view.

In my main view (ViewA) I have tried this:

<input type="submit" value="abc" form="EditContactInfoForm" />

But that appears to do nothing.

I have also tried this (in ViewA):

<td class="boxIcons" id="ContactInfoHeaderAcceptButton" onclick="saveInfoChanges();">
    Save
</td>

Executing this in ViewA:

function saveInfoChanges() {
    $("#EditContactInfoForm").submit();
};

This gets me to the controller:

[HttpPost]
public ActionResult SaveInfoChanges(ContactInfo editedContactInfoResult)
{
    // Do stuff
}

Here, the parameter (editedContactInfoResult) is not null, but is a ContactInfo object with all porperties as null.

I can't seem to find any solution for this. I hope that you can help!

EDIT:

This is the ContactInfo object:

namespace Contacts.Models
{
    public class ContactInfo
    {
        public string Name { get; set; }
        public string Address1 { get; set; }
        public string Address2 { get; set; }
        public string Address3 { get; set; }
        public string ZipAndCity { get; set; }
        public string Country { get; set; }
        public string Phone { get; set; }
    }
}

EDIT 2:

I tried moving the submit buttons from ViewA to the partial view (ViewB). In there, the <input type="submit" value="abc" form="EditContactInfoForm"/> still does nothing. But the saveInfoChanges() works perfectly.

Is there no way that I can move the submit button to ViewA?

EDIT 3:

Main view (ViewA):

@using MT_Contacts.Models
@model ContactInfo

<link rel="stylesheet" type="text/css" href="~/Styles/InfoBoxStyle.css" media="screen" />
<script type="text/javascript" src="~/Scripts/Basic/Tools.js"></script>
<script type="text/javascript" src="~/Scripts/Basic/ContactInfoBox.js"></script>

<div ID="InfoBox">
    <table class="infobox">
        <thead>
            <tr>
                <th>
                    Kontaktinfo
                </th>
                <th id="tester1" style="text-align: right">
                    <table id="HoverButtonTable" style="text-align: right; width: 100%; vertical-align: middle">
                        <tr style="text-align: right">
                            <td style="width: 100%"></td>

                            <td class="boxIcons" id="ContactInfoHeaderEditButton" style="vertical-align: middle; text-align: right; font-size: 10px" onclick="ContactInfoBox.toggleEditMode('1')">
                                L
                            </td>

                            <td class="boxIcons" id="ContactInfoHeaderAcceptButton" style="display: none; vertical-align: middle; text-align: right; font-size: 10px" onclick="saveInfoChanges();">
                                &#xe2a0;
                            </td>
                            <td id="ContactInfoHeaderSpace" style="display: none"> &#160 </td>
                            <td class="boxIcons" id="ContactInfoHeaderCanselButton" style="display: none; vertical-align: middle; text-align: right; font-size: 10px" onclick="ContactInfoBox.toggleEditMode('0');">
                                &#xe262;
                            </td>
                        </tr>
                    </table>
                </th>
            </tr>
        </thead>
        <tbody>
            <tr>
                <td colspan="2" id="contactInfoList">
                    @{ Html.RenderPartial("InfoBoxes/ContactInfoBox/_ContactInfoList", Model);}
                </td>
            </tr>
        </tbody>
    </table>
</div>

Solution

  • Technically, you have illegal code here. The HTML spec does not allow elements such as hidden fields to be inside a table, but outside of a cell. This could also be a contributing factor. I would suggest placing the form outside of the table, as well as the hidden elements (but within the form)

    @using (Html.BeginForm(...)
    {
        <table> 
          ...
        </table>
        @Html.HiddenFor(...)
    }