When the user picks a row to edit and clicks the edit button, it seems that the grid says "Edit the 5th item in the grid". Of course, during the AJAX postback, the grid loads completely different data, and the record they want to edit is now the 9th item.
Is there any way to have the grid say "Edit item with a key value of 34832" instead of being positional? The only other solution I've come up with is to cache the grid data in session, and if the grid gets an edit command, reload from the cache instead of the database. I'm going to go try to implement that now.
28 Answers, 1 is accepted
You mentioned that there are ajax requests on the page which change the grid data. Do you also have a setting where the AJAX initiator updates the grid control? If so, one option is to rebind the grid on callbacks from the initiator control.
If not, you can try by trapping the Edit command in RadGrid by wiring the ItemCommand event of the control. Then cancel the default command and put in edit mode the "correct" row. This could be done by finding it (using its DataKeyValue) and adding its index to the EditIndexes of the RadGrid control.
Regards,
Tsvetina
the Telerik team
Can you provide an example of how to fix this.
Thanks.
Have you tried the suggestions from the previous post and what are the results? What else apart from the grid itself refreshes its datasource? You could add an Ajax setting where the control in question refreshes the grid and if this other control is not the grid itself, access the RadGrid instance and rebind it.
Greetings,
Tsvetina
the Telerik team
Browse the vast support resources we have to jump start your development with RadControls for ASP.NET AJAX. See how to integrate our AJAX controls seamlessly in SharePoint 2007/2010 visiting our common SharePoint portal.
There is no other control that is refreshing the datasource of the grid. Basically what is happening is, if I have the page with the grid open and someone else adds a record to the datasource, when I click "Edit" the grid refreshes the source, I see the new row at the 0 index position, but now I am not editing the row I clicked on.
What I ended up doing was caching the data for the grid, and using the cached data if they were going into edit mode, using the NeedDataSource method. It's a bit clumsy, and it will use up some memory on the web server, but it was the only way I could get it to work.
In the GridView_ItemCommand method, I did...
if
(e.CommandName ==
"Cancel"
) {
Session.Remove(
"CommandArgument"
);
return
;
}
if
(e.CommandName ==
"Edit"
) {
Session[
"CommandArgument"
] = e.CommandArgument;
return
;
}
In the GridView_NeedDataSource method...
protected
void
GridView1_NeedDataSource(
object
source, Telerik.Web.UI.GridNeedDataSourceEventArgs e) {
DataSet data;
if
(Session[
"CommandArgument"
] ==
null
) {
// Fill your data into the dataset here...
Session[
"GridData"
] = data;
// Here's where we cache it...
}
else
{
data = (DataSet)Session[
"GridData"
];
// They must be going into edit mode - fill from the cache instead
}
GridView1.DataSource = data.Tables[1];
}
When they leave edit mode, we also need to clear the command argument. This should go at the end of your GridView_Update method...
Session.Remove(
"CommandArgument"
);
To be safe, I also included that line in the Page_Load method - when they first enter the page, they shouldn't be in edit mode.
Like I said, somewhat clumsy, but it does work. As long as they aren't in edit mode, they should get fresh data from the database. When they click the edit button, it will use the previous query results, and the edited row will match the one they intended to edit.
Could you explain this with a code snippet. Not sure if I understood this.
Assuming you have accessed and passed to the server the key value of the item you clicked to put the grid in edit mode, you can use code like this:
protected
void
RadGrid1_ItemCommand(
object
sender, GridCommandEventArgs e)
{
if
(e.CommandName == RadGrid.EditCommandName)
{
e.Canceled =
true
;
int
index = RadGrid1.MasterTableView.FindItemByKeyValue(keyValue).ItemIndex;
RadGrid1.EditIndexes.Add(index);
RadGrid1.Rebind();
}
}
Regards,
Tsvetina
the Telerik team
Tsvetine,
I tried below code and I'm getting an error 'Object reference not set to instance of an object' on this line
Dim index As Integer = RadGrid1.MasterTableView.FindItemByKeyValue("Trip_ID", tripID).ItemIndex
The value of tripID is "61151" and its not null.
If e.CommandName = RadGrid.EditCommandName Then
Dim item As GridDataItem = CType(e.Item, GridDataItem)
Dim tripID As String = item.GetDataKeyValue("Trip_ID").ToString
e.Canceled = True
Dim index As Integer = RadGrid1.MasterTableView.FindItemByKeyValue("Trip_ID", tripID).ItemIndex
RadGrid1.EditIndexes.Add(index)
RadGrid1.Rebind()
End If
Could you please try casting the value into the tripID variable to the type of the Trip_ID column. For example if the Trip_ID column is integer you need to use following code:
Dim
index
As
Integer
= RadGrid1.MasterTableView.FindItemByKeyValue(
"Trip_ID"
,
CType
(tripID,
Integer
)).ItemIndex
Please give it try and let me know if it helps you. Looking forward for your reply.
Greetings,
Radoslav
the Telerik team
In which event should I get the DataKeyValue?
To achieve the desired functionality you need to execute the described code into the RadGrid.ItemCommand event:
Protected
Sub
RadGrid1_ItemCommand(sender
As
Object
, e
As
Telerik.Web.UI.GridCommandEventArgs)
Handles
RadGrid1.ItemCommand
If
e.CommandName = RadGrid.EditCommandName
Then
Dim
item
As
GridDataItem =
CType
(e.Item, GridDataItem)
Dim
tripID
As
String
= item.GetDataKeyValue(
"Trip_ID"
).ToString()
e.Canceled =
True
Dim
index
As
Integer
= RadGrid1.MasterTableView.FindItemByKeyValue(
"Trip_ID"
,
CType
(tripID,
Integer
)).ItemIndex
RadGrid1.EditIndexes.Add(index)
RadGrid1.Rebind()
End
If
End
Sub
<
MasterTableView
DataKeyNames
=
"Trip_ID"
></
MasterTableView
>
Additionally I am sending you a simple example. Please check it out and let me know if it helps you.
Kind regards,
Radoslav
the Telerik team
I've already tried the code that you have suggested. It is getting the Trip_ID of the wrong record when another user insert a record into the table.
Please see my previous posts.
Thank you!!
Dim
item
As
GridDataItem =
CType
(e.Item, GridDataItem)
If item is not null, and is the correct item, I'm not sure why the RadGrid's normal edit command wouldn't put the correct item in edit mode. What happens if you don't have any code in the ItemCommand event for Edit? Does the wrong item still get placed in edit mode?
You may also try setting item.Edit = true and then rebinding the RadGrid after canceling the event, if it still isn't working:
Protected
Sub
RadGrid1_ItemCommand(sender
As
Object
, e
As
Telerik.Web.UI.GridCommandEventArgs)
Handles
RadGrid1.ItemCommand
If
e.CommandName = RadGrid.EditCommandName
Then
Dim
item
As
GridDataItem =
CType
(e.Item, GridDataItem)
e.Canceled =
True
item.Edit = true;
RadGrid1.Rebind()
End
If
End
Sub
I hope this helps!
Casey
I tried to reproduce the described issue but to no avail. In my previous post I attached a small example which demonstrates the desired functionality. Could you please check it out and let me know what differs in your case. Additionally based on the provided information it is hard to say what is causing the described issue on your end. Could you please send us a small runnable example which demonstrates it. You could open a formal support ticket from your Telerik account and attach a ZIP file there. Thus we will be able to debug the project and provide you with more to-the-point answer.
Looking forward for your reply.
Kind regards,
Radoslav
the Telerik team
I do not know if this has already been solved through support tickets or such, but I'm suffering from the same issue than Jagat and would really like to hear if you found a solution or workaround for the problem?
Here's my way of explaining the problem. We use RadGrid with ViewState DISABLED which causes the NeedDataSource event to trigger before ItemCommand event. Therefore if a row/rows are deleted from the datasource by some other user AFTER you have loaded the page contaning the grid, it will not open the correct row for editing in all cases.
Consider the following scenario:
1. You load the page and get 5 rows in the grid.
2. Some other user deletes the first row (with index 0) from the datasource (Database table or whatever).
3. You edit the third row (with index 2). The NeedDataSource retrieves the remaining FOUR rows from the datasource and in ItemCommand the row with the index 2 in the refreshed DataTable is processed (put to edit mode etc).
4. This causes the wrong row to be edited, since the row with the index 2 is no longer the row that You selected, but the fourth row of the orignal grid you saw instead.
See the problem? This can actually be reproduced with the sample code Radoslav provided by setting the ViewStateEnabled="false" on the Default.aspx page and by deleting a row from the table at the end of the NeedDataSource in debugging mode.
To do this, start in debugging mode and set a breakpoint at the end of the RadGrdi1_NeedDataSource method. Then edit the fifth row and when the breakpoint is hit, delete the first row from the DataTable called table by using the immediate Window in visual Studio. Then run the rest of the code (press F5) and you should see that it's the GroupState6 that is edited instead of GroupState5.
So, the problem is the index aproach the grid uses. IMO it really should rely on some unique data keys instead. I haven't figured out yet if that is somehow possible or how should we go around this issue.
Thanks in advance for any help!
Best regards,
Tommi
Dim
item
As
GridDataItem =
CType
(e.Item, GridDataItem)
is not returning the correct item in my case since the GridCommandEventArgs in ItemCommand gives you the item with the original selected index in the refreshed DataTable. See my previous post.....
That makes sense in your scenario since the RadGrid is rebinding and returning a different number of rows than before.
You could try setting some global variable(s) in the EditCommand of the RadGrid and then canceling the event and rebinding the grid. Then in the ItemDataBound, if the text for the column(s) match the global variable(s) then you can place that item in Edit mode, clear out the global variable(s) and rebind the RadGrid.
I hope this helps!
Casey
string
value1 =
""
;
protected
void
RadGrid1_ItemCommand(
object
sender, GridCommandEventArgs e)
{
if
(e.CommandName ==
"Edit"
)
{
GridDataItem dataItem = (GridDataItem)e.Item;
value1 = dataItem[
"UniqueName1"
].Text;
e.Canceled =
true
;
RadGrid1.Rebind();
}
}
protected
void
RadGrid1_ItemDataBound(
object
sender, GridItemEventArgs e)
{
if
(e.Item
is
GridDataItem)
{
GridDataItem dataItem = (GridDataItem)e.Item;
if
(dataItem[
"UniqueName1"
].Text == value1)
{
dataItem.Edit =
true
;
value1 =
""
;
RadGrid1.Rebind();
}
}
}
I don't see how your suggestion would make it different, since the e.Item is still the wrong item as the NeedDataSource has been executed before Itemcommand and a different number of rows has been returned as you mentioned?
Doesn't the code you posted just take the value (from the wrong item), stores it and then makes it editable in ItemCommand?
Or am I missing something relevant?
Have you thought about putting the item in edit mode using the client event instead of server side event?
I've resolved this issue..
Instead of using GridEditCommand, I've used GridTemplateColumn to edit the records.
When edit button is clicked call the Javascipt function (GetTripID()) to save the DataKeyValue into a hiddenfield.
Now use this value in the hiddenfield to put the record in edit mode.
<
telerik:GridTemplateColumn
HeaderText
=
"Edit"
UniqueName
=
"Edit"
>
<
EditItemTemplate
>
<
asp:ImageButton
ID
=
"ibtnUpdate"
runat
=
"server"
tooltip
=
"Update"
OnClick
=
"ibtnUpdate_Click"
ImageUrl
=
"~/Images/Grid/Update.gif"
/>
<
asp:ImageButton
ID
=
"ibtnCancel"
runat
=
"server"
tooltip
=
"Cancel"
OnClick
=
"ibtnCancel_Click"
ImageUrl
=
"~/Images/Grid/Cancel.gif"
/>
</
EditItemTemplate
>
<
ItemTemplate
>
<
asp:ImageButton
ID
=
"ibtnEdit"
runat
=
"server"
tooltip
=
"Edit"
OnClick
=
"ibtnEdit_Click"
ImageUrl
=
"~/Images/Grid/Edit.gif"
/>
</
ItemTemplate
>
<
HeaderStyle
Width
=
"50px"
/>
</
telerik:GridTemplateColumn
>
Protected
Sub
ibtnEdit_Click(
ByVal
sender
As
Object
,
ByVal
e
As
EventArgs)
Dim
index
As
Integer
= -1
' BindDispatchRadGrid()
RadGrid1.Rebind()
'Dim tripID As String = RadGrid1.Items(2).GetDataKeyValue("Trip_ID").ToString
Dim
tripID
As
String
= hidTripID.Value
Try
index = RadGrid1.MasterTableView.FindItemByKeyValue(
"Trip_ID"
,
CType
(tripID,
Integer
)).ItemIndex
Catch
RadAjaxManager1.Alert(
"The trip you are trying to edit has moved to another page. <br/> Please find the trip and try again."
)
Exit
Sub
End
Try
Dim
row
As
GridEditableItem =
CType
(RadGrid1.Items(index), GridEditableItem)
ObjSchedules.SaveSelectedValuesOfDDLinEditMode(row)
ObjSchedules.Dispatch =
DirectCast
(row.FindControl(
"lblDisp"
), Label).Text.ToString.Trim
RadGrid1.EditIndexes.Add(index)
RadGrid1.Rebind()
End
Sub
Protected
Sub
ibtnUpdate_Click(
ByVal
sender
As
Object
,
ByVal
e
As
EventArgs)
Dim
tripID
As
String
= hidTripID.value
Dim
index
As
Integer
= RadGrid1.MasterTableView.FindItemByKeyValue(
"Trip_ID"
,
CType
(tripID,
Integer
)).ItemIndex
Dim
row
As
GridEditableItem =
CType
(RadGrid1.Items(index), GridEditableItem)
UpdateSchedules(row)
RadGrid1.EditIndexes.Clear()
' BindDispatchRadGrid()
RadGrid1.Rebind()
End
Sub
Protected
Sub
ibtnCancel_Click(
ByVal
sender
As
Object
,
ByVal
e
As
EventArgs)
RadGrid1.EditIndexes.Clear()
'BindDispatchRadGrid()
RadGrid1.Rebind()
End
Sub
Protected
Sub
RadGrid1_SortCommand(
ByVal
sender
As
Object
,
ByVal
e
As
Telerik.Web.UI.GridSortCommandEventArgs)
Handles
RadGrid1.SortCommand
'Dim expression1 As New GridSortExpressionCollection
MySortExpression = e.SortExpression
Select
Case
(e.NewSortOrder)
Case
GridSortOrder.Ascending
MySortDirection =
"ASC"
Case
GridSortOrder.Descending
MySortDirection =
"DESC"
Case
GridSortOrder.None
MySortExpression =
"Route, Pickup_Time"
End
Select
End
Sub
Private Sub RadGrid1_ItemCreated(ByVal sender As Object, ByVal e As Telerik.Web.UI.GridItemEventArgs) Handles RadGrid1.ItemCreated
If TypeOf e.Item Is GridDataItem Then
Dim dataItem As GridDataItem = CType(e.Item, GridDataItem)
'Dim btnEdit As Button = DirectCast(dataItem("Edit").Controls(1), Button)
Dim ibtnEdit As ImageButton = DirectCast(dataItem("Edit").Controls(1), ImageButton)
ibtnEdit.Attributes.Add("onClick", "GetTripID(" & dataItem.ItemIndex & "); ")
End If
End Sub
function
GetTripID(itemIndex) {
var
grid = $find(
"<%=RadGrid1.ClientID %>"
);
var
MasterTable = grid.get_masterTableView();
var
row = MasterTable.get_dataItems()[itemIndex];
var
cell = MasterTable.getCellByColumnUniqueName(row,
"TripID"
);
document.getElementById(
"<%=hidTripID.ClientID %>"
).value = cell.innerHTML;
}
I'm getting an error 'Value of type 'Telerik.Web.UI.GridDataItem' cannot be converted to 'Telerik.Web.UI.GridEditFormItem'.'
in this line
Dim
row
As
GridEditFormItem =
CType
(RadGrid1.Items(index), GridEditFormItem)
How do I access the row that is in 'EditMode'?
Please see above post for more details.
Protected
Sub
ibtnUpdate_Click(
ByVal
sender
As
Object
,
ByVal
e
As
EventArgs)
Dim
tripID
As
String
= hidTripID.value
Dim
index
As
Integer
= RadGrid1.MasterTableView.FindItemByKeyValue(
"Trip_ID"
,
CType
(tripID,
Integer
)).ItemIndex
Dim
row
As
GridEditFormItem =
CType
(RadGrid1.Items(index), GridEditFormItem)
UpdateSchedules(row)
RadGrid1.EditIndexes.Clear()
' BindDispatchRadGrid()
RadGrid1.Rebind()
End
Sub
Try using GridEditableItem instead of GridEditFormItem. Another option is to access the edited row in Update button click as follows.
C#:
protected
void
ibtnUpdate_Click(
object
sender, ImageClickEventArgs e)
{
ImageButton UpdateImage = (ImageButton)sender;
GridEditableItem edit = (GridEditableItem)lnk.NamingContainer;
//access the controls here...
}
Thanks,
Shinu.
This seems like a lot of code to fix a bug in the radgrid control. I don't see anyone reporting this error since 2012. Has the problem been fixed in a later release of the Telerik RadGrid control?
This is something that could not be supported out-of-the-box and should be handled manually by the developer.
RadGrid editing functionality could not depend on values from the existing item when it comes to editing, so the only possible solution would be to manually find the item after rebinding (by storing an identifying value in a HiddenField control or in the Session) and open it for editing.
Best Regards,
Konstantin Dikov
Telerik
Check out the Telerik Platform - the only platform that combines a rich set of UI tools with powerful cloud services to develop web, hybrid and native mobile apps.
If someone still has this problem, I've solved it out in this way:
Protected
Sub
radGrid1_ItemCommand(sender
As
Object
, e
As
GridCommandEventArgs)
If
e.CommandName = RadGrid.EditCommandName
Then
Dim
dataitem
As
GridDataItem = e.Item
Dim
myDataKeyValue= dataitem.GetDataKeyValue(
"myDataKeyName"
)
radGrid1.Rebind()
Dim
index = radGrid1.MasterTableView.FindItemByKeyValue(
"myDataKeyName"
, myDataKeyValue).ItemIndex
e.Canceled =
True
radGrid1.EditIndexes.Add(index)
radGrid1.Rebind()
End
If
So basically I save the datakeyvalue of the dataitem before the rebind and find the itemindex to put in edit after the rebind. It works.
-- NVM - I was accidentally calling clearEditIndexes somewhere else. Still really hard to implement this without having a high level of understanding of webforrms and Telerik databinding ecosystem.
Hi,
Thanks a lot for sharing your solution with the community! I believe it will be very beneficial for the other clients.
Regards,
Vessy
Progress Telerik