Bulk Inserting Data with the ListView Control
I am working on a project that needs a new screen for bulk entry tasks. We have a few business scenarios coming up where we have people inputting 5 to 8 records of data at a time. I met with a few of our analysts last week and hashed out a rough outline of what they were looking for. About 10 times or so during the 30 minute meeting some form of the phrase 'kind of like excel' was mentioned. Our data entry personnel are familiar with excel and our analysts thought an excel styled grid would make a lot of sense. 'An excel grid with a Submit button' was the phrase I had underlined twice in my notes.
I wasn't too worried about the grid's styling, but I wasn't quite sure what the best way to handle the 'bulk insert' requirement. Most of our other grids require an explicit mouse click to insert an item - and often times this click includes navigating the user to a separate page that is made to handle inserts. Of course for mass data entry tasks this can get a little old - tabbing through the cells is much nicer. So I took my notes back to my desk and started building a small prototype. You can check out the live demo to watch the grid in action. And a few of my implementation notes can be found under the screen shots below.
Configuring the ListView
My excel styled grid only has one mode - bulk insert. It would also support mass updating as well, but for our use cases this is a one way data stream. I want to use the ListView because I like how the templates are structured, but the ListView doesn't natively support bulk inserting data (the ListView supports defining an InsertItemTemplate, but the ListView will only render this template once - so this template isn't useful for my scenario). I decided I would try using the regular ItemTemplate, but render elements that support editing instead of the usual read-only controls (i.e. TextBox's instead of Labels). I still use the Bind syntax because I want 2 way databinding, but because I am using the ItemTemplate for an insert scenario I will be responsible for telling the ListView when my data needs to be moved out of the controls and back to my data source. Below is the markup for my ListView.
Setting Up My DataSource
Next, I setup my data source. For this example I am using the ObjectDataSource control. When my data source is first bound to the ListView, I want to render placeholder objects for 8 records (i.e. I want my grid to show 8 empty rows by default). So when my Select method fires, I return a collection that contains 8 Customer objects that have their property values set to their default values (null strings for my example).
Next, I handle the Submit button's click event handler and loop through all of the ListViewDataItems and invoke the ListView's UpdateItem function which will cause the Update method on my ObjectDataSource to fire - moving the data back out from the controls and back into memory. Finally, after the data is moved back to memory, I persist the batch to the database (for the demo I am persisting it to memory, but when this page goes live it will obviously be put in the database).
To make sure I don't persist records with all empty values, I added a validation check to my Customer business object that makes sure the object has at least one data value before the row is submitted. If validation passes, I move the customer data into the database.
Toggling the DataTable's Skin
For a bit of flair I included a couple of radio buttons for changing the grids theme from the default 2003 style excel shown below (found a nice article here on creating this skin) to the 2007 version which is a bit softer (see screen shot at the beginning of the article).
That's it. Enjoy!