While using the RadGrid in Batch Mode, I am trying to do some complex client side validation on save. To do so, I am using the ClientEvents-OnCommand to handle it. What I've discovered is that if I cancel the OnCommand event (args.set_cancel(true)) the save is canceled as expected, but when I go to save again (passing validation), what the OnBatchEditCommand command receives on the server side is an UPDATE, not an Insert, and that UPDATE command's newValues and oldValues are both null.
We are currently using version 2014.3.1209.40 I'd like to know if this has been fixed in a newer version before I upgrade our solution, as that will require a full regression test.
Here is my test jig that shows the issue.
Default.aspx
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="TestRadGrid.Default" UnobtrusiveValidationMode="None" %>
<%@ Register TagPrefix="telerik" Namespace="Telerik.Web.UI" Assembly="Telerik.Web.UI" %>
<!DOCTYPE html>
<
html
xmlns
=
"http://www.w3.org/1999/xhtml"
>
<
head
runat
=
"server"
>
<
title
></
title
>
<
script
src
=
"https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"
type
=
"text/javascript"
></
script
>
<
telerik:RadCodeBlock
runat
=
"server"
>
<
script
type
=
"text/javascript"
>
var isValidatingGrid = false;
function gridCommand(sender, args) {
if (args.get_commandName() !== 'BatchEdit')
return;
var failValidationChk = $('#failValidation');
if (failValidationChk.prop("checked")) {
args.set_cancel(true);
return;
}
else {
//good to save
return;
}
}
</
script
>
</
telerik:RadCodeBlock
>
</
head
>
<
body
>
<
form
id
=
"form1"
runat
=
"server"
>
<
asp:ScriptManager
ID
=
"theScriptManager"
runat
=
"server"
></
asp:ScriptManager
>
<
div
>Fail Validation<
input
id
=
"failValidation"
type
=
"checkbox"
/></
div
>
<
div
>
<
telerik:RadGrid
ID
=
"EventSubjects"
CssClass
=
"eventSubjectsGrid"
AutoGenerateColumns
=
"False"
GridLines
=
"Both"
AllowPaging
=
"True"
PagerStyle-AlwaysVisible
=
"true"
OnNeedDataSource
=
"EventSubjects_NeedDataSource"
OnBatchEditCommand
=
"EventSubjects_BatchEditCommand"
ValidationSettings-EnableValidation
=
"true"
Skin
=
"Sunset"
runat
=
"server"
GroupPanelPosition
=
"Top"
>
<
ClientSettings
AllowKeyboardNavigation
=
"true"
>
<
Selecting
AllowRowSelect
=
"True"
/>
<
ClientEvents
OnCommand
=
"gridCommand"
/>
</
ClientSettings
>
<
MasterTableView
CommandItemDisplay
=
"Bottom"
DataKeyNames
=
"LocationID"
EditMode
=
"Batch"
>
<
BatchEditingSettings
EditType
=
"Cell"
/>
<
Columns
>
<
telerik:GridEditCommandColumn
ButtonType
=
"ImageButton"
UniqueName
=
"EditCommandColumn1"
>
<
HeaderStyle
Width
=
"20px"
></
HeaderStyle
>
<
ItemStyle
CssClass
=
"MyImageButton"
></
ItemStyle
>
</
telerik:GridEditCommandColumn
>
<
telerik:GridBoundColumn
DataField
=
"Location"
FilterControlAltText
=
"Filter Location column"
HeaderText
=
"Location"
MaxLength
=
"50"
UniqueName
=
"Location"
>
<
ColumnValidationSettings
EnableRequiredFieldValidation
=
"True"
>
<
RequiredFieldValidator
Display
=
"Dynamic"
ForeColor
=
"Red"
ErrorMessage
=
"This field is required"
></
RequiredFieldValidator
>
</
ColumnValidationSettings
>
</
telerik:GridBoundColumn
>
<
telerik:GridTemplateColumn
DataField
=
"Barcode"
HeaderText
=
"Barcode"
UniqueName
=
"BarcodeColumn"
>
<
ItemTemplate
>
<
asp:Label
runat
=
"server"
ID
=
"lblBarcode"
Text='<%# Eval("Barcode") %>' ></
asp:Label
>
</
ItemTemplate
>
<
EditItemTemplate
>
<
asp:TextBox
runat
=
"server"
ID
=
"txtBarcode"
Text='<%# Bind("Barcode") %>'></
asp:TextBox
>
<
asp:CustomValidator
ID
=
"CustomValidatortxtBarcode"
runat
=
"server"
ErrorMessage
=
"Barcode already used"
ControlToValidate
=
"txtBarcode"
Display
=
"Dynamic"
OnServerValidate
=
"CustomValidatortxtBarcode_ServerValidate"
>
</
asp:CustomValidator
>
</
EditItemTemplate
>
</
telerik:GridTemplateColumn
>
</
Columns
>
</
MasterTableView
>
</
telerik:RadGrid
>
</
div
>
</
form
>
</
body
>
</
html
>
Default.aspx.cs
using
System;
using
System.Collections.Generic;
using
System.Linq;
using
System.Web;
using
System.Web.UI;
using
System.Web.UI.WebControls;
using
Telerik.Web.UI;
namespace
TestRadGrid
{
public
partial
class
Default : System.Web.UI.Page
{
protected
global::System.Web.UI.HtmlControls.HtmlForm form1;
protected
global::System.Web.UI.ScriptManager theScriptManager;
protected
global::Telerik.Web.UI.RadGrid EventSubjects;
public
class
AreaStops
{
public
int
LocationID {
get
;
set
; }
public
string
Location {
get
;
set
; }
public
string
Barcode {
get
;
set
; }
}
public
static
List<AreaStops> s_AreaStopsData =
new
List<AreaStops>();
static
Default()
{
s_AreaStopsData.Add(
new
AreaStops() { LocationID = 1, Location =
"lions"
, Barcode =
"223"
});
s_AreaStopsData.Add(
new
AreaStops() { LocationID = 2, Location =
"tigers"
, Barcode =
"456"
});
s_AreaStopsData.Add(
new
AreaStops() { LocationID = 3, Location =
"bears"
, Barcode =
"789"
});
s_AreaStopsData.Add(
new
AreaStops() { LocationID = 4, Location =
"ducks"
, Barcode =
"123"
});
}
protected
void
Page_Load(
object
sender, EventArgs e){ }
protected
void
EventSubjects_NeedDataSource(
object
sender, Telerik.Web.UI.GridNeedDataSourceEventArgs e)
{
EventSubjects.DataSource = s_AreaStopsData;
}
protected
void
EventSubjects_BatchEditCommand(
object
sender, Telerik.Web.UI.GridBatchEditingEventArgs e)
{
System.Diagnostics.Debug.WriteLine(
"Batch update"
);
foreach
(GridBatchEditingCommand curCommand
in
e.Commands)
{
System.Diagnostics.Debug.WriteLine(curCommand.Type);
if
(curCommand.NewValues ==
null
|| curCommand.OldValues ==
null
){
System.Diagnostics.Debug.WriteLine(
"new or old data missing"
);
return
;
}
string
newLocation = (
string
)curCommand.NewValues[
"Location"
];
string
newBarcode = (
string
)curCommand.NewValues[
"Barcode"
];
if
(newBarcode.Contains(
'G'
))
{
e.Canceled =
true
;
curCommand.Canceled =
true
;
return
;
}
if
(curCommand.Type == GridBatchEditingCommandType.Update)
{
AreaStops stop = s_AreaStopsData.FirstOrDefault(ars => ars.LocationID == (
int
)curCommand.OldValues[
"LocationID"
]);
if
(stop !=
null
)
{
stop.Location = newLocation;
stop.Barcode = newBarcode;
}
else
{
s_AreaStopsData.Add(
new
AreaStops() { LocationID = s_AreaStopsData.Count + 1, Location = newLocation, Barcode = newBarcode });
}
}
else
{
s_AreaStopsData.Add(
new
AreaStops() { LocationID = s_AreaStopsData.Count + 1, Location = newLocation, Barcode = newBarcode });
}
}
}
protected
void
CustomValidatortxtBarcode_ServerValidate(
object
source, ServerValidateEventArgs args)
{
bool
isValid = !args.Value.Contains(
'F'
);
args.IsValid = isValid;
}
}
}