Call controller before Edit command Grid

9 posts, 0 answers
  1. Leoni
    Leoni avatar
    9 posts
    Member since:
    Jul 2012

    Posted 01 Oct 2015 Link to this post

    I use the Ajax Editing to manage the record in my grid .
    I would like call the controller before edit the selected record to check if the record is not lock.
    I would like have this process :
       - Click on "Edit" buttom on grid,
       - Call the action controller to check the lock,
           -> If record lock, Abort Edit record,
           -> If record is not lock, Edit record.
     Do you know of a great way to make this process ?
    Thanks
    I set up a simple grid like this using the Razor syntax:

    @(Html.Kendo().Grid<GridCustomPopupTemplate.Models.Person>().Name("persons")
        .DataSource(dataSource => dataSource
            .Ajax()
            .Model(model => model.Id(m => m.PersonID))
            .Read(read => read.Action("GetPersons", "Home"))
            .Update(up => up.Action("UpdatePerson", "Home"))
        )
        .Columns(columns =>
        {
            columns.Bound(c => c.PersonID).Width(200);
            columns.Bound(c => c.Name);
            columns.Command(cmd => {
                cmd.Edit();
                });
        })
        .Pageable()
        .Sortable()
        .Editable(ed => ed.Mode(GridEditMode.PopUp).TemplateName("Person"))
    )

  2. Boyan Dimitrov
    Admin
    Boyan Dimitrov avatar
    1746 posts

    Posted 05 Oct 2015 Link to this post

    Hello Leoni,

     

    My suggestion is to use a custom command button as shown in the Grid / Custom command demo, make the request to the server to check whether the selected record is locked and based on the response open the popup editor for the data item. This could be done by calling the editRow method of the Kendo UI DataSoure and pass the jQuery row element. 

     

     

     

    Regards,
    Boyan Dimitrov
    Telerik
    Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Feedback Portal and vote to affect the priority of the items
  3. UI for ASP.NET MVC is VS 2017 Ready
  4. Leoni
    Leoni avatar
    9 posts
    Member since:
    Jul 2012

    Posted 06 Nov 2015 in reply to Boyan Dimitrov Link to this post

    Thank you Boyan for your answer.
    I have used  the basic custom command buttons and "edit" event to call action controller with ajax request.The ajax request check the record status : lock or unlock :
    - If record is locked then the record is null and the popup edit is close. This process work fine.
    - If record is unlocked then record return the last version record (record different of Master grid, if an user has modified the record after display of the grid).
    My issue being that the trigger event of the "update" buttom doesn't work after update the setting the model (set.model). The "CTCO_PRENOM" field content the last value, but the popup edit is always display after click "update". 
    I have noticed that the "requestEnd" event type of datasource return "undefined" (See enclosed file).

    Why the trigger event of the "update" buttom is disabled after the ajax return ?

    I'm beginning to use telerik UI for asp .net mvc and i don't know if a good way for edit record of master grid. I found examples with the partial Views.

    What is your suggestion ?
    I continue this way or change method. Do you have a code library aspnet-mvc to explain this process ?
    Regards.

    View Master Grid:

    <div class="col-xs-18 col-md-12">
        @* Grille "Contact" *@
        @(Html.Kendo().Grid<CSE.Model.ContactEntity>().Name("grid")
        .Columns(columns =>
        {
            // Command disponible au niveau de la grille
            columns.Command(command =>
            {
                command.Edit();
                command.Destroy();
            }).Width(200);
            columns.Bound(p => p.CTCO_ID);
            columns.Bound(p => p.CTCO_CIVILITE);
            columns.Bound(p => p.CTCO_PRENOM);
            columns.Bound(p => p.CTCO_EMAIL);
            columns.Bound(p => p.CTCO_FONCTION).Filterable(ftb => ftb.Multi(true));
            columns.Bound(p => p.CTCO_LIB);
            })
            .ToolBar(toolbar => toolbar.Create())
            // Mode d'édition
            .Editable(editable =>
                {
                 editable.Mode(GridEditMode.PopUp).TemplateName("ContactResultEntityTable");
                })
            .Pageable()
            .Events(e =>
                {
                    // Edit event to call action controller
                    e.Edit("onRequestEdit");
                    e.Cancel("onRequestClose");
                })
            .Sortable()
                    .Filterable()
            .DataSource(dataSource => dataSource
                        .Ajax()
                        .PageSize(20)
                        .Model(model =>
                            {
                                model.Id(p => p.ID);
                            })
                        .Events(events =>
                        {
                            events.Error("onError");
                            events.RequestEnd("onRequestEnd");
                        })
                        .Create(update => update.Action("Create", "Contacts"))
                        .Update(update => update.Action("Update", "Contacts"))
                        .Destroy(update => update.Action("Destroy", "Contacts"))
                        .Read(r Optionsead => read.Action("Search", "Contacts").Data("additionalInfo")
                        )
                )
        )
    </div>

     Javascript in View :

    // Event : Edit Record (coté client): Appel Controller "CheckLock"
    function onRequestEdit(arg) {
     
        // get model
        var model = arg.model;
        //model.sender.read();
        alert("onRequestEdit");
        kendoConsole.log("onRequestEdit : Edit : " + model.CTCO_ID + ":" + model.CTCO_PRENOM);
        grid = $("#grid").data("kendoGrid");
        // Appel de la méthode "CheckLock" en passant ID du contact pour vérifier le lock sur l'enregistrement.
        $.ajax({
            url: '@Url.Action("CheckLock", "Contacts")',
            type: 'POST',
            data: { ID: model.CTCO_ID },
            //data: JSON.stringify(model),//{ contactAtLock: model.},
            datatype : 'json',
            success: function (result) {
                //if (result.rlock) {
                if (result.contact != null && result.contact !== undefined) {
                    // Edit de l'enregistrement possible
                    alert('onRequestEdit : Edit record :' + result.contact.CTCO_ID + "Prenom->" + result.contact.CTCO_PRENOM);
                    // Mise à jour de l'enregistrement
                    for (var property in result.contact) {
                            model.set(property, result.contact[property]);
                    }
                }
                if (result.contact == null) {
                    // Edition de l'enregistrement impossible
                    alert('Edit: Record verrouillé par un autre utilisateur');
                    $('span.k-i-close').click();
                }
            },
            error: function () { alert('Error in popup edit'); }
        })
    }
     
    // Event : Abort Edit (coté client): Appel Controller "UnLock"
    function onRequestClose(arg) {
        var model = arg.model;
        // Call de la méthode "UnLock" en passant ID du contact pour vérifier le lock sur l'enregistrement.
        $.ajax({
            url: '@Url.Action("UnLock", "Contacts")',
            data: { ID: model.CTCO_ID },
            success: function (result) {
                if (result.rlock) {
                    // Enregistrement courant déverouillé
                    alert('onRequestClose : Record unlock');
                }
            }
        })
    }
     
    // Event : Edit End : Forcer la lecture de la source en cas d'update (Spécifique au Template Custom)
    function onRequestEnd(e) {
        kendoConsole.log("onRequestEnd : Start : event type :" + e.type);
        if (e.type == "update") {
            alert("onRequestEnd : Update");
            //Get Grid
            var grid = $("#grid").data("kendoGrid");
            grid.dataSource.read();
        }
    }
     
    function onError(e, status) {
        if (e.errors) {
            var message = "There are some errors:\n";
            // Create a message containing all errors.
            $.each(e.errors, function (key, value) {
                if ('errors' in value) {
                    $.each(value.errors, function () {
                        message += this + "\n";
                    });
                }
            });
            // Display the message
            alert(message);
            // Cancel the changes
            var grid = $("#grid").data("kendoGrid");
            grid.cancelChanges();
        }
    }

    My Template PopupEdit (Form) :

    @model CSE.Model.ContactEntity
    <html>
    <head>
        <title>My Custom PopUpEdit</title>
    </head>
    <body>
        <div id="inputWindow" class="responsive-table-line" style="margin:0px auto;max-width:700px;">
            <table class="table table-bordered table-condensed table-body-center">
                <tbody>
                    <br />
                    @Html.HiddenFor(model => model.ID)
                    <tr>
                        <td>
                            <div class="form-group">
                                @Html.LabelFor(model => model.CTCO_CIVILITE)
                            </div>
                        </td>
                        <td>
                            <div class="form-group">
                                @Html.EditorFor(model => model.CTCO_CIVILITE)
                                @Html.ValidationMessageFor(model => model.CTCO_CIVILITE)
                            </div>
                        </td>
                    </tr>
                    <tr>
                        <td>
                            <div class="form-group">
                                @Html.LabelFor(model => model.CTCO_LIB)
                            </div>
                        </td>
                        <td>
                            <div class="form-group">
                                <div class="form-group">
                                    @Html.EditorFor(model => model.CTCO_LIB)
                                    @Html.ValidationMessageFor(model => model.CTCO_LIB)
                                </div>
                            </div>
                        </td>
                    </tr>
                    <tr>
                        <td>
                            <div class="form-group">
                                @Html.LabelFor(model => model.CTCO_PRENOM)
                            </div>
                        </td>
                        <td>
                            <div class="form-group">
                                @Html.EditorFor(model => model.CTCO_PRENOM)
                                @Html.ValidationMessageFor(model => model.CTCO_PRENOM)
                            </div>
                        </td>
                    </tr>
                    <tr>
                        <td>
                            <div class="form-group">
                                @Html.LabelFor(model => model.CTCO_EMAIL)
                            </div>
                        </td>
                        <td>
                            <div class="form-group">
                                @Html.EditorFor(model => model.CTCO_EMAIL)
                                @Html.ValidationMessageFor(model => model.CTCO_EMAIL)
                            </div>
                        </td>
                    </tr>
                    <tr>
                        <td>
                            <div class="form-group">
                                @Html.LabelFor(model => model.CTCO_FONCTION)
                            </div>
                        </td>
                        <td>
                            <div class="form-group">
                                @Html.EditorFor(model => model.CTCO_FONCTION)
                                @Html.ValidationMessageFor(model => model.CTCO_FONCTION)
                            </div>
                        </td>
                    </tr>
                    <tr>
                        <td>
                            <div class="form-group">
                                @Html.LabelFor(model => model.CTCO_PUBLIC)
                            </div>
                        </td>
                        <td>
                            <div class="form-group">
                                @Html.EditorFor(model => model.CTCO_PUBLIC)
                                @Html.ValidationMessageFor(model => model.CTCO_PUBLIC)
                            </div>
                        </td>
                    </tr>
                </tbody>
            </table>
        </div>
    </body>
    </html>

    Controller :

    [AcceptVerbs(HttpVerbs.Post)]
    public ActionResult CheckLock([DataSourceRequest] DataSourceRequest request, int ID)
    //public ActionResult CheckLock(ContactEntity contactAtLock)
    {
        ContactEntity cto = null;
        ContactEntity lastVersionContact = null;
        if (ModelState.IsValid)
        {
            // Vérifier que l'enregistrement courant n'est pas verrouillé par un autre utilisateur
            //IManager manager = new ContactManager();
            InitManager();
     
            (manager as ContactManager).AuthenticationManager = (IAuthenticationManager)Session["UserManager"];
             
            //A l'ouverture de la fiche : Verifier si le contact peut être éditer
            //todo: cto a stocker
            cto = manager.EditElement(ID) as ContactEntity;
             
            //Vérifier si on peut modifier
            if (manager.CanEdit(ID))
            {
                // Simuler Modification du record si valeur différente de la grille
                cto.CTCO_PRENOM = "lastVersion_" + cto.CTCO_PRENOM;
     
                lastVersionContact = cto;
            }
        }
        return Json(new { contact = lastVersionContact }, JsonRequestBehavior.AllowGet); //.ToDataSourceResult(request, ModelState));
        //return Json(new[] { lastVersionContact }.ToDataSourceResult(request, ModelState));
    }
     
    // Déverrouiller l'enregistrement
    [AcceptVerbs(HttpVerbs.Post)]
    public ActionResult UnLock(int ID)
    {
        var result = false;
        if (ModelState.IsValid)
        {
            InitManager();
            (manager as ContactManager).AuthenticationManager = (IAuthenticationManager)Session["UserManager"];
     
            //var entity = manager.EditElement(ID);
            //todo: supprimer
            var entity = manager.GetElement(ID);
     
            // Si utilisateur annule les modifications
            manager.Release(entity);
     
            result = true;
             
        }
        return Json(new { rlock = result }, JsonRequestBehavior.AllowGet);
    }
     
    // MàJ un "Contact"
    [AcceptVerbs(HttpVerbs.Post)]
    public ActionResult Update([DataSourceRequest] DataSourceRequest request, ContactEntity contact)
    {
        bool hasErrors = ModelState.Values.Any(x => x.Errors.Count > 1);
        
        // Test
        if (contact != null && ModelState.IsValid)
        {
            int id = contact.ID;
     
            // Récupérer le manager courant
            InitManager();
            (manager as ContactManager).AuthenticationManager = (IAuthenticationManager)Session["UserManager"];
     
            // Travailler Directement avec l'entitié récupérer 
            var entity = (ContactEntity)contact;
     
            // A la fermeture de la fiche
            // Si utilisateur clic sur save
            manager.Save(entity);
            // Si utilisateur annule les modifications
            //manager.Release(entity);
        }
        return Json(new[] { contact }.ToDataSourceResult(request, ModelState));
    }

  5. Boyan Dimitrov
    Admin
    Boyan Dimitrov avatar
    1746 posts

    Posted 10 Nov 2015 Link to this post

    Hello Leoni,

    Actually the "Update" button in the popup editor will perform an update request to the server. Basically what you are trying to achieve is to perform a validation before the actual update. 

    In this case there is another possible solution: to prevent the default behavior when the "Update" button is clicked in order to perform the validation. If it is successful to call the sync method of the Kendo UI DataSource and if not - to show a message or something else. 

    Preventing the default behavior when "Update" button is clicked can be done in the save event handler of the Kendo UI Grid. Please refer to the code snippet below:

     

    save: function(e){
        e.preventDefault();
          //here goes the validation logic and so on
    },

    In order to get the Kendo UI DataSource for the gird widget you can use the dataSource property of the Kendo UI Grid widget. 

     

     

    Regards,
    Boyan Dimitrov
    Telerik
    Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Feedback Portal and vote to affect the priority of the items
  6. Leoni
    Leoni avatar
    9 posts
    Member since:
    Jul 2012

    Posted 12 Nov 2015 in reply to Boyan Dimitrov Link to this post

    Hello Boyan,

    Yes, I would like to update the popup Edit with the last version record from the database after the lock.

    I followed your suggestions, but the update method is not called after sync DataSource. I modified :

    Add : save event handler of kendi UI Grid :

     @(Html.Kendo().Grid<CSE.Model.ContactEntity>().Name("grid")
        .Columns(columns =>

        ....

    .Events(e =>
                {
                    // Edit event to call action controller
                    e.Edit("onRequestEdit");
                    e.Cancel("onRequestClose");
                    e.Save("onRequestSave"); // SM 10/11/2015
                })

     Add save function :

    function onRequestSave(arg) {
            kendoConsole.log("Grid data onRequestSave");
            arg.preventDefault;
            kendoConsole.log("Grid data onRequestSave : preventDefault");
            var grid = $("#grid").data("kendoGrid");
            grid.dataSource.sync();  // The Update method is not called ?
        }

     I have forgotten somebody ? 

    Thanks.

    Regards.

  7. Leoni
    Leoni avatar
    9 posts
    Member since:
    Jul 2012

    Posted 13 Nov 2015 in reply to Leoni Link to this post

    In addition to the reply below :

    For "CheckLock" method in Controller :

    [AcceptVerbs(HttpVerbs.Post)]
            public ActionResult CheckLock([DataSourceRequest] DataSourceRequest request, int ID)
            //public ActionResult CheckLock(ContactEntity contactAtLock)
            {
                ContactEntity cto = null;
                ContactEntity lastVersionContact = null;
                if (ModelState.IsValid)
                {
                     
                    //IManager manager = new ContactManager();
                    InitManager();
                    (manager as ContactManager).AuthenticationManager = (IAuthenticationManager)Session["UserManager"]; // SM 03/09/2015
                     
                    cto = manager.EditElement(ID) as ContactEntity;
                     
                    //Check modified
                    if (manager.CanEdit(ID))
                    {
                        // Simulate update record in database (data different of grid)
                        cto.CTCO_PRENOM = "lastVersion_" + cto.CTCO_PRENOM;
     
                        lastVersionContact = cto;
                    }
                }
                // Return last version record to update all fields in popupEdit
                return Json(new { contact = lastVersionContact }, JsonRequestBehavior.AllowGet);
                 
            }

    Event : onRequestEdit() event grid :

    function onRequestEdit(arg) {
    ....
    $.ajax({
                url: '@Url.Action("CheckLock", "Contacts")',
                type: 'POST',
                data: { ID: model.CTCO_ID },
                //data: JSON.stringify(model),//{ contactAtLock: model.},
                datatype: 'json',
                success: function (result) {
                    if (result.contact != null && result.contact !== undefined) {
                        for (var property in result.contact) {
                                // SM 13/11/2015 : Update record in popup Edit
                                arg.model.set(property, result.contact[property]);
                            //}
                        }
    }
    if (result.contact == null) {
                        // Close automatically PopPup
                        alert('Edit: Record verrouillé par un autre utilisateur');
                        $('span.k-i-close').click();
                    }

  8. Boyan Dimitrov
    Admin
    Boyan Dimitrov avatar
    1746 posts

    Posted 16 Nov 2015 Link to this post

    Hello Leoni,

     

    The preventDefault is actually a method, so it should be called as a method: 

    arg.preventDefault();

    Please find attached a sample project that implements the desired behavior. 

     

    Regards,
    Boyan Dimitrov
    Telerik
    Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Feedback Portal and vote to affect the priority of the items
  9. Leoni
    Leoni avatar
    9 posts
    Member since:
    Jul 2012

    Posted 16 Nov 2015 in reply to Boyan Dimitrov Link to this post

    Hello Boyan,

    Thank you for your sample project.
    I have seen this error in my code.

    I compared and checked my code but i don't understand why the update bottom action is not called after "sync" DataSource in onRequestSave event. The edit popup display until.
    I was wondering what the real problem is.
    The issue may be with the update record process after the ajax resquest (see below) because this process disables the status of master grid (change row). In addition, the "RequestEnd" event of master grid return "undefined". why ?
    See enclosed, the controller and view code files.
     I ask myself if this is possible.
    What is your opinion?

    Thanks,

    Regards.

  10. Boyan Dimitrov
    Admin
    Boyan Dimitrov avatar
    1746 posts

    Posted 18 Nov 2015 Link to this post

    Hello Leoni,

     

    Calling the sync method of the Kendo UI DataSource in the save event handler of the Kendo UI Grid is not supported scenario. At this time the model is not updated with the new value ( the event is preventable). My suggestion is to have a button that will call the sync method of the Kendo UI DataSource. 

     

    Regards,
    Boyan Dimitrov
    Telerik
    Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Feedback Portal and vote to affect the priority of the items
Back to Top
UI for ASP.NET MVC is VS 2017 Ready