arame3333
arame3333

Reputation: 10193

Trying to figure out Ajax.BeginForm

I have a view in 2 sections. The top section I input fields and submit to save them. In the second section I have an autocomplete textbox. I select an item in autocomplete, and when I click submit I want to add that item to a datatable. So for the first part when I click submit I save the details via a HttpPost method on the controller. For the second part I intend to save it via an Ajax call for the controller and then bring back a partial view with the results. I have not coded the partial view yet, that is next. Now I am new to Ajax.BeginForm and I am struggling with it. I was hoping that the submit button inside the Ajax.BeginForm would only apply to that part of the form. But in fact it calls the HttpPost method for the whole form. So how do I fix this? My view looks like;

@using ITOF.HtmlHelpers
@model ITOF.Models.OngoingContractViewModel
@{
    ViewBag.Title = "EditOngoingContractDetails";
    Layout = "~/Views/Shared/_Layout.cshtml";
}
    @using (Html.BeginForm("EditOngoingContractDetails", "Contract", FormMethod.Post,
         new { enctype = "multipart/form-data" }))
    {
        @Html.ValidationSummary(true)
        @Html.HiddenFor(model => model.Contract.ContractId)
        <h1>Edit Ongoing Contract Details</h1>
        <fieldset>
            <legend>@Model.Contract.Heading</legend>
            <p>Where you see <span class="error">*</span> you must enter data.</p>
            <table>
                <tr>
                    <td style="text-align: right">
                        @Html.LabelFor(model => model.Contract.EndDate)
                    </td>                    
                    <td>
                        @Html.EditorFor(model => model.Contract.EndDate)
                    </td>
                </tr>
                <tr>
                    <td style="text-align: right">
                        @Html.LabelFor(model => model.Contract.Organogramme)    
                    </td>
                    <td>
                        <input type="file" id="PDF" name="file" />
                        @Html.HiddenFor(model => model.Contract.Organogramme)
                    </td>
                </tr>
                @if (!string.IsNullOrWhiteSpace(Model.Contract.Organogramme))
                {
                    <tr>
                        <td></td>
                        <td>
                            The current organogramme is <span class="HighlightTextRed">@Model.GetOrganogrammeName()</span> 
                            for the contract <span class="HighlightTextRed">@Model.Contract.ContractName</span><br/>
                            <a href="@Model.Contract.Organogramme" target="_blank">Click here to see the last saved organogramme</a> 
                        </td>
                    </tr>
                }
                <tr>
                    <td style="text-align: right">
                        @Html.LabelFor(model => model.Contract.AssistantRLOManagerId)
                    </td>                    
                    <td>
                        @Html.DropDownListFor(model => model.Contract.AssistantRLOManagerId, Model.AssistantRloManagerSelectList, "--N/A--")
                    </td>                   
                </tr>
                @if (this.TempData["SuccessMessage"] != null)
                {
                    <tr>
                        <td colspan="2" class="success">@this.TempData["SuccessMessage"].ToString()</td>
                    </tr>
                }
                <tr>
                    <td colspan="2" style="padding-top: 20px; text-align: center;"><input type="submit" value="Save" /></td>
                </tr>
            </table>
        </fieldset>


        <fieldset>
            <legend>Add an existing Site to this contract: </legend>
            @using (Ajax.BeginForm("AddExistingSite", new AjaxOptions { UpdateTargetId = "siteRows" }))
            {

                <input type="text" name="q" style="width: 800px" 
                       data-autocomplete="@Url.Action("SiteSearch", "DataService", new { contractId = @Model.Contract.ContractId })" />
                <input type="submit" value="Add site to contract" />
            }

            @if (Model.SiteList.Count > 0)
            {
                <table id="siteDataTable" class="display">
                    <thead>
                        <tr>
                            <th>Main Site?</th>
                            <th>Type</th>
                            <th>Address</th>
                            <th>Map</th>
                            <th>Telephone</th>
                            <th>Email</th>
                        </tr>
                    </thead>
                    <tbody id="siteRows">
                        @foreach (var item in Model.SiteList)
                        {
                            <tr id="@item.SiteContract.SiteContractId">
                                <td>@item.SiteContract.MainSiteFlag</td>
                                <td>@item.Site.SiteType</td>
                                <td>@item.Site.Address</td>
                                <td>@item.Site.MapUrl</td>
                                <td>@item.Site.Telephone</td>
                                <td>@item.Site.Email</td>
                            </tr>
                        }
                    </tbody>
                </table>
                <div class="add_delete_toolbar" />
            }
            @Html.ListLink("Back to List") 
        </fieldset>
    }

Upvotes: 0

Views: 518

Answers (1)

Darin Dimitrov
Darin Dimitrov

Reputation: 1038730

Oh no, you just cannot nest HTML forms. That's not supported. You will have to rethink your design. This really has absolutely nothing to do with ASP.NET MVC and things like Html.BeginForm or Ajax.BeginForm. The HTML specification simply tells you that the <form> tag cannot be nested and if you nest it you will get undefined behavior that could vary between browsers.

For example you could implement the autocomplete functionality using jquery UI autocomplete plugin and get rid of the Ajax.BeginForm.

Upvotes: 1

Related Questions