We use cookies to give you the best experience on our website. If you continue to browse, then you agree to our privacy policy and cookie policy.
Unfortunately, activation email could not send to your email. Please try again.

ejGrid: Cell Events (e.g. cellEdit) only fire in Batch Mode

Thread ID:

Created:

Updated:

Platform:

Replies:

130485 May 15,2017 12:33 PM May 19,2017 09:21 AM JavaScript 9
loading
Tags: ejGrid
Robert Mims
Asked On May 15, 2017 12:33 PM

See: http://jsplayground.syncfusion.com/nl0vyvcy

Scenario: I need to trigger workflow (populate default values based upon a selection within a cell) during entry of a new row. 

I'm using KnockoutJS and ideally the property value would be committed for the cell to the backing property on edit, however, the value is not updated until the row is committed. Therefore, I am seeking to intercept the CellEdit event and force the udpate to trigger my behavior, however, this only appears to be triggering when the Edit Mode is Batch.

Desired behavior: Trigger the cell edit events during Normal mode as well.

Any suggestions how to achieve this behavior?

Thank you.

Robert

Prasanna Kumar Viswanathan [Syncfusion]
Replied On May 16, 2017 08:04 AM

Hi Robert, 

Thanks for contacting Syncfusion support. 

Query : “Trigger the cell edit events during Normal mode as well” 

In Normal mode when we perform edit operation the edit form will be generated for the whole row. So, the value will updated for each cell when the whole row is submitted. If you need to update the cell value once you focus out, we suggest you to bind the focus out event for the cells.  

To bind the focus out event, use actionComplete event for ejGrid. In this event we check the requestType and bind the focus out event for each cell. 

Find the code example:  

 
$("#Grid").ejGrid({ 
            // the datasource "window.gridData" is referred from jsondata.min.js 
            dataSource: window.gridData, 
            allowPaging: true, 
            actionComplete: function (args) { 
                if (args.requestType == "beginedit") { 
                    this.element.find(".gridform").find("td").focusout(function () { 
                        debugger; 
                    }); 
                } 
            }, 


Refer to the Help document for the actionComplete event. 


Regards, 
Prasanna Kumar N.S.V 


Robert Mims
Replied On May 16, 2017 08:15 AM

Thank you, again, for your quick reply.

I'll give that a try.

Robert

Robert Mims
Replied On May 17, 2017 08:31 AM

I took your direction as inspiration and composed a custom KnockoutJS binding handler to allow for configuration of target properties and editors within a cell. Perhaps somebody else runs in to this need, so, sharing it here. To use it, just add a reference with your string property list after your ejGrid data binding instruction.

Example use:
ejUpdateCellOnLostFocus: [ 'productId', 'quantity' ]
The binding handler:
ko.bindingHandlers.ejUpdateCellOnLostFocus = {
    init: function(element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {
        /// <summary>Initializes the Syncfusion Cell Property Update binding handler</summary>
        /// <param name="element" type="Object">The target Syncfusion Grid</param>
        /// <param name="valueAccessor" type="Object">The binding configuration in the form of an array of property names.</param>
 
        var config = ko.utils.unwrapObservable(valueAccessor());
        if (config.constructor !== Array) {
            return;
        }
 
        // Safely store the configuration and grid identifier within this binding context so the extension can be reused
        bindingContext.$data.__ejUpdateCellOnLostFocus = config;
        bindingContext.$data.__ejUpdateCellOnLostFocus_gridId = element.id;
 
        $(element).ejGrid({
            actionComplete: function(args) {
                /// <summary>Grid Action Complete handler to adapt Syncfusion Grids to requirements, see: https://goo.gl/Bni3P8 </summary>
                /// <param name="args" type="Object">The grid event arguments</param>
                switch (args.requestType) {
                case ej.Grid.Actions.BeginEdit:
                    {
                        // By using array, you can trigger multiple properties for auto-update
                        $.each(bindingContext.$data.__ejUpdateCellOnLostFocus, function(i, v) {
                            // Attach a focus out handler to each target property wrapper, the DOM elements are removed on end edit, so, no clean-up
                            args.row.find("#" + bindingContext.$data.__ejUpdateCellOnLostFocus_gridId + v + "_wrapper").on("focusout", function () {
                                // Update the row data property with the value from the hidden input for the cell
                                args.rowData[v] = args.row.find("#" + bindingContext.$data.__ejUpdateCellOnLostFocus_gridId + v + "_input").val();
                            });
                        });
                        break;
                    }
                }
            }
        });
    }
};

Prasanna Kumar Viswanathan [Syncfusion]
Replied On May 18, 2017 08:45 AM

Hi Robert, 

Thanks for providing the information. 

Please get back to us if you need any further assistance. 

Regards, 
Prasanna Kumar N.S.V 


Robert Mims
Replied On May 18, 2017 01:56 PM

One side-effect that I didn't notice when updating the row data value with focus out: it ends editing.

Is there some mutation observer or something that is causing an update to another property to end the edit operation?

Thank you.

Robert

Robert Mims
Replied On May 18, 2017 05:00 PM

To add a little more to the observed behavior. If I cancel the next grid event actionBegin -> refresh, the edit mode is retained and the underlying value updated - but not reflected within the grid.My multiple-revision question, then, is:I want to update the value without ending the continuous edit operations (tab from cell that just changed, whose value updated another) and have it reflected within the grid (given that I am using KnockoutJS.) In examining the KO Widget source, I believe the call to refreshTemplate is where I lose my edit state. 

Robert Mims
Replied On May 18, 2017 07:21 PM

Current state:

I've added a case to the actionComplete event that takes data from the BeginEdit and on Refresh instead of cancelling, it waits for 25ms and begins the edit again.

What I'd like to do is, using normal edit mode, select and edit the next cell within the grid.

I've tried (perhaps incorrectly) selectCells (e.g. [[ current row index, [ next column index]]] as the argument) to no avail. 

Given I am not in batch edit mode, is there a way to activate edit of a row and then a specific cell (column) within that row?

I've tried jQuery selectors, however, the internal state of the diagram changes based on invocations of methods/state management and the classes need to be changed too - so, it seems this is something that I need to accomplish with existing methods within the grid.

Thank you.

Robert

Prasanna Kumar Viswanathan [Syncfusion]
Replied On May 19, 2017 09:10 AM

Hi Robert, 

Before we proceed with your query, we need some clarifications.  

1. In focus out event do you need to update only the current cell value?  

2. “To add a little more to the observed behavior. If I cancel the next grid event actionBegin -> refresh, the edit mode is retained and the underlying value updated - but not reflected within the grid” 

Please provide more information for the above query.  

Regards, 
Prasanna Kumar N.S.V 


Robert Mims
Replied On May 19, 2017 09:21 AM

Answers:

1. Yes, and the underlying property change (Knockout Observable) has a subscription that changes the value of another bound column within the grid which should be reflected.

2. What I was describing here is that cancelling the next actionComplete event where the requestType is Refresh retained the edit mode state, however, that workflow was necessary in order to update the dependent cell value.

Ideally, we could decorate a column bound to a Knockout observable as updating immediately. The subscription on the observable in the dependent column would then update on change notification and the edit mode retained. 

My current binding handler workaround (though it doesn't retain the current edit column) looks like this where the grid row selection and start edit attempt to remedy that the refresh request updated the row template but ended the edit request and focus on the next cell after the BeginEdit -> FocusOut value assignment to the underlying view model observable:

ko.bindingHandlers.ejUpdateCellOnLostFocus = {
       init: function(element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {
           /// <summary>Initializes the Syncfusion Cell Property Update binding handler</summary>
           /// <param name="element" type="Object">The target Syncfusion Grid</param>
           /// <param name="valueAccessor" type="Object">The binding configuration in the form of an array of property names.</param>
 
           var config = ko.utils.unwrapObservable(valueAccessor());
           if (config.constructor !== Array) {
               return;
           }
 
          $(element).data("__ejUpdateCellOnLostFocus", config);
 
           $(element).ejGrid({
               actionComplete: function(args) {
                   /// <summary>Grid Action Complete handler to adapt Syncfusion Grids to requirements, see: https://goo.gl/Bni3P8 </summary>
                   /// <param name="args" type="Object">The grid event arguments</param>
                   switch (args.requestType) {
                   case ej.Grid.Actions.BeginEdit:
                       {
                           var gridId = args.target.id, properties = $(args.target).data("__ejUpdateCellOnLostFocus");
                           $.each(properties, function (i, v) {
                               args.row.find("#" + gridId + v + "_wrapper").on("focusout", function () {
                                   var val = args.row.find("#" + gridId + v + "_input").val();
                                   if (args.rowData[v] !== val) {
                                       $(args.target).data("__actionCompletedFor", { rowIndex: args.rowIndex, property: v });
                                       args.rowData[v] = val;
                                   }
                               });
                           });
                           break;
                       }
                   case ej.Grid.Actions.Refresh:
                       {
                           setTimeout(function() {
                                   var workaround = $(args.target).data("__actionCompletedFor");
                                   if (workaround) {
                                       var grid = $(args.target).data("ejGrid"),
                                           columnIndex = grid.getColumnIndexByField(workaround.property) + 1;
 
                                       grid.selectRows(workaround.rowIndex);
                                       grid.startEdit(grid.getRowByIndex(workaround.rowIndex));
                                       
                                       // TODO: Select the next cell and focus
 
                                       $(args.target).data("__actionCompletedFor", null);
                                   }
                               },
                               25);
                           break;
                       }
                   }
               }
           });
       }
   };

CONFIRMATION

This post will be permanently deleted. Are you sure you want to continue?

Sorry, An error occured while processing your request. Please try again later.

You are using an outdated version of Internet Explorer that may not display all features of this and other websites. Upgrade to Internet Explorer 8 or newer for a better experience.

;