I have a GridView that allows editing the values in every column, in every row, all the time. The user enters in all their changes, clicks Save once and all changes are commited.
The user must also be able to click the New button, have a new row appear in the GridView (yep, it has to show up in the actual GridView), enter whatever data they want, click Save and have all changes go to the database.
Now. Here's the user case that's throwing me: a user arrives at the page, makes several changes on several existing rows, and then needs to add a new row, enter data in the new row, click Save, and have all changes go to the database.
However, the only ways I've seen to add a new, empty row involve rebinding the GridView, which means all of their changes will be lost. This is obviously no good.
So, my question would be: what are some approaches to adding a new, empty, editable row to a GridView without having to rebind the GridView?
The only thing I can think of would be, on the New buttons' click event, suck all the data out of the GridView (including the user's potential edits), save it to ViewState (or whatever), add the new row, repopulate the grid. This, to me, seems a little hacky, but it should allow me to turn ViewState off on the GridView.
Any ideas?
Just off my head I can think of two options. The first is to cache the original results that you are binding into the grid and when you need to add another row you add a datarow to the datatabale that you are binding to and then bind this to the grid. If there are changes in the grid then you need to update the datatable. Once all changes have been made and the user clicks the save button you can iterate through the table and update the DB with the data.
It might look like this
Page Loads
Get DB Data and put into a table
Bind the table to the grid
Store the table in a cache
When user asks for a new row
Get the cached data object.
Update any rows that have changed
Add an empty row Bind to the grid
When the user saves the grid
Get the cached object.
Make last set of updates
Loop through the row and update the DB
The other way to do this is by creating the grid dynamically but this will involve far more effort than it's worth given what you have described.
You could dynamically add the new row via javascript, and on the save command look for newly added rows. That is fairly common.
Related
I an looking for a way to change asp.net gridview row in EDIT mode based on primary key of the data and not based on the row number clicked on the gridview.
What are the options.
I'd probably have a hidden column in the GridView that contains the PK. When the edit button is clicked, you can use the appropriate handler to get the PK from that row and manipulate it as you see fit.
Update: After reading your comment, it's not that you can't get the PK, it's that the data has been refreshed between when the button is clicked and when the gridview is re-rendered as editable. In your scenario, a user could click the third row to edit and suddenly it becomes the seventh row because other users have inserted four rows.
The simple answer is don't do that! For one, it'll make your life a lot harder and 2) it'll be confusing for a user if they clicked the third row to edit and suddenly it's the seventh row on their screen.
If for whatever reason you MUST refresh the data, do it after the user commits their changes. If you need to refresh the data to make sure that some other user didn't edit the values before the user updates them, well, you're going to have to find another solution. maybe a parent/detail screen would work or add a pop-up that says that the data has been changed. (Remember that if the values suddenly change without warning that the user will be confused as well.)
I have a bit of a unique problem. I am using a GridView to display information from a database. The requirements for this GridView are that it is always editable so I have TextBoxes in the ItemTemplates and want to save the values when a button is clicked.
That all works great.
The problem is I am trying to get sorting (and eventually paging) working and hitting problems. If I bind the GridView from an ObjectDataSource this obviously doesn't work because it rebinds the datasource before it sorts and I lose any modified values. If I bind the GridView from a DataTable and try to store it in a Session variable it still doesn't work because any modified values aren't in the session variable.
I'm really just looking for suggestions on what I could possibly do to sort (and page later) without losing values the user has modified. I realize most people don't modify the Gridview all at once so its a weird problem.
You could implement client-side sorting of the GridView which would have the added benefit of making your UI feel faster. There is a blog post on sorting with jQuery you could try, though I have not personally used the method suggested.
Alternatively, you could send the values back to the server via AJAX while editing and save them (temporarily) in the session, the database, or where it makes the post sense in your scenario. You would obviously need to retrieve them when sorting.
One final option would be to save your values on the postback caused by the sort command. Mostly you would do something along the lines of handling the OnTextChanged event of the TextBoxes and (as above) saving the values to a temporary store. You would not want these TextBoxes to autopostback - they would simply wait for a postback such as the one caused by your sorting event. In this scenario you could also use the temporary store you populate during the save event to avoid duplicating the effort.
I want to do something really simple, I just can't seem to find the EnableClientAddRow property, so I can set it to true. I have a standard GridView control on a web form. I want a button to appear on the web form. When the user clicks the button, an empty row is added to the GridView UI, so the user can enter data in the appropriate fields. The row will of course, have a "Save" button of some type in one of the columns.
I know this functionality must be in the GridView somewhere, I just can't find it. I did find some odd hacks that try to manually implement this. I'm not really interested in footer manipulations or binding tricks, just the standard add row method.
EDIT:
It appears the GridView does not support adding a row as a first-order operation. This appears to be a serious design flaw.
I typically add a new record to the underlying data source as a part of the "add record" button click action. I then re-bind the view in order to show the blank row.
The new record is typically a DataRow if the GridView is bound to a DataTable, or an object if the GridView is bound to a collection of a particular type. Not sure if that is what you consider a binding trick from your question, but it works well and is quite easy to implement.
Edit - more detail to describe the process:
Add the row to the data source, set the EditItemIndex to the newly added row in order for the row to enter edit mode, then bind the data source to the GridView. Your EditItemTemplate would contain a Cancel and a Save button. Cancel would re-bind the GridView to the underlying data source without the empty row and set EditItemIndex to -1, thereby removing the row from the GridView.
How to easily insert row in GridView with SqlDataSource
If you add a new row to the datasource, even if the row has empty values, and you databind the datasource to the Gridview, it should show up as an editable row just like any of the other rows.
I have a gridview full of telephone numbers. To populate the gridview I bind the gridview's datasource to a List<> of telephone numbers. I do this when the page is first loaded, but not on postbacks.
I want the user to be able to delete some of the telephone numbers, and then, if they want, click a Save button, and this will update the database, otherwise their changes will be ignored. So I have a button in the grid, and an event is fired, and I can call DeleteRow(row index) and remove the row from inside this event. For some reason this doesn't work.
All the gridview examples I find on the Internet execute the delete straight away by calling an sql function, and then bind again. And some examples bind the grid every time the page ios loaded, which seems inefficient.
My questions is:
The delete button causes a postback to the server. On postback the list of telephone numbers no longer exists. And the gridview's datasource is null. The grid is no longer bound. But there must be data somewhere, because the data in the grid is still visiable. Where is this data, and can I delete a row of it, so that a row in the gridview is deleted?
The viewstate saves the contents of the datagrid, so the answer is "The Viewstate"
Understanding the viewstate is essential to understanding how ASP.NET works, so rather than posting just enough info to answer your question, I'm going to recommend you read the entire article I linked to.
You can use jquery , you need to save the Datakey value of each deleted row in a hidden field
and hide the selected row , and when user clicks save , u can delete the rows based on hidden field values # code behind.
I have a database with 2 records Id and Description.
What I want to do is try to bind this to a table so for example
<tr>
<drop down select list with ids available> <textbox>
</tr> <add button>
So the user can select an id from the drop down list, enter a description then click an add button next to this which will duplicate that block dynamically so they can enter as many as they like. What is the best way to go about this in webforms? Detailsview? I'm not sure how to make it dynamically add html blocks though? Any help would be appreciated.
pseudocode :
foreach description
create new tablerow
create a table cell in the row with the description as a label
create a table cell in the row with the id dropdown as a combobox
add the tablerow to the table.rows collection
the tricky part is accessing the data in your dynamically created table, but it shouldn't be hard to do as long as you set an identifier on each control that can be tied back to your data.
I'd stay away from any of the built in controls (i.e. DetailsView, FormView) for anything other than simple CRUD forms, as it's not much more effort to manually create your own data-entry forms.
Dynamically adding controls to an ASP.NET Webform (and have them work across postbacks) is quite a tricky one to get right, but in short you'll need to do something like:
Add a table server control which will store your dynamic rows.
Create a property (stored in ViewState or ControlState) to store a count of rows available.
Handle the appropriate 'add' button click event, to increment the count property and add a new table row, and child controls.
Inside an OnInit event, create the number of table rows stored in the count property.
Dynamically created controls aren't persisted across postbacks, so you'll need to create them on every postback during the pages OnInit method. As long as the controls are recreated in the right order and with the same ID's, then they will be repopulated successfully on postback.
Because you're dynamically adding controls, you may need to set the pages EnableEventValidation property to false.