db2
db2

Reputation: 517

One <form> for each <tr>

We're building an application in MVC3, and we want to have editable data tables. What we're after is something like this (slightly abridged):

<table class="project-items data-grid">
    foreach (var item in Model.Items) {
        using (Html.BeginForm("SaveItem", "Project", FormMethod.Post)) {
            <tr>
                <td>@Html.TextBox("Title", item.Title) @Html.Hidden("ProjectID", proj.ProjectID) @Html.Hidden("ItemID", item.ItemID)</td>
                <td>@Html.DropDownList("State", item.State.ToSelectList(), "")</td>
                <td>@Html.DropDownList("QuoteID", Model.Quotes.ToSelectList(item.QuoteID), "")</td>
                <td>@Html.TextBox("EstimatedCost", item.EstimatedCost, new { @class = "costfield" })</td>
                <td>@Html.TextBox("VendorEstimatedCost", item.VendorEstimatedCost, new { @class = "costfield" })</td>
                <td>@Html.TextBox("VendorQuotedCost", item.VendorQuotedCost, new { @class = "costfield" })</td>
                <td><input type="submit" value="Save" name="Save"/></td>
            </tr>
        }
    }
</table>

Of course, putting a <form> directly inside a <table> isn't valid HTML; it seems to work in some cases, but in others, it totally freaks out the browser and/or model binder.

What's the safest, cleanest way to do this so that we don't rely on undefined behaviors? I'd like to have something suitable for forms with or without AJAX. I played around with using <div> and display: table-cell tricks, but that prevents the use of colspan, which we also need to do.

Upvotes: 1

Views: 178

Answers (2)

db2
db2

Reputation: 517

Well I've been playing around with it, and it seems like wrapping a <tr> inside a <form> does produce the expected form submission behavior, even if it isn't strictly Kosher HTML, at least with the relatively narrow sample of browsers I tested. I suspect combining this with Jukka's use of the form attribute on controls could provide some assistance to any browsers that mangle the DOM to the point where this doesn't work.

I think this will do for now; it's only an internal-use app, and every other alternative required stupid Javascript stunts, even stupider CSS stunts, or hurting the overall user experience.

Maybe if we all just start doing it, the W3C and browser makers will decide this should be fully supported. ;)

Upvotes: 0

Jukka K. Korpela
Jukka K. Korpela

Reputation: 201728

If your application is intended to run in modern browsers only, you can use the HTML5 form attribute. It lets you associate a control with a form element even when the control is not inside the form element in HTML markup. So you could e.g. use form markup inside the cell that contains the submit button and use form in other controls that are meant to be functionally part of the same form.

Upvotes: 1

Related Questions