I have a webgrid where I would like to add a column where each cell contains a name and an ID, with the name displayed in the cell. I can do this by creating my own class as below, and make each cell element an instance of this class:
private class NameAndID { private string name; private int ID; public NameAndID(string name, int ID) { this.name = name; this.ID = ID; } public override string ToString() { return this.name; } public int getID() { return this.ID; } }
This works server-side because I can use the getID method to retrieve the ID of an element, but how do I get the ID at client-side with javascript? The cell.getValue() javascript method only returns the name! And is this the way to go or can I create a custom column that contains a name and an ID in some other way?
EDIT: I have tried making a hidden column that contains the ID but this doesn't work, because a hidden column is not sorted when the grid is sorted, and therefore the proper IDs are not linked to the proper names after a sort, so I would like to avoid hidden columns!
you can do one thing.
make this column as type="dropdown" and then put ID as value and whatever you want to display as DisplayText.
if you do getValue() it will give you ID if you want text you can use this in javascript.
cell.Element.innerText
I hope this gives answer.
Thanks for your response. I would like to have the cells in the column editable to the user, so the user can enter a new, custom name in each cell. This cannot be done if I use a column with drop-down lists (at least I don't know how). Besides that, your solution was fine. Any other ideas?
I see now, thanks for the clarification. If the hidden ID column is not being sorted along with its corresponding row, as you've described here, then I don't believe that this is functioning correctly.
Whether this is a bug or not may depend on how you're putting the ID of each row into the grid in the first place. If you're basing this off the row's Index, and if you're recreating the rows on every postback, then this is an expected result - the index of the row matches its visual position, and so is changed when you sort.
Additional related questions:
Can you reproduce this behavior in a concise sample application that we can run and debug? If so, then you should submit a support request so that a Developer Support Engineer can investigate this, to better determine if this is a bug - to get it fixed if it is, and to see if we can find a workaround whether it is or isn't a bug. If this turns out to be a likely bug, we'll need you to submit this as a support request anyway.
Vince, thanks for your response. I was a little too quick on posting my problem: After some debugging I found that my problem was not, that the hidden column didn't sort. The problem was instead, that I repopulated the grid before I used the value of the cell in the hidden column. I did this in the following lines in my UpdateCell eventhandler-method:
int rowIndex = e.Cell.Row.Index;SetUpGrid(WebGrid1);int ID = Convert.ToInt32(WebGrid1.Rows[rowIndex].Cells[0].Value);
The home-made SetUpGrid method reloads data to the unbound grid and when you call this method, the original sorting of the grid would be applied.
The reason for me doing the above lines of code is, that the event argument "e" only contains the value of the single cell that has been changed (that is, it doesn't contain the value of the hidden cell in column 0). I checked this by debugging and thereby viewing the value of the e.Cell.Row.Cells property, which only contained the value of the updated cell. Can I, in any way, get the value of the other cells in the row of the updated cell via the event argument without having to reload the grid? And is my explanation to complicated or what? :)
Repopulating or re-binding the grid during an update event is very likely to make updates not function correctly.
Are you using the grid's built-in AJAX functionality? This will make a big difference as to whether or not you can get a reference to other cells in the row, and what suggestions I can provide.
If you're using the grid's AJAX functionality, then only the information about the individual cell updated is available on the server. If you want to access any information about other cells in the same row, you should use the UpdateRow event instead of UpdateCell. If you want updates to be triggered on a cell-by-cell basis anyway (rather than the row-by-row basis that UpdateRow uses), then handle the grid's client-side AfterCellUpdate event:
function UltraWebGrid1_AfterCellUpdateHandler(gridName, cellId){ var cell = igtbl_getCellById(cellId); cell.Row.processUpdateRow();}
If you're not using the grid's AJAX functionality, then you should have all of the row's data available even during UpdateCell. If you need to repopulate or re-bind the grid in this circumstance after the updates are completed, do this in the grid's UpdateGrid event - this event is raised once after all UpdateCell/UpdateRow/AddRow/DeleteRow events (and their batch equivalents) have finished.
As I described above, I had a problem with the data in the other cells in the grid not being available in the UpdateCell event (only the data in the updated cell was available). I discovered however, that the reason of this problem was, that I didn't enable viewstate tracking. The following text from the UltraGridCell help-page describes this:
The most common problem with creating an unbound grid is with cell values not being persisted after postback. This usually happens when viewstate tracking hasn't been turned on for the cell objects. Viewstate can be turned on or off for the cell, row, column and band objects to give fine grained control over how viewstate is tracked by the grid. The viewstate tracking is set by a parameter that is passed to object's constructor.
Now, I'm creating every cell with "new UltraGridCell(true); ", and now all data in the grid is available on update events.
Ahah, good catch. I didn't even consider that one, and this should provide help for others encountering similar problems in the future.
As an additional note, this would also affect any UltraGridRow, UltraGridColumn, or UltraGridBand objects created in code. If you want to use view state, you should always use the contructor overload that takes a boolean as a parameter (and pass in "true" for that parameter) whenever you dynamically create any of these objects.
You might also be able to sidestep the need to dynamically create cell objects altogether, by adding the new row to a Rows collection in your grid first. Doing so causes cells to be created in that row to correspond to each column. These new cells are tracked in view state automatically, at least assuming the row is. In other words:
using Infragistics.WebUI.UltraWebGrid;...UltraGridRow row = new UltraGridRow(true); // track the row in view statethis.ultraGrid1.Rows.Add(row);// You can now access cells in the row object here, without needing to manually create them