This is a migrated thread and some comments may be shown as answers.

[Solved] Disabling Edit on Row-by-Row Basis

5 Answers 410 Views
Grid
This is a migrated thread and some comments may be shown as answers.
Brad Hehe
Top achievements
Rank 1
Brad Hehe asked on 20 Oct 2009, 01:56 PM
I'm working with another developer to satisfy their busienss requirement of enabling/disabling editing on a row-by-row basis based on a given criteria...  For simplicity sake, let's say they can edit Even row #'s and Odd row #'s are displayed but not editable...

Our grid has a standard GridEditCommandColumn named "EditCommandColumn"... We also have an additional GridButtonColumn named "DeleteCommand" and its CommandName is set to "Delete"...  There is also a ClientEvents setting for OnRowDblClick to call a JavaScript function which performs the following:


radGrid.get_masterTableView().editItem(eventArgs.get_itemIndexHierarchical()); 

What I've done thus far is to use the following code to access the ImageButton in the GridEditCommandColumn and set it's Visible property to False...  Same basic approach I'm assuming I would apply for the Delete column though I haven't made it that far yet...


TableCell tableCell = gridDataItem[
"EditCommandColumn"];  
ImageButton imageButton = tableCell.Controls[0] as ImageButton;  
imageButton.Visible = false

So this works to hide the button and prevent the user from clicking on it, but it leaves the client-side OnRowDblClick still functional...

I was hoping to find something far more elegant / canned & ready-to-use... ie. a row-level setting of some sort - such as a property on the GridDataItem for "AllowEdit" or something similar... perhaps both "AllowEdit" and "AllowDelete"... but I see nothing of the sort...

What is the "right" way to handle this case? Or am I heading in the right direction and just need a few more tweaks.... 

I'm thinking my option here for dealing with the client-side double-click handler would be to do as described above and additionally catch the ItemCommand event and test for the same conditions and conditionally Cancel the ItemCommand event?


5 Answers, 1 is accepted

Sort by
0
Yavor
Telerik team
answered on 21 Oct 2009, 08:56 AM
Hi Brad,

Basically, you can use the onRowDblClick client side event handler to allow/disallow the processing of the event. For example, you can use the get_itemIndexHierarchical() method to get the item index, or get a specific cell value:

http://www.telerik.com/help/aspnet-ajax/grid_getcellbycolumnuniquename.html

to determine whether to raise another event, or disallow further action.
I hope this information helps.

Greetings,
Yavor
the Telerik team

Instantly find answers to your questions on the new Telerik Support Portal.
Watch a video on how to optimize your support resource searches and check out more tips on the blogs.
0
Brad Hehe
Top achievements
Rank 1
answered on 21 Oct 2009, 01:46 PM
So if I understand correctly, there is no server-side means of achieving this? The reason I ask is that I do not want to duplicate the decision logic that makes the determination in both C# and JavaScript... that's a poor choice from a maintenace perspective in that the 2 could get out of sync...

I could envision a hybrid approach where the decision is determined server-side and 'stored' in a special hidden column (i.e. IsRowEditable) and then the OnRowDblClick handler we use (it's in a common JS library and used on all grids - yet another reason why I need common/generic logic on the client-side if I use any) could look to that hidden column for a simple boolean....

I have a working model where I use the ItemDataBound event to make the determination and then Hide the Edit / Delete buttons. That works exactly as I need and is 100% server-side...  On the client-side I still allow the OnRowDblClick to fire and I end up on the server-side in either the DeleteCommand event handler or the EditCommand event handler.  I call upon the same decision logic to determine if the action should be allowed and then if it is not allowed, attempt to 'cancel' the event...

What I get is soooo close... The 1st time it appears to work fine. I see the RadAjaxLoadingPanel unfortunately but the event is cancelled and all appears well - but it is not.  The next time I double-click on the same exact row I get an unhandled exception...

        protected virtual void DeleteCommandEventHandler(object source, GridCommandEventArgs e)  
        {  
            bool allowRowDelete = OnAllowRowDelete(e.Item);  
 
            if (!allowRowDelete)  
            {  
                CancelGridCommand(e);  
            }  
        }  
 
 
        protected void CancelGridCommand(GridCommandEventArgs gridCommandEventArgs)  
        {  
            gridCommandEventArgs.Canceled = true;  
        }  
 

The above code produced the following exception... This is after the OnRowDblClick client-side event put the Row into Edit mode, the server-side EditCommand event handler had fired and the [e.Canceled = true] had processed. The event firing had fully completed and the grid was ready for the next interaction - which was a second double click on that same row...


"Failed to load viewstate.  The control tree into which viewstate is being loaded must match the control tree that was used to save viewstate during the previous request.  For example, when adding controls dynamically, the controls added during a post-back must match the type and position of the controls added during the initial request."
 

I've tried a couple variations within my CanceGridCommand method including calling Rebind - which yielded even stranger results - the command did not cancel and I ended up in Edit mode or Deleteing as though setting the Canceled property had never happened...

Another variation I had tried was setting [e.Item.Selected = false] for both aesthetic and functional purposes... That didn't change the behavior and the exception still occurs...



0
Brad Hehe
Top achievements
Rank 1
answered on 21 Oct 2009, 02:45 PM
So I'm attempting the approach where I have a hidden column containing the pre-determined state of "IsRowEditable" and "IsRowDeletable"...

For my client-side OnRowDblClick handler in JavaScript... I assume the following is basically what I should need to test the value in that hidden column...


function
 RadGridEditSelectedRow(radGrid, eventArgs) {  
 
    var masterTableView = radGrid.get_masterTableView();  
    var rowIndex = eventArgs.get_itemIndexHierarchical();  
    var isRowEditable = masterTableView.getCellByColumnUniqueName  
        (  
            masterTableView.get_dataItems()[rowIndex],  
            "IsRowEditable" 
         ).innerHTML;  
 
    if (isRowEditable == "true") {  
 
        masterTableView.editItem(rowIndex);  
    }  

Correct?

Then I simply remove the code I had previously placed in my EditCommand and DeleteCommand event handlers since the events should never occur...
0
Brad Hehe
Top achievements
Rank 1
answered on 21 Oct 2009, 02:53 PM
A minor variation to the script... Some of the grids that we are already using this shared library function on are not inheriting from the same base class which will contain the functionality to add these special hidden 'control columns'...  To make the script behave as it used to (blindly go into edit mode) - I'm trying to test for the presence of the hidden 'control column' first and if it is not present, go into edit mode... if it is present, check the value before going into edit mode...

 
function RadGridEditSelectedRow(radGrid, eventArgs) {  
 
    var masterTableView = radGrid.get_masterTableView();  
    var rowIndex = eventArgs.get_itemIndexHierarchical();  
    var isRowEditableCell = masterTableView.getCellByColumnUniqueName  
        (  
            masterTableView.get_dataItems()[rowIndex],  
            "IsRowEditable" 
         );  
 
    if (isRowEditableCell != null) {  
 
        if (isRowEditableCell.innerHTML == "true") {  
 
            masterTableView.editItem(rowIndex);  
        }  
    }  
    else {  
 
        masterTableView.editItem(rowIndex);  
    }  

I think this is correct (JavaScript isn't my strength - I'm a C# guy) and I'm beginning to test it out...


0
Brad Hehe
Top achievements
Rank 1
answered on 21 Oct 2009, 03:21 PM
Initially, the above script wass not able to find the cell by it's unique name. The column was added during the grid's Load event... I've been debugging this with the use of Alerts() scattered through it and can't get past my 1st test condition of finding the cell for some reason...

What I finally found was that the Column was setting both Visible and Display to false. It seems the [getCellByColumnUniqueName] method cannot find the column/cell when Visible = false...  

I think I have a functioning prototype now and I'm performing more rigorous testing at this time...

Thanks!
Tags
Grid
Asked by
Brad Hehe
Top achievements
Rank 1
Answers by
Yavor
Telerik team
Brad Hehe
Top achievements
Rank 1
Share this question
or