1

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.

db2
  • 497
  • 1
  • 3
  • 21
  • Have you considered using a KendoUI editable grid? – Andrew Walters Aug 26 '13 at 16:59
  • Answers to [Create a HTML table where each TR is a FORM](http://stackoverflow.com/q/4035966/743382) contains two approaches you could combine: put a form around the whole table to make it work without JS, use JS to only submit the current row where possible. –  Aug 26 '13 at 16:59
  • I'm trying to avoid wrapping the whole table in one form, since we'd end up having to do stunts to keep the control names unique, and parse them back out in the action method (which would likely be a lot less elegant than binding the form inputs directly to action method parameters like we're doing now). – db2 Aug 26 '13 at 17:09

2 Answers2

1

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.

Jukka K. Korpela
  • 195,524
  • 37
  • 270
  • 390
  • I like that idea. Our current doctype is XHTML 1.1. Would that need to change? (Along with the necessary XHTML/HTML syntax changes, e.g. empty tags.) – db2 Aug 26 '13 at 17:07
  • @db2, the doctype string has no effect on support to HTML5 features. Either the browser supports them, or it doesn’t. In HTML5, XHTML 1.1 doctype string is even formally allowed as an “obsolete doctype”. Re browser support, seems to be OK in Chrome and Firefox, but not on IE (it only knows `form` as a readonly IDL attribute of a control). – Jukka K. Korpela Aug 26 '13 at 17:30
  • Damn! IE ruins everything again. I'll have to make sure this works in IE; such is life with special-purpose intranet apps. – db2 Aug 26 '13 at 17:54
0

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. ;)

db2
  • 497
  • 1
  • 3
  • 21