Hi,
I have an Add , Edit, Update and Cancel Button on top of a WebDataGrid.
Edit should work only for a specific row user clicks first time and after the RowEditing event is fired, the Grid should be made non Editable.
So far I am able to perform the below:
1.) Upon Clicking Add , the RowAdding behavior is enabled . You type something in the added row and only after tab\enter key the row add event is triggered.
2. Upon Clicking Edit, the RowEditing behavior is enabled. You Edit something in a row, you click done and if you click on another row or press enter\tab key, the edit row event is triggered
3. Upon Clicking Cancel, both these behaviors are disabled which is working fine.
4. I have custom logic to ensure either add or edit followed by update and cancel buttons are displayed. When user clicks update I get the value from session and pass it to DAL.
Issues I am facing:
1. In the grdDataTable_RowUpdating event, even though I put rowediting.enabled and editingcore.enabled properties to false still I can edit other rows after the event is fired. What additional properties should I set in this event to ensure the grid is non editable. ?
2. The grdDataTable_RowAdding event, is only triggered when I click enter or tab buttons and not while I click another row. (Please note that the grid reside in a user control(.ascx) which is dynamically populated with data. The WebDataGrid resides in a generic wrapper user control which in turn is used by other user controls.)
3. Given a scenario where user does not click tab, enter or click on another row in the grid(user just types in the values in the add\edit row) and clicks update, is there a way to get the row that was added or edited in Server Side code instead of using the Events? (Seems the row adding\row updating events are only triggered based on a tab or enter key click.)
Behavior Toggling Server Logic:
Method 1-> Public Property editable() As Boolean ' -------------------------------------------------------------------------- ' Property Name: editable ' Description: Sets/Gets whether the grid is editable ' -------------------------------------------------------------------------- Get Return grdDataTable.Behaviors.EditingCore.Enabled End Get Set(ByVal Value As Boolean) grdDataTable.Behaviors.EditingCore.Enabled = Value 'grdDataTable.Behaviors.EditingCore.EnableInheritance = Value End Set End Property Method 2 Sub Logic-> With grdDataTable.Behaviors Select Case Mode Case ModeType.ReadMode .EditingCore.Behaviors.RowAdding.Enabled = False .EditingCore.Behaviors.RowEditing.Enabled = False Me.editable = False Case ModeType.AddMode Me.editable = True .EditingCore.Behaviors.RowAdding.Enabled = True Case ModeType.EditMode Me.editable = True .EditingCore.Behaviors.RowEditing.Enabled = True grdDataTable.DataKeyFields = Me.DataColumnKey Events-> Protected Sub grdDataTable_RowAdding(sender As Object, e As RowAddingEventArgs) Handles grdDataTable.RowAdding Session("WebDataGridAddEditRow") = Nothing Session.Add("WebDataGridAddEditRow", ConvertHashtableRowsToDataTableColumns(e.Values)) Me.grdDataTable.Behaviors.EditingCore.Behaviors.RowAdding.Enabled = False Me.editable = False End Sub Protected Sub grdDataTable_RowUpdating(sender As Object, e As RowUpdatingEventArgs) Handles grdDataTable.RowUpdating Session("WebDataGridAddEditRow") = Nothing Session.Add("WebDataGridAddEditRow", ConvertHashtableRowsToDataTableColumns(e.Values)) Me.grdDataTable.Behaviors.EditingCore.Behaviors.RowEditing.Enabled = False Me.editable = False End Sub
WebPage Code:
<ig:WebDataGrid ID="grdDataTable" runat="server" AutoGenerateColumns="true" width="100%" ViewStateMode ="Enabled" EnableViewState ="true" EnableAjax="true" EnableDataViewState="True" HeaderCaptionCssClass="WebDataGridColumnHeader" ItemCssClass = "WebDataGridRow" AltItemCssClass = "WebDataGridAlternating" OnColumnSorted="grdDataTable_SortColumn" OnPageIndexChanged="grdDataTable_PageIndexChanged" OnInitializeRow="grdDataTable_InitializeRow" OnRowAdding="grdDataTable_RowAdding" OnRowAdded="grdDataTable_RowAdded" OnRowUpdating="grdDataTable_RowUpdating"> <Behaviors> <ig:Selection RowSelectType="Single" CellClickAction="Row" CellSelectType="Single" SelectedRowSelectorCssClass="DataGridSelectedRow" Enabled="true" > </ig:Selection> <ig:Paging PagerAppearance="Bottom" PageSize="100" Enabled="true" /> <ig:Sorting SortingMode="Single" Enabled="true" /> <ig:ColumnResizing Enabled="false" /> <ig:Activation> </ig:Activation> <ig:EditingCore Enabled="false" EnableInheritance="false"> <Behaviors> <ig:RowAdding Enabled="false" EnableInheritance="false" Alignment="Bottom"> <EditModeActions EnableOnActive="true" MouseClick="Single" /> </ig:RowAdding> <ig:RowEditing Enabled="false"> <EditModeActions EnableOnActive="true" MouseClick="Single" /> <ColumnSettings> <ig:EditingColumnSetting ReadOnly="true" /> </ColumnSettings> </ig:RowEditing> <%-- <ig:Cellediting> <editmodeactions mouseclick="single" /> </ig:Cellediting> --%> </Behaviors> </ig:EditingCore> </Behaviors> </ig:WebDataGrid>
Thanks,Aravind
Hello Aravind,Thank you for the detailed description of the issues you have encountered.1. The rows in the WebDataGrid get committed and the RowUpdating event gets fired after a row has been edited and it has been deactivated (for example clicking another row). Prior to this, the event will not fire and the RowEditing.Enabled property is not yet set to false.In order to commit the row manually after the user has finished editing it, I can suggest you use the RowEditingClientEvents-ExitedEditMode event by invoking the commit method of the editing core.
<ig:RowEditing Enabled="true" RowEditingClientEvents-ExitedEditMode="RowEditing_ExitedEditMode"> </ig:RowEditing> function RowEditing_ExitedEditMode(sender, e) { var grid = $find("dataGrid"); grid.get_behaviors().get_editingCore().commit(); }
dataGrid.Behaviors.EditingCore.Behaviors.RowAdding.Row
Hi Tacho,
I have opened up a case-> CAS-194960-T5P2B0 and i have attached our working POC to the solution. Unfortunately point 1 and 2 dint gent resolved based on the solution provided. For point 3, can you provide the working code to convert Row to a c# DataTable? I did do a quick watch on the Row property, i do see the count but i cant get into the datavalues.
Thanks,
Aravind
Hello Aravind,Thank you for the feedback.It seems you are referring to similar issues in this thread and in the case you have created, so in order to better keep track of the them I will continue updating you on this thread.Since the application you have provided contains some additional custom implementation and logic, I have attached a trimmed down sample with a WebDataGrid that demonstrates the behaviors I have mentioned and by targeting the issues you have referred to in the case.1. The values in the add row are not carried back to the server if the row is just there. (This is why we cannot use the RowAdding.Row property in this case) It only happens if the add row commits itself. This would fire the RowAdding event. Off of those event args, you would have access to the values from the add row.
protected void dataGrid_RowUpdating(object sender, RowUpdatingEventArgs e) { var values = e.Values; var row = e.Row; }
function RowEditing_EnteringEditMode(sender, e) { // Allow Editing only for row with index==1. // var editingRow = e.getCells()[0].getCell().get_row(); if (editingRow.get_index() !== 1) { e.set_cancel(true); } }
var activeRow = dataGrid.Behaviors.Activation.ActiveCell.Row;
dataGrid.Behaviors.EditingCore.Behaviors.RowEditing.Enabled = false;
WebDataGrid_Sample
Thanks Tacho,
A.) Add feature-> I have figured the logic for add functionality base on the below logic but i would like to get it confirmed if it is the right approach?:
Scenario: When Add feature is enabled, the newly added row shows up. Disable enter and tab on the added row, User types in the values in the added row and clicks a button. The On RowAdding event should be triggered:
Solution:
1. Ensure BatchUpdating="true" at EditingCore (Not sure why, but i can make it work only if this is true)
2. At the EditingClientEvents-RowAdding at EditingCore call a method. Logic of this method:
var toSave = false;
function cancelRowAdding(sender, e) { if (!toSave) { e.set_cancel(true); } toSave = false; }
3. On the onClient click of the button call the below method:
function saveRow() { toSave = true; $find("<%= grdDataTable.ClientID%>") .get_behaviors() .get_editingCore() .get_behaviors().get_rowAdding()._commitRow(); }
The above steps will ensure the RowAdding Server Event is called only upon button click.
B.) Edit Feature-> I am almost there (your solution has opened my eyes that not all features are available via Server Side) . But i have the following question and kindly confirm the below is the right approach?:
In the RowEditing_ExitedEditMode , Can you share the code on:
How to Find if Row Was actually Edited(that is at least 1 cell value in the row was changed from previous, done is clicked and then only set commit on the row edited, set isAlreadyRowEdited to true and then fire the On RowUpdating event)?
Scenario: When edit feature is enabled, the edit should be enabled at the first row user has selected and all other rows should have edit disabled. When user changes any cell in that row and he clicks done, then the On RowUpdating Event should be triggered. Then the grid should be non editable for any row.
1. Add the below JS method for <SelectionClientEvents RowSelectionChanged="RowSelection_Changed" />
var selectedRowIndex = 0;
var isAlreadyRowEdited = false;
function RowSelection_Changed(webDataGrid, evntArgs) { var grid = $find("<%= grdDataTable.ClientID%>"); var gridBehaviors = grid.get_behaviors(); var row = gridBehaviors.get_selection().get_selectedRows().getItem(0); selectedRowIndex = row.get_index(); }
2. For the RowEditing_EnteringEditMode method:
function RowEditing_EnteringEditMode(sender, e) { // Do not Allow Editing if Already a Row was edited previosly if (isAlreadyRowEdited) { e.set_cancel(true) } else { var editingRow = e.getCells()[0].getCell().get_row(); // Allow Editing only for the selected row if (editingRow.get_index() !== selectedRowIndex) { e.set_cancel(true); } } }
3. For the RowEditing_ExitedEditMode method:
function RowEditing_ExitedEditMode(sender, e) { var grid = $find("<%= grdDataTable.ClientID%>"); // Find if Row Was Edited(that is atleast 1 cell value in the row was changed from previous, done is clicked and then only set commit the row edited and set isAlreadyRowEdited to true) How to? grid.get_behaviors().get_editingCore().commit(); isAlreadyRowEdited = true; }
Hello Aravind,Thank you for the detailed description you have provided.A) Add featureWhen the BatchUpdating is set to True, the changes to the row will not be sent to the server until a postback is triggered. We can manually trigger the necessary postback by invoking the get_rowAdding()._commitRow() method as you have done in the provided code-snippet.(When the BatchUpdating is set to False, the changes to the row will be automatically sent to the server.)The approach looks good and please note that since these events are handled with custom logic, any additional changes have to be carefully integrated when using them in your application.B) Edit featureHere 1 and 2 look good as well and the same statement for the custom logic applies here too.In order to detect if a cell has changed its value, you can use the EditingClientEvents.CellValueChanged (it will fire only if the client types a value that is different from the original one). This way we can set the isAlreadyRowEdited variable to true and handle the ExitedEditMode accordingly.
<Behaviors> <ig:EditingCore AutoCRUD="true"> <EditingClientEvents CellValueChanged="EditingEvents_CellValueChanged" /> ... </ig:EditingCore> </Behaviors>
var isAlreadyRowEdited = false; function EditingEvents_CellValueChanged(sender, e) { isAlreadyRowEdited = true; // The old value of the cell (if we need it) var oldValue = e.get_oldValue(); // The new value of the cell (if we need it) var newValue = e.get_cell().get_value(); } function RowEditing_ExitedEditMode(sender, e) { var grid = $find("dataGrid"); if (isAlreadyRowEdited) { grid.get_behaviors().get_editingCore().commit(); isAlreadyRowEdited = false; alert("row commited!"); } }
Thanks Tacho, this solution is finally working! I am marking this as a verified answer since it solves the problem with add and edits. However i have run into another issue and since it is a new one, posted a new question in the forum.
https://www.infragistics.com/community/forums/f/ultimate-ui-for-asp-net/118084/webdatagrid-edit-add-rows-and-disable-after-rowadding-and-row-updating-events
Hello Aravind,Thank you for the feedback.I am glad to know that you were able to achieve the functionality you were looking for.Our support team will update you on the new issue you have referred to as soon as they are ready with their investigation.Thank you for using Infragistics components.