Afternoon,
I am using a RadGrid with Batch Editing. Under a couple of conditions I want to be able to stop a cell from being edited.
I've followed another example using the OnBatchEditOpening client event:
function onBatchEditOpening(sender, args) {
args.get_tableView().get_dataItems();
var cell = args.get_cell();
var cellValue = cell.innerText;
var columnUniqueName = args.get_columnUniqueName();
var row = args.get_row();
var item = row.control;
var itemIndex = item.get_itemIndex();
if (itemIndex > -1) { // if itemIndex is -1 it means this is a new row
if ((columnUniqueName === "Process_type" && cellValue === "L") ||
(columnUniqueName === "Process_order" && cellValue === "1")) {
args.set_cancel(true);
}
}
It just so happens that when the process type is L and process order is 1 will occur in the same row, so all other rows should remain unaffected.
It works fine - I click in the row with 1 and L, and the process order and process type cells are not editable. However, when I then click on a field in another row I get this error:
This only occurs when I've clicked in the row with the non-editable cells first.
Any ideas on how to clear this?
Kind regards,
Richard
1 Answer, 1 is accepted
Hi Richard,
To address the issue you're encountering with RadGrid's Batch Editing, it seems like the error might be related to the way the grid is handling edit operations when switching between rows. When you prevent editing on specific cells, it's crucial to ensure that the grid's internal state is correctly managed to avoid conflicts when interacting with other rows.
Here's how you can handle this scenario:
Ensure Proper Closure of Edit Operations: Before you prevent editing on specific cells, make sure that any existing edit operations are properly closed. This can help prevent conflicts when you try to interact with other rows.
Modify the
onBatchEditOpening
Function: Adjust your JavaScript function to ensure that any necessary cleanup is done before canceling the edit. Here's an example:function onBatchEditOpening(sender, args) { // Close any other edit cells to clear potential conflicts sender.get_batchEditingManager()._tryCloseEdits(sender.get_masterTableView()); var cell = args.get_cell(); var cellValue = cell.innerText; var columnUniqueName = args.get_columnUniqueName(); var row = args.get_row(); var item = row.control; var itemIndex = item.get_itemIndex(); if (itemIndex > -1) { // if itemIndex is -1 it means this is a new row if ((columnUniqueName === "Process_type" && cellValue === "L") || (columnUniqueName === "Process_order" && cellValue === "1")) { args.set_cancel(true); return; } } }
Check for Console Errors: Make sure to check your browser's console for any JavaScript errors that might provide more insight into the issue. If you see any specific error messages, please let me know so I can assist further.
By ensuring that any ongoing edit operations are properly closed before canceling a new edit, you can help prevent conflicts that lead to errors when interacting with other rows. If the issue persists, please provide any specific error messages from the console for further investigation.
Please refer to the following article for additional information:
Regards,
Vasko
Progress Telerik
Hi Vasko,
Many thanks for your reply.
I've added the get_batchEditingManager()._tryCloseEdits to my onBatchEditOpening function, and I'm still seeing the same console error "Uncaught TypeError: Cannot read properties of undefined (reading 'style')".
I've also noticed that if I don't include args.get_tableView().get_dataItems(); in the function, I get the console error "Uncaught TypeError: Cannot read properties of undefined (reading 'get_itemIndex')".
The complete onBatchEditOpening function is:
function onBatchEditOpening(sender, args) {
// Close any other edit cells to clear potential conflicts
sender.get_batchEditingManager()._tryCloseEdits(sender.get_masterTableView());
args.get_tableView().get_dataItems();
var cell = args.get_cell();
var cellValue = cell.innerText;
var columnUniqueName = args.get_columnUniqueName();
var row = args.get_row();
var item = row.control;
var itemIndex = item.get_itemIndex();
if (itemIndex > -1) { // if itemIndex is -1 it means this is a new row
if ((columnUniqueName === "Process_type" && cellValue === "L") ||
(columnUniqueName === "Process_order" && cellValue === "1")) {
args.set_cancel(true);
return;
}
}
}
This is the main part of the grid:
<telerik:RadGrid ID="RadGridEntries" runat="server" RenderMode="Lightweight" AllowSorting="True" CellSpacing="-1" GridLines="Horizontal"
OnNeedDataSource="RadGridEntries_NeedDataSource" OnBatchEditCommand="RadGridEntries_BatchEditCommand"
OnItemInserted="RadGridEntries_ItemInserted" OnItemUpdated="RadGridEntries_ItemUpdated" OnItemDeleted="RadGridEntries_ItemDeleted"
OnPreRender="RadGridEntries_PreRender" AutoGenerateColumns="false"
AllowAutomaticUpdates="false" AllowAutomaticInserts="false" AllowAutomaticDeletes="false">
<ClientSettings>
<Scrolling AllowScroll="true" UseStaticHeaders="true" SaveScrollPosition="true" />
<KeyboardNavigationSettings AllowSubmitOnEnter="false" />
<ClientEvents OnBatchEditOpening="onBatchEditOpening" />
</ClientSettings>
<MasterTableView Name="Processes" AutoGenerateColumns="false" DataKeyNames="Process_id"
CommandItemDisplay="Top" EditMode="Batch" BatchEditingSettings-OpenEditingEvent="Click" HeaderStyle-HorizontalAlign="Center">
<CommandItemSettings ShowRefreshButton="false" />
<BatchEditingSettings EditType="Row" HighlightDeletedRows="true" />
The PreRender is setting the max length for one of the Bound Columns.
Let me know if I can provide any further detail.
Kind regards,
Richard
Hello Richard,
Could you try replicating the behavior with the provided code snippet:
<telerik:RadGrid ID="RadGrid1" runat="server" AllowPaging="True" Width="400px" OnNeedDataSource="RadGrid1_NeedDataSource">
<MasterTableView AutoGenerateColumns="False" DataKeyNames="OrderID" EditMode="Batch">
<Columns>
<telerik:GridBoundColumn DataField="OrderID" DataType="System.Int32"
FilterControlAltText="Filter OrderID column" HeaderText="OrderID"
ReadOnly="True" SortExpression="OrderID" UniqueName="OrderID">
</telerik:GridBoundColumn>
<telerik:GridBoundColumn DataField="Process_type"
FilterControlAltText="Filter Process_type column" HeaderText="Process Type"
SortExpression="Process_type" UniqueName="Process_type">
</telerik:GridBoundColumn>
<telerik:GridBoundColumn DataField="Process_order"
FilterControlAltText="Filter Process_order column" HeaderText="Process Order"
SortExpression="Process_order" UniqueName="Process_order">
</telerik:GridBoundColumn>
</Columns>
</MasterTableView>
<ClientSettings>
<ClientEvents OnBatchEditOpening="onBatchEditOpening" />
</ClientSettings>
</telerik:RadGrid>
protected void RadGrid1_NeedDataSource(object sender, GridNeedDataSourceEventArgs e)
{
(sender as RadGrid).DataSource = OrdersTable();
}
private DataTable OrdersTable()
{
DataTable dt = new DataTable();
dt.Columns.Add(new DataColumn("OrderID", typeof(int)));
dt.Columns.Add(new DataColumn("Process_type", typeof(string)));
dt.Columns.Add(new DataColumn("Process_order", typeof(int)));
dt.PrimaryKey = new DataColumn[] { dt.Columns["OrderID"] };
for (int i = 0; i < 3; i++)
{
int index = i + 1;
DataRow row = dt.NewRow();
row["OrderID"] = index;
row["Process_type"] = index % 2 == 0 ? "L" : "N";
row["Process_order"] = index % 2 == 0 ? 1 : 2;
dt.Rows.Add(row);
}
return dt;
}
function onBatchEditOpening(sender, args) {
args.get_tableView().get_dataItems();
var cell = args.get_cell();
var cellValue = cell.innerText;
var columnUniqueName = args.get_columnUniqueName();
var row = args.get_row();
var item = row.control;
var itemIndex = item.get_itemIndex();
if (itemIndex > -1) {
if ((columnUniqueName === "Process_type" && cellValue === "L") ||
(columnUniqueName === "Process_order" && cellValue === "1")) {
args.set_cancel(true);
}
}
}
If possible, could you adjust the code snippet so that it reproduces the issue?
Regards,Author nickname
Progress Telerik
Hello Vasko,
I've managed to adjust the code snippet, and reproduce and locate the error:
<telerik:RadGrid ID="RadGrid1" runat="server" AllowPaging="True" Width="400px" OnNeedDataSource="RadGrid1_NeedDataSource"
AllowSorting="True" CellSpacing="-1" GridLines="Horizontal" AllowAutomaticUpdates="false" AllowAutomaticInserts="false" AllowAutomaticDeletes="false"
OnPreRender="RadGrid1_PreRender" AutoGenerateColumns="false">
<MasterTableView Name="ProcessList" AutoGenerateColumns="False" DataKeyNames="OrderID"
CommandItemDisplay="Top" EditMode="Batch" BatchEditingSettings-OpenEditingEvent="Click" HeaderStyle-HorizontalAlign="Center">
<CommandItemSettings ShowRefreshButton="false" />
<BatchEditingSettings EditType="Row" HighlightDeletedRows="true" />
<Columns>
<telerik:GridBoundColumn DataField="OrderID" DataType="System.Int32"
FilterControlAltText="Filter OrderID column" HeaderText="OrderID"
ReadOnly="True" SortExpression="OrderID" UniqueName="OrderID" Exportable="false">
</telerik:GridBoundColumn>
<telerik:GridTemplateColumn DataField="Process_type" SortExpression="Process_type" UniqueName="Process_type"
HeaderText="Process Yype" FilterControlAltText="Filter Process_type column" >
<ItemTemplate>
<%#DataBinder.Eval(Container.DataItem, "Process_type")%>
</ItemTemplate>
<EditItemTemplate>
<telerik:RadTextBox ID="txtProcessType" runat="server" MaxLength="2" Style="text-transform:uppercase">
<ClientEvents OnValueChanging="processTypeChanging" />
</telerik:RadTextBox>
<asp:RequiredFieldValidator ID="rfvProcessType" runat="server" ForeColor="Red"
ErrorMessage="*Process Type is required" Display="Dynamic"
ControlToValidate="txtProcessType" />
<asp:RegularExpressionValidator ID="revProcessType" runat="server" ForeColor="Red"
ErrorMessage="*Process Type must be up to two alpha characters" Display="Dynamic"
ControlToValidate="txtProcessType" ValidationExpression="^[A-Za-z]*$" />
</EditItemTemplate>
</telerik:GridTemplateColumn>
<telerik:GridBoundColumn DataField="Process_order"
FilterControlAltText="Filter Process_order column" HeaderText="Process Order"
SortExpression="Process_order" UniqueName="Process_order">
</telerik:GridBoundColumn>
<telerik:GridBoundColumn DataField="Process_name"
FilterControlAltText="Filter Process_name column" HeaderText="Process Name"
SortExpression="Process_name" UniqueName="Process_name" MaxLength="30" ItemStyle-HorizontalAlign="Left" HeaderStyle-Width="150px">
<ColumnValidationSettings EnableRequiredFieldValidation="true">
<RequiredFieldValidator ForeColor="Red" Text="*Process Name is required" Display="Dynamic">
</RequiredFieldValidator>
</ColumnValidationSettings>
</telerik:GridBoundColumn>
</Columns>
</MasterTableView>
<ClientSettings>
<Scrolling AllowScroll="true" UseStaticHeaders="true" SaveScrollPosition="true" />
<KeyboardNavigationSettings AllowSubmitOnEnter="false" />
<ClientEvents OnBatchEditOpening="onBatchEditOpening" />
</ClientSettings>
</telerik:RadGrid>
protected void RadGrid1_PreRender(object sender, EventArgs e)
{
GridTableView masterTable = (sender as RadGrid).MasterTableView;
// Set the max length for the Bound Columns
GridTextBoxColumnEditor processName = masterTable.GetBatchColumnEditor("Process_name") as GridTextBoxColumnEditor;
processName.TextBoxMaxLength = 30;
}
protected void RadGrid1_NeedDataSource(object sender, GridNeedDataSourceEventArgs e)
{
(sender as RadGrid).DataSource = OrdersTable();
}
private DataTable OrdersTable()
{
DataTable dt = new DataTable();
dt.Columns.Add(new DataColumn("OrderID", typeof(int)));
dt.Columns.Add(new DataColumn("Process_type", typeof(string)));
dt.Columns.Add(new DataColumn("Process_order", typeof(int)));
dt.Columns.Add(new DataColumn("Process_name", typeof(string)));
dt.PrimaryKey = new DataColumn[] { dt.Columns["OrderID"] };
for (int i = 0; i < 3; i++)
{
int index = i + 1;
DataRow row = dt.NewRow();
row["OrderID"] = index;
row["Process_type"] = index % 2 == 0 ? "L" : "N";
row["Process_order"] = index % 2 == 0 ? 1 : 2;
row["Process_name"] = index % 2 == 0 ? "US range" : "Non-US";
dt.Rows.Add(row);
}
return dt;
}
function processTypeChanging(sender, args) {
args.set_newValue(args.get_newValue().toUpperCase());
}
function onBatchEditOpening(sender, args) {
args.get_tableView().get_dataItems();
var cell = args.get_cell();
var cellValue = cell.innerText;
var columnUniqueName = args.get_columnUniqueName();
var row = args.get_row();
var item = row.control;
var itemIndex = item.get_itemIndex();
if (itemIndex > -1) {
if ((columnUniqueName === "Process_type" && cellValue === "L") ||
(columnUniqueName === "Process_order" && cellValue === "1")) {
args.set_cancel(true);
}
}
}
The error is caused by me having EditType="Row" set in BatchEditingSettings (highlighted above). Removing it allows the grid editing to work as desired.
Kind regards,
Richard
Hi Richard,
Thank you for providing a reproducible sample code snippet.
After researching the issue more in-depth, it appears that this is a limitation of the Batch Editing mode when the EditType is set to Row. The issue stems from setting the args.set_cancel(true) to certain cells based on the clicked cell's Column and Value, but having other cells still be opened.
This I am afraid will not work properly with Row editing, and Cell edit type needs to be used. For the issue itself, I suggest you open a bug report on our Feedback Portal.
Regards,Author nicknameProgress Telerik
Thanks Vasko.
I'll have to stick with just cell editing for now. I may open a bug report at a later date.
Thanks for your help,
Richard