Auto save row when moving to the next row

8 posts, 0 answers
  1. Tim
    Tim avatar
    10 posts
    Member since:
    Oct 2015

    Posted 12 Aug Link to this post

    Hi,

    Is there a way to auto save a row when you've finished editing and moved to another next row either by tabbing to the next row or editing a cell on another row?

    I'm using InCell mode.

    Regards,
    Tim

  2. Preslav
    Admin
    Preslav avatar
    233 posts

    Posted 15 Aug Link to this post

    Hi Tim,

    To automatically sync any changes in the Grid, set the autoSync configuration of the DataSource to true.
    For example, check this Dojo: http://dojo.telerik.com/AcEHu

    Furthermore, syncing the changes will rebind the Grid thus, the current focus will be lost. To overcome this problem, I would suggest checking the approach outlined in this How To article:
    I hope the above helps. Do not hesitate to write back if I can assist you with any further information.


    Regards,
    Preslav
    Progress Telerik
    Try our brand new, jQuery-free Angular 2 components built from ground-up which deliver the business app essential building blocks - a grid component, data visualization (charts) and form elements.
  3. Tim
    Tim avatar
    10 posts
    Member since:
    Oct 2015

    Posted 15 Aug in reply to Preslav Link to this post

    Hi Preslav,

    Thanks for the update, however, I know how to configure auto-sync. My question was more specific in that I wanted to auto-sync when leaving the row and not the cell.

    Regards,

    Tim

     

  4. Preslav
    Admin
    Preslav avatar
    233 posts

    Posted 15 Aug Link to this post

    Hi again,

    Thank you for elaborating on the scenario and please excuse me for misunderstanding the first post.

    To achieve the desired functionality, I will suggest:
    1. Removing the autoSync configuration.
    2. Handle the edit event of the Grid.
    3. Get the index of the row.
    4. Based on the row index, manually invoke the sync method of the data source.

    http://docs.telerik.com/kendo-ui/api/javascript/ui/grid#events-edit
    http://docs.telerik.com/kendo-ui/api/javascript/data/datasource#methods-sync

    For example, I used and modified the code from the article from my last reply, now it looks like:

    <!DOCTYPE html>
    <html>
    <head>
        <meta charset="utf-8"/>
        <title>Kendo UI Snippet</title>
     
     
        <script src="https://code.jquery.com/jquery-1.12.4.min.js"></script>
    </head>
    <body>
       
    <div id="grid"></div>
     
    <script>
      $(function () {
        var crudServiceBaseUrl = "//demos.telerik.com/kendo-ui/service",
            dataSource = new kendo.data.DataSource({
              transport: {
                read:  {
                  url: crudServiceBaseUrl + "/Products",
                  dataType: "jsonp"
                },
                update: {
                  url: crudServiceBaseUrl + "/Products/Update",
                  dataType: "jsonp"
                },
                destroy: {
                  url: crudServiceBaseUrl + "/Products/Destroy",
                  dataType: "jsonp"
                },
                create: {
                  url: crudServiceBaseUrl + "/Products/Create",
                  dataType: "jsonp"
                },
                parameterMap: function(options, operation) {
                  if (operation !== "read" && options.models) {
                    return {models: kendo.stringify(options.models)};
                  }
                }
              },
              batch: true,
              autoSync: false,
              pageSize: 5,
              schema: {
                model: {
                  id: "ProductID",
                  fields: {
                    ProductID: { editable: false, nullable: true },
                    ProductName: { validation: { required: true } },
                    UnitPrice: { type: "number", validation: { required: true, min: 1} },
                    Discontinued: { type: "boolean" },
                    UnitsInStock: { type: "number", validation: { min: 0, required: true } }
                  }
                }
              }
            });
     
        var rowIndex = null;
        var cellIndex = null;
        var saveButtonClicked = false;
        var editCell = false;
     
        $("#grid").kendoGrid({
          dataSource: dataSource,
          navigatable: true,
          pageable: true,
          height: 300,
          toolbar: ["create", "save", "cancel"],
          columns: [
            "ProductName",
            { field: "UnitPrice", title: "Unit Price", format: "{0:c}", width: 120 },
            { field: "UnitsInStock", title: "Units In Stock", width: 120 },
            { field: "Discontinued", width: 120 },
            { command: "destroy", title: " ", width: 150 }],
          editable: true,
          saveChanges: function(e) {
            saveButtonClicked = true;
          },
          dataBinding: function(e) {
            var current = e.sender.current() || [];
            if (current[0]) {
              cellIndex = current.index();
              rowIndex = current.parent().index();
            }
          },
          edit: function(e){
            var index = e.sender.current().parent().index();
             
            if(rowIndex === null){
              rowIndex = index;
            }else{
              if(rowIndex != index){
                rowIndex = null;
                editCell = true;
                 
                e.sender.dataSource.sync();
              }
            }
          },
          dataBound: function(e) {
            if (!isNaN(cellIndex)) {
              e.sender.current(e.sender.tbody.children().eq(rowIndex).children().eq(cellIndex));
              rowIndex = cellIndex = null;
     
              // The code below is needed only when the user clicks on the "Save Changes" button.
              // Otherwise, focusing the table explicitly and unconditionally can steal the page focus.
              if (saveButtonClicked) {
                e.sender.table.focus();
                saveButtonClicked = false;
              }
              if(editCell){
                editCell = false;
                 
                e.sender.editCell(e.sender.current());
              }         
            }
          }
        });
      });
    </script>
    </body>
    </html>

    For a runnable example, check this Dojo: https://dojo.telerik.com/AcAQi

    I hope this helps.


    Regards,
    Preslav
    Progress Telerik
    Try our brand new, jQuery-free Angular 2 components built from ground-up which deliver the business app essential building blocks - a grid component, data visualization (charts) and form elements.
  5. Tim
    Tim avatar
    10 posts
    Member since:
    Oct 2015

    Posted 15 Aug in reply to Preslav Link to this post

    Hi Preslav,

    Superb, it works very well, thank you :)

    Regards,

    Tim

  6. Tim
    Tim avatar
    10 posts
    Member since:
    Oct 2015

    Posted 15 Aug in reply to Preslav Link to this post

    Hi Preslav,

    Superb, it works very well, thank you.

    Regards,

    Tim

  7. Tim
    Tim avatar
    10 posts
    Member since:
    Oct 2015

    Posted 16 Aug in reply to Preslav Link to this post

    Hi Preslav,

    It appears I was a little hasty in my response as I now get some string effects - every time I click in a cell (this cell has a DropDownList) then click another row the grid performs the sync but it also refocuses back to row 1 even though I've applied all the changes you demonstrated.

    I am using MVC, would this make any difference?

    Could you provide an MVC example?

    Regards,

    Tim

  8. Preslav
    Admin
    Preslav avatar
    233 posts

    Posted 17 Aug Link to this post

    Hello Tim,

    Using the MVC wrappers should not make any difference. I was not able to replicate the problem with DropDownList editor in an MVC Grid.

    For a base, I used the "Grid / Editing custom editor" demo:
    Now, the code in the "editing_custom.cshtml" page looks like:

    @(Html.Kendo().Grid<Kendo.Mvc.Examples.Models.ProductViewModel>()
        .Name("grid")
        .Columns(columns =>
        {
            columns.Bound(p => p.ProductName);
            columns.Bound(p => p.Category).ClientTemplate("#=Category.CategoryName#").Width(180);
            columns.Bound(p => p.UnitPrice).Width(130);
            columns.Command(command => command.Destroy()).Width(150);
        })
        .ToolBar(toolBar =>
        {
            toolBar.Create();
            toolBar.Save();
        })
        .Editable(editable => editable.Mode(GridEditMode.InCell))
        .Events(e=> {
            e.SaveChanges("saveChanges");
            e.DataBinding("dataBinding");
            e.Edit("edit");
            e.DataBound("dataBound");
        })
        .Pageable()
        .Sortable()
        .Navigatable()
        .Scrollable()
        .HtmlAttributes(new { style = "height:550px;" })
        .DataSource(dataSource => dataSource
            .Ajax()
            .Batch(true)
            .ServerOperation(false)
            .Events(events => events.Error("error_handler"))
            .Model(model =>
            {
                model.Id(p => p.ProductID);
                model.Field(p => p.ProductID).Editable(false);
                model.Field(p => p.Category).DefaultValue(
                    ViewData["defaultCategory"] as Kendo.Mvc.Examples.Models.CategoryViewModel);
            })
            .PageSize(20)
            .Read(read => read.Action("EditingCustom_Read", "Grid"))
            .Create(create => create.Action("EditingCustom_Create", "Grid"))
            .Update(update => update.Action("EditingCustom_Update", "Grid"))
            .Destroy(destroy => destroy.Action("EditingCustom_Destroy", "Grid"))
        )
    )
     
    <script type="text/javascript">
        var rowIndex = null;
        var cellIndex = null;
        var saveButtonClicked = false;
        var editCell = false;
     
        function error_handler(e) {
            if (e.errors) {
                var message = "Errors:\n";
                $.each(e.errors, function (key, value) {
                    if ('errors' in value) {
                        $.each(value.errors, function() {
                            message += this + "\n";
                        });
                    }
                });
                alert(message);
            }
        }
     
        function saveChanges(e) {
            saveButtonClicked = true;
        }
     
        function dataBinding(e) {
            var current = e.sender.current() || [];
            if (current[0]) {
                cellIndex = current.index();
                rowIndex = current.parent().index();
            }
        }
     
        function edit(e){
            var index = e.sender.current().parent().index();
             
            if(rowIndex === null){
                rowIndex = index;
            }else{
                if(rowIndex != index){
                    rowIndex = null;
                    editCell = true;
                 
                    e.sender.dataSource.sync();
                }
            }
        }
        function dataBound(e) {
            if (!isNaN(cellIndex)) {
                e.sender.current(e.sender.tbody.children().eq(rowIndex).children().eq(cellIndex));
                rowIndex = cellIndex = null;
     
                // The code below is needed only when the user clicks on the "Save Changes" button.
                // Otherwise, focusing the table explicitly and unconditionally can steal the page focus.
                if (saveButtonClicked) {
                    e.sender.table.focus();
                    saveButtonClicked = false;
                }
                if(editCell){
                    editCell = false;
                 
                    e.sender.editCell(e.sender.current());
                }         
            }
        }
     
     
    </script>

    If the above does not help, in order to continue my investigation, could you please prepare and share an isolated Dojo that clearly replicates the problem? If sending a Dojo is not doable, you can send us an MVC project.

    Regards,
    Preslav
    Progress Telerik
    Try our brand new, jQuery-free Angular 2 components built from ground-up which deliver the business app essential building blocks - a grid component, data visualization (charts) and form elements.
Back to Top