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

[Solved] Send changes in grid.data() to controller

5 Answers 114 Views
Grid
This is a migrated thread and some comments may be shown as answers.
This question is locked. New answers and comments are not allowed.
Raúl
Top achievements
Rank 1
Raúl asked on 19 Jun 2012, 09:33 AM

Hi, I have the next problem:
I have a grid, and I must can edit your check cells, and after send the changes to my controller for saving data in session var.
I need do it manual, without the grid.

My grid code is:

@(Html.Telerik().Grid<ThomsonReuters.InfolexWeb.UI.Models.SelectInvolvedNotificationListItem>()
                    .Name("MatterInstancePersonsNotificationGrid")
                    .DataKeys(keys => keys.Add(m => m.InvolvedName))
                    .Columns(columns =>
                    {                       
                        columns.Bound(m => m.MatterInstancePersonID)
                            .Width(0);
                        columns.Bound(m => m.PersonID)
                            .ClientTemplate("")
                            .Title("")
                            .Filterable(false)
                            .Width(25);
                        columns.Bound(m => m.PersonID)
                            .ClientTemplate("")
                            .Title("")
                            .Filterable(false)
                            .Width(25);                                                                 
                        columns.Bound(m => m.Selected)
                            .ClientTemplate("<input type='checkbox' name='IsSelected' id='IsSelected' onclick='SetNotifyCheck(this)' <#= Selected?\"checked\":\"\" #>/>")
                            .Title(CommunicationResource.To)
                            .Filterable(false)
                            .Width(45);
                        columns.Bound(m => m.InvolvedType).Width(70).Column.Title = CommunicationResource.InvolvedRoleType;
                        columns.Bound(m => m.InvolvedName).Width(140).Column.Title = CommunicationResource.InvolvedName;
                        columns.Bound(m => m.WrittingID)
                            .Width(0);
                        columns.Bound(m => m.Writting)
                            .Width(140)
                            .ClientTemplate("<a href='javascript:ChangeWriting(<#= InvolvedID #>)'><img src='/Content/images/ico_template.png'/></a> <#= Writting #>")
                            .Title(CommunicationResource.Writing);
                        columns.Bound(m => m.SelectedLetter)
                            .ClientTemplate("<input type='checkbox' name='IsSelectedLetter' id='IsSelectedLetter' onclick='LetterIsChanged(this)' <#= SelectedLetter?\"checked\":\"\" #> />")                                                                                   
                            .Title(CommunicationResource.Letter)
                            .Filterable(false)
                            .Width(40);
                        columns.Bound(m => m.SelectedMail)
                            .ClientTemplate("<input type='checkbox' name='IsSelectedMail' id='IsSelectedMail' onclick='MailIsChanged(this)' <#= SelectedMail?\"checked\":\"\" #> />")
                            .Title(CommunicationResource.Mail)
                            .Filterable(false)
                            .Width(40);
                        columns.Bound(m => m.InvolvedMailAddress)
                            .Width(140)
                            .Title(CommunicationResource.InvolvedMailAddress);
                        columns.Bound(m => m.InvolvedTypeID).Hidden(true);                            
                        columns.Bound(m => m.PersonID).Hidden(true);                            
                        columns.Bound(m => m.InvolvedID).Hidden(true);
                    })
                    .Pageable(paging => paging.PageSize(20))                  
                    .Scrollable(c => c.Height("100px"))                        
                    .ClientEvents(events => events
                            .OnRowDataBound("onRowDataBound"))
                    .Selectable()
                    .Filterable()
                    .Sortable()                   
                        .DataBinding(dataBinding => dataBinding.Ajax().Select("SearchGridMatterInstancePersonsNotification", "Matters"))
)


This is the javascript code where I want send my data to controller.
The problem is if I click in any check cell, and I inspect the grid.data now, this data haven't been updated and have the initial values from databinding. By this reason, the data are not sent correctly to my controller action.

How I can fix it?

function SaveRecievers() {   
        var grid = $('#MatterInstancePersonsNotificationGrid').data('tGrid');
        var data = grid.data;               
 
        $.ajax({
            type: "POST",
            url: "/Matters/SaveInvolvedsCommunicationsSession",
            data: { source: Sources.Action, JsonInvolveds: JSON.stringify(data) },
            dataType: "json",
            error: function (xhr, status, error) {
                alert(error);
            },
            success: function (data) {
                ...
            }
        });
 
 
    }



5 Answers, 1 is accepted

Sort by
0
Petur Subev
Telerik team
answered on 22 Jun 2012, 08:59 AM
Hi Raúl,

Changes made to the ClientTemplate are not taken into account. You could get all the data items and implement logic which on click updates their values depending on the checkbox state. In order to recognize which dataItem is related with the clicked checkbox, you could find the closest tr element and pass it to the dataItem method of the Grid which will return you the actual data item. Then you could use that item and its id to find the item in your copy of item and update the boolean field.

All the best,
Petur Subev
the Telerik team
Check out the successor of Telerik MVC Extensions - Kendo UI for ASP.NET MVC - and deem it for new ASP.NET MVC development.
0
Raúl
Top achievements
Rank 1
answered on 22 Jun 2012, 09:55 AM
Hello, I have managed to update the data grid manually doing this:
function LetterIsChanged(chk, rowIndex) { 
    var grid = $("#MatterInstancePersonsNotificationGrid").data("tGrid");
    var gridPageDataModel = grid.dataSource._data;       
    gridPageDataModel[rowIndex].SelectedLetter = chk.checked;
}

But when the JSON.stringify(data)arrives at the action in the controller (string JsonInvolveds) and try to parse the json data to a list of my model, the Boolean fields that I have updated in the view, not are deserialized correctly.
[Authorize()]
public ActionResult SaveInvolvedsCommunicationsSession(RecieverSource source, string JsonInvolveds)
{
//...
System.Web.Script.Serialization.JavaScriptSerializer jss = new System.Web.Script.Serialization.JavaScriptSerializer();
List<SelectInvolvedNotificationListItem> lst0 = jss.Deserialize<List<SelectInvolvedNotificationListItem>>(JsonInvolveds);
Session["PersonsNotifyActionCollection"] = lst0;
//...
return new EmptyResult();
}

For example: I recieved this Json data:

[{"MatterInstancePersonID":6,"Selected":true,"InvolvedType":"Cliente","InvolvedTypeID":1,"InvolvedName":"ROBERTO MARTINE","PersonID":3,"InvolvedID":6,"SelectedLetter":false,"SelectedMail":true,"WrittingID":22,"Writting":"NOTIFICACION EXPEDIENTE","InvolvedMailAddress":"raul.garcia@thomsonreuters.com","Index":0},{"MatterInstancePersonID":8,"Selected":false,"InvolvedType":"Responsable","InvolvedTypeID":5,"InvolvedName":"LAURA GARCIA","PersonID":2,"InvolvedID":8,"SelectedLetter":true,"SelectedMail":true,"WrittingID":22,"Writting":"NOTIFICACION EXPEDIENTE","InvolvedMailAddress":"juan.camarero@thomsonreuters.com","Index":1},{"MatterInstancePersonID":31,"Selected":false,"InvolvedType":"Contrario","InvolvedTypeID":2,"InvolvedName":"DANIEL PEREZ PEREZ","PersonID":9,"InvolvedID":31,"SelectedLetter":false,"SelectedMail":false,"WrittingID":22,"Writting":"NOTIFICACION EXPEDIENTE","InvolvedMailAddress":"juan.camarero@thomsonreuters.com","Index":2},{"MatterInstancePersonID":36,"Selected":false,"InvolvedType":"Letrado","InvolvedTypeID":3,"InvolvedName":"LAURA JUAREZ ROJO","PersonID":44,"InvolvedID":36,"SelectedLetter":false,"SelectedMail":false,"WrittingID":22,"Writting":"NOTIFICACION EXPEDIENTE","InvolvedMailAddress":"","Index":3},{"MatterInstancePersonID":37,"Selected":false,"InvolvedType":"Cliente","InvolvedTypeID":1,"InvolvedName":"LAURA GARCIA","PersonID":2,"InvolvedID":37,"SelectedLetter":false,"SelectedMail":false,"WrittingID":22,"Writting":"NOTIFICACION EXPEDIENTE","InvolvedMailAddress":"juan.camarero@thomsonreuters.com","Index":4},{"MatterInstancePersonID":38,"Selected":false,"InvolvedType":"Colaborador","InvolvedTypeID":7,"InvolvedName":"Colaborador Colaborador","PersonID":64,"InvolvedID":38,"SelectedLetter":false,"SelectedMail":false,"WrittingID":22,"Writting":"NOTIFICACION EXPEDIENTE","InvolvedMailAddress":"","Index":5},{"MatterInstancePersonID":39,"Selected":false,"InvolvedType":"Cliente","InvolvedTypeID":1,"InvolvedName":"LAURA GARCIA","PersonID":2,"InvolvedID":39,"SelectedLetter":false,"SelectedMail":false,"WrittingID":22,"Writting":"NOTIFICACION EXPEDIENTE","InvolvedMailAddress":"juan.camarero@thomsonreuters.com","Index":6},{"MatterInstancePersonID":40,"Selected":false,"InvolvedType":"Letrado","InvolvedTypeID":3,"InvolvedName":"MARÍA DE LAS CUEVAS","PersonID":6,"InvolvedID":40,"SelectedLetter":false,"SelectedMail":false,"WrittingID":22,"Writting":"NOTIFICACION EXPEDIENTE","InvolvedMailAddress":"maria@prueba.es","Index":7}]

In bold are the fields I updated in the view and and have been received correctly in the controller, but after deserialized, this fields are false in mi model. I don't understand!
0
Petur Subev
Telerik team
answered on 26 Jun 2012, 03:29 PM
Hello again Raúl,

I tried to deserializethe the JSON to List of objects with the same properties and everything works fine. I am not sure if the problem is in the deserialization. What exactly you mean by "this fields are false in mi model" ? Probably the data you display is not the updated one - i.e. lst0 list from your code snippet.

Regards,
Petur Subev
the Telerik team
Check out the successor of Telerik MVC Extensions - Kendo UI for ASP.NET MVC - and deem it for new ASP.NET MVC development.
0
Jason
Top achievements
Rank 1
answered on 02 Nov 2012, 09:58 PM
Greetings Petur,

I am having the same issue as Raul, from his original post. I have values in my client template that I need sent to my controller. I am using jQuery to submit my data. Just as Raul had discovered, grid.data only has the original values, and the client template values are not being captured. I found your original response to him a bit hard to understand and I haven't fully grasped how to use dataItem. Would it be possible for you to post a sample script showing the solution you recommended to him?

"In order to recognize which dataItem is related with the clicked checkbox, you could find the closest tr element and pass it to the dataItem method of the Grid which will return you the actual data item. Then you could use that item and its id to find the item in your copy of item and update the boolean field.".

I've been searching through the forums and even stackoverflow to find a solution closest enough for me to even modify to fit my needs, however no such luck, hence my request.

VIEW:
@(Html.Telerik().Grid<TankDips_>()
                .Name("TankListView")
                .DataBinding(db =>
                    db.Ajax()
                        .OperationMode(GridOperationMode.Client)
                        .Select("_Select_TankDips", "Tanks", new { id = poNum })
                )
                .Columns(c =>
                {
                    c.Bound(cb => cb.TankID).Width(40);
                    c.Bound(cb => cb.FuelGrade).Width(40);
                    c.Bound(cb => cb.IsReceived)
                        .ClientTemplate("<input type='checkbox' id='IsReceived' name='IsReceived' />")
                        .Title("Received")
                        .HeaderHtmlAttributes(new { style = "text-align:center" })
                        .Width(25)
                        .HtmlAttributes(new { style = "align:center" });
                    c.Bound(cb => cb.PreDip)
                        .ClientTemplate("<input type='text' id='PreDip' name='PreDip' readonly='readonly' style='width:80px' class='right-align' />")
                        .Title("Pre-Dip")
                        .HeaderHtmlAttributes(new { style = "text-align:center" });
                    c.Bound(cb => cb.PostDip)
                        .ClientTemplate("<input type='text' id='PostDip' name='PostDip' readonly='readonly' style='width:80px' class='right-align' />")
                        .Title("Post-Dip");
                    c.Bound(cb => cb.IsTempDips).Hidden(true);
                })
                .ClientEvents(events =>
                {
                    events.OnRowDataBound("TanksList_onRowDataBound");
                    events.OnError("TanksList_onError");
                    events.OnDataBound("UpdateGridText");
                })
                .Sortable()
                .NoRecordsTemplate("Retrieving Data, please wait...")
                 
            )

JAVASCRIPT
// enable/disable readonly status on textbox in TanksListView grid
function TanksList_onRowDataBound(e) {
    //the DOM element (<tr>) representing the row which is being databound
    var row = e.row;
    //the data item - JavaScript object.
    var dataItem = e.dataItem;
    var grid = $("#TankListView").data("tGrid");
 
    // find the checkbox defined in the template column
    // and subscribe to its change event
    $(row).find("input:checkbox")
        .change(function () {
            // input elements in the row
            if ($(this).is(":checked")) {
                // remove the readonly attribute
                //alert("Checkbox checked");
                $(row).find("#PreDip").removeAttr("readonly");
                $(row).find("#PostDip").removeAttr("readonly");
 
                gridDataModel[$(row).
            }
            else {
                // add the readonly attribute
                $(row).find("#PreDip").attr("readonly", "readonly");
                $(row).find("#PreDip").val("");
                $(row).find("#PostDip").attr("readonly", "readonly");
                $(row).find("#PostDip").val("");
            }
    });
}
 
// Form Submit
$("form").submit(function (fh) {
 
    // gather form information
    var extra = {
        IsTempPO: true,
        TransactionID: $("#TransactionTypeID").val()
    };
    // gather grid data
    var gridview_dips = $("#TankListView").data("tGrid");
    var dips_data = JSON.stringify(gridview_dips.data);
    console.log(dips_data);
 
    fh.preventDefault();
    // various $.post requests using the above data
}

Thank you in advance for you assistance,
Jason
0
Jason
Top achievements
Rank 1
answered on 06 Nov 2012, 08:05 PM
I finally figured it out, based on Petur's original suggestion, re-reading the client-side api documentation and some searches which lead me to this thread, I eventually modified my JavaScript to get the result I wanted.

function TanksList_onRowDataBound(e) {
    //the DOM element (<tr>) representing the row which is being databound
    var row = e.row;
    //the data item - JavaScript object.
    var dataItem = e.dataItem;
    var grid = $("#TankListView").data("tGrid");
    var gridDataModel = grid.dataSource._data;
    var tr = $(row).closest("tr");
    var rowIndex = tr[0].rowIndex - 1; // offset the index, as grid.data uses zero based indexing
 
    // find the checkbox defined in the template column
    // and subscribe to its change event
    $(row).find("input:checkbox")
        .change(function () {
            // input elements in the row
            if ($(this).is(":checked")) {
                // remove the readonly attribute
                //alert("Checkbox checked");
                $(row).find("#PreDip").removeAttr("readonly");
                $(row).find("#PostDip").removeAttr("readonly");
                gridDataModel[rowIndex].IsRecieved = true; // update the grid data
            }
            else {
                // add the readonly attribute
                $(row).find("#PreDip").attr("readonly", "readonly");
                $(row).find("#PreDip").val("");
                $(row).find("#PostDip").attr("readonly", "readonly");
                $(row).find("#PostDip").val("");
                gridDataModel[rowIndex].IsRecieved = false;
            }
        });
 
        $(row).find("#PreDip")
        .change(function () {
            gridDataModel[rowIndex].PreDip = $(this).val(); // update the grid data
        });
 
        $(row).find("#PostDip")
        .change(function () {
            gridDataModel[rowIndex].PostDip = $(this).val();
        });
}

I used the same OnRowDataBound event handler to attach to the elements (checkbox and textbox) change events. I hope this helps anyone else who hit on this brick wall.

I'm sure someone else who has a better grasp on javascript can optimize the above, if you can and have, please feel free to share it.

Thanks everyone,
Jason
Tags
Grid
Asked by
Raúl
Top achievements
Rank 1
Answers by
Petur Subev
Telerik team
Raúl
Top achievements
Rank 1
Jason
Top achievements
Rank 1
Share this question
or