I need to be able to edit a table of data in the browser.
I have seen in MVCContrib there is a HTML helper to render out a table. Useful... but what about if I want the
Take a look at Phil Haack's blog where he describes how to model bind to a list.
Maybe this can help?
I would checkout one of the javascript UI libraries first:
WebForms are easier when it comes to quickly developing rich UI's like editable grids.
Last night I implemented a simple solution: form + table inside, using input fields in the cells with naming convention as described in Phil Haack's blog (thanks to @BengtBe for link).
It's working but its a bit fiddly (e.g. adding rows with jquery requires me to work out the next unused index).
So I am still looking for more solutions.
One I have discovered is the extjs library which provides a very rich grid. I have yet to work out whether there is an easy way to post back the grid data to one of my controller actions yet though...
I've got the same problem, and I have found a solution for it. Don't think it's the most beautiful, but it's ideal for me, because one of my requirements was be able to edit table data using jQuery's Jeditable plugin.
So I generate a table using MVCContrib's Grid<> extension:
Html.Grid<Somenamespace.Line>( Model.InvoiceLines )
.Attributes( id => "InvoiceGrid" )
.Columns( column => {
column.For( li => li.LineItem.ItemDescription ).Attributes( name => ".LineItem.ItemDescription", @class => "click" );
column.For( li => li.LineItem.InvoiceUnitNetPrice ).Named( "Unit net price " ).Attributes( name => ".LineItem.InvoiceUnitNetPrice", @class => "click" );
column.For( li => li.LineItem.InvoiceQuantity ).Attributes( name => ".LineItem.InvoiceQuantity", @class => "click" );
})
.Render();
//rest of the code
Html.Submit("_submit", "Save");
Right now You can edit in place values, but it doesn't upgrade corresponding model. All the magic happens after user clicks submit button:
$(document).ready(function() {
$('#_submit').click(function(e) {
e.preventDefault();
$('#InvoiceGrid tbody tr').each(function(index) {
var hidden = $('<input />').attr({ type: 'hidden', name: 'InvoiceLines.Index', value: index });
$(this).children('td:first-child').before(hidden);
$(this).children('td:not(:first-child)').each(function() {
$(this).append($('<input />').attr({ type: 'hidden', value: $(this).text(), name: 'InvoiceLines[' + index + ']' + $(this).attr('name') }));
});
});
$('form').submit();
});
//editable stuff
$('.click').editable(function(value, settings) {
return (value);
}, { submit: 'OK' });
});
In every TD I create hidden input, with value from that TD, in every row input with Index, and the most important here is 'name' attribute: Name of collection in Model[here goes index].rest.of.path, so in this particular case (example):
InvoiceLines[2].LineItem.ItemDescription
Hope it'll help, because rich grid isn't always an answer ;)
Regards Mateusz