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

Submit entire form, including grids

12 Answers 218 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.
Ricardo
Top achievements
Rank 1
Ricardo asked on 05 Jun 2012, 02:13 PM
Hi, I have the following scenario:
A master table named Basket;
Two child tables named Fruits and Others.

I want to submit the entire form at once, having on the same page the fields from the master table Basket and the two grids, both as batch editing.

Do you have any nice solution for this?

I'm already able to do this, but requires too much writing, since $('#Grid').data('tGrid').insertedDataItems() can't be bind like [Bind(Prefix = "inserted")]IEnumerable<Fruits> insertedFruits.

Ricardo Schroeder

12 Answers, 1 is accepted

Sort by
0
Daniel
Telerik team
answered on 08 Jun 2012, 09:34 AM
Hello Ricardo,

You can use the serializeData client-side method to transform the array returned from the insertedDataItems method into a format that can be handled by the ModelBinder e.g.
var grid = $("#Grid").data("tGrid");
var updated = grid.serializeData(grid.updatedDataItems(), "updated");
var inserted = grid.serializeData(grid.insertedDataItems(), "inserted");
var data = $.extend({}, updated, inserted);

Regards,
Daniel
the Telerik team
If you want to get updates on new releases, tips and tricks and sneak peeks at our product labs directly from the developers working on the Telerik Extensions for ASP.MET MVC, subscribe to their blog feed now.
0
Ricardo
Top achievements
Rank 1
answered on 08 Jun 2012, 01:02 PM
I was able to do, but, not to pass to controller. I'll explain.

That's my asp page:
<%= Html.EditorFor(m => m.Id)%> <!-- Shows up two input fields(for the basket), that's all -->
<%= Html.Telerik()
            .Grid(Model.Fruits)
            .Name("GridFruits")
            .ToolBar(toolbar =>
            {
                toolbar.Insert();
            })
            .DataKeys(dataKeys => dataKeys.Add(a => a.Id))
            .DataBinding(dataBinding =>
            {
                dataBinding.Ajax().Insert("Insert", "Baskets");
                dataBinding.Ajax().Delete("Delete", "Baskets");
            })
            .Columns(columns =>
            {
                columns.Bound(b => b.Name);
                columns.Bound(b => b.Amount);
                columns.Command(command =>
                {
                    command.Delete();
                });
            })
            .KeyboardNavigation(k => k.EditOnTab(true).Enabled(true))
            .Editable(editable => editable.Mode(GridEditMode.InCell))
    %>
    <br />
    <%= Html.Telerik()
            .Grid(Model.Others)
            .Name("GridOthers")
            .ToolBar(toolbar =>
            {
                toolbar.Insert();
            })
            .DataKeys(dataKeys => dataKeys.Add(a => a.Id))
            .DataBinding(dataBinding =>
            {
                dataBinding.Ajax().Insert("Insert", "Baskets");
      dataBinding.Ajax().Update("Update", "Baskets"); 
                dataBinding.Ajax().Delete("Delete", "Baskets");
            })
            .Columns(columns =>
            {
                columns.Bound(b => b.Name);
                columns.Bound(b => b.Amount);
                columns.Command(command =>
                {
                    command.Delete();
                });
            })
            .KeyboardNavigation(k => k.EditOnTab(true).Enabled(true))
            .ClientEvents(events => events.OnSubmitChanges("onSubmitChanges"))
            .Editable(editable => editable.Mode(GridEditMode.InCell))
    %>
    <br />
    <input type="button" value="Save" onclick="onClick()" class="t-button" />


And then the javascript:
function onSubmitChanges(e) {
    var gridFruits = $('#GridFruits').data('tGrid');
  
    var gridFruitsUpdated = gridFruits.serializeData(gridFruits.updatedDataItems(), "gridFruitsUpdated");
    var gridFruitsInserted = gridFruits.serializeData(gridFruits.insertedDataItems(), "gridFruitsInserted");
    var gridFruitsDeleted = gridFruits.serializeData(gridFruits.deletedDataItems(), "gridFruitsDeleted");
  
    var data = $.extend({}, gridFruitsInserted, gridFruitsUpdated, gridFruitsDeleted);
  
    e.values = data;
  
    e.values.BasketName = $("#BasketName").val();
    e.values.BasketDescription = $("#BasketDescription").val();
}
  
function onClick() {
    var gridOthers = $('#GridOthers').data('tGrid');
    gridOthers.submitChanges();
}

And my controller:
[GridAction]
        public ActionResult Update(
            [Bind(Prefix = "inserted")]IEnumerable<Others> insertedOthers,
            [Bind(Prefix = "updated")]IEnumerable<Others> updatedOthers,
            [Bind(Prefix = "deleted")]IEnumerable<Others> deletedOthers,
            Basket basket,
            [Bind(Prefix = "gridFruitsInserted")]IEnumerable<Fruits> insertedFruits,
            [Bind(Prefix = "gridFruitsDeleted")]IEnumerable<Fruits> deletedFruits,
            [Bind(Prefix = "gridFruitsUpdated")]IEnumerable<Fruits> updatedFruits,
            FormCollection f)
        {
            [...] // CODE
        }

Doing like this, I can only get the inserted, updated and deleted from the second grid(others grid).

If I do this other way on my javascript, it works, but it's too much code, if I have more columns in the grid, even more code.
function onSubmitChanges(e) {
    var gridFruits = $('#GridFruits').data('tGrid');
 
    e.values.BasketName = $("#BasketName").val();
    e.values.BasketDescription = $("#BasketDescription").val();
  
    var inserted = gridFruits.insertedDataItems();
 
    for (var i = 0;i < inserted.length;i++) {
      e.values["gridFruitsInserted[" + i + "].Name"] = inserted[i].Name;
      e.values["gridFruitsInserted[" + i + "].Amount"] = inserted[i].Amount;
    }
 
    var updated = gridFruits.updatedDataItems();
 
    for (var j = 0; j < updated.length; j++) {
      e.values["gridFruitsUpdated[" + j + "].Name"] = updated[j].Name;
      e.values["gridFruitsUpdated[" + j + "].Amount"] = updated[j].Amount;
    }
 
    var deleted = gridFruits.deletedDataItems();
 
    for (var k = 0; k < deleted.length; k++) {
      e.values["gridFruitsDeleted[" + k + "].Name"] = deleted[k].Name;
      e.values["gridFruitsDeleted[" + k + "].Amount"] = deleted[k].Amount;
    }
}
  
function onClick() {
    var gridOthers = $('#GridOthers').data('tGrid');
    gridOthers.submitChanges();
}
0
Accepted
Daniel
Telerik team
answered on 11 Jun 2012, 02:35 PM
Hello again Ricardo,

The values from the other Grid will not be send with the request because the values parameter is overridden:

e.values = data;
The rest of the code looks correct and extending the values parameter instead should resolve the problem e.g.
e.values =  $.extend(e.values, gridFruitsInserted, gridFruitsUpdated, gridFruitsDeleted);

 
Greetings,
Daniel
the Telerik team
If you want to get updates on new releases, tips and tricks and sneak peeks at our product labs directly from the developers working on the Telerik Extensions for ASP.MET MVC, subscribe to their blog feed now.
0
Ricardo
Top achievements
Rank 1
answered on 11 Jun 2012, 03:34 PM
It works perfectly, thanks Daniel.
0
Ricardo
Top achievements
Rank 1
answered on 18 Jun 2012, 01:50 PM
Daniel, it's me again.

I have a new problem now with the following example:
Table State: Id, Name
Table City: Id, Name, StateId

Table Customer: Id, Name.
Table CustomerAddress: Id, Street, Number, CityId
Table CustomerPhones: Id, PhoneNumber, CustomerAddressId

Think this as an atomic insert, all(Customer, CustomerAddress, CustomerPhone) in one page and everything must be inserted or nothing will be.
I have to fill the customer name in one field, add the customer's addresses, in a grid and add the phone numbers to a specific address.
Also, to add the address in the grid, I'll have two combobox, one with the state and one with the city, as a cascade combobox.

Any thoughts?

Thanks for any reply.
0
Daniel
Telerik team
answered on 21 Jun 2012, 09:47 AM
Hello Ricardo,

I am not sure if I understand the issue. Could you provide more detailed information on the problem you are experiencing or the needed functionality?

Kind regards,
Daniel
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
Ricardo
Top achievements
Rank 1
answered on 22 Jun 2012, 12:23 PM
Hello Daniel,

What I'm trying to accomplish here is to build one page with 3 input fields, from one class, one grid with cascade combobox from another class and another grid, which is the child from the prior grid, from another class, but I want to save it all at once.

Is there a way to do this? What do you recommend?
0
Daniel
Telerik team
answered on 26 Jun 2012, 12:22 PM
Hello Ricardo,

You could use a custom Ajax request to post the data and save the all changes with one request. The approach used for formatting the sent data should also work in this scenario but the Grids should be reloaded with the ajaxRequest or rebind client-side methods in order for the changes to be accepted.

Regards,
Daniel
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
Ricardo
Top achievements
Rank 1
answered on 26 Jun 2012, 12:26 PM
Hello Daniel,

What kind of grid editing mode should I use to do this? InCell, InLine, PopUp?

I've tried with InCell, which seems to me the most obvious, but during InCell mode I'm not able to do cascade comboboxes.

Att,
Ricardo Schroeder
0
Daniel
Telerik team
answered on 28 Jun 2012, 02:30 PM
Hi again Ricardo,

You should use InCell editing mode in order to post all the values with one request. In all other modes the values will be posted automatically after updating, deleting or inserting a row. 
Regarding the ComboBoxes - the built-in cascading functionality cannot be used in this mode as they will not be shown at the same time. You could cascade the items shown in the dependent ComboBox by binding the items in the OnEdit event with the dataBind method based on the value in the dataItem. You could also use the ComboBox OnDataBinding event to get the value from the closest row and send it with the request. I attached a sample project which implements the first approach. I hope it helps.

Regards,
Daniel
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
Michael
Top achievements
Rank 1
answered on 01 Aug 2012, 08:21 PM
var grid = $("#Grid").data("tGrid");
var updated = grid.serializeData(grid.updatedDataItems(), "updated");
var inserted = grid.serializeData(grid.insertedDataItems(), "inserted");
var data = $.extend({}, updated, inserted);

For the above, I need to do something similar.  I need to combine the serialized form with the grid data.
Something like this...
$('#myForm').submit(function (e) {
     var grid = $('#UnitGrid').data('tGrid');
     var serializedForm = $(this).serialize();
     var serializedGrid = grid.serializeData(grid.insertedDataItems(), "inserted");
     var data = $.extend({}, serializedForm, serializedGrid);
}

But the problem is that the form gets serialized into a string, so after .extend(), that string gets broken up into many properties (one for each character in the string).  How can I merge the grid data in with the form so that I can keep my model?

Controller:
[HttpPost]
        public ActionResult Index(FormCollection frmCollection, MyModel model, IEnumerable<MyGridRowViewModel> inserted)
        {
}

Thanks in advance
0
Svetlana
Top achievements
Rank 1
answered on 03 Aug 2012, 01:57 AM
Hi Michael, I have a similar problem. I can't use the suggested solution with grid.submitChanges() because it is not called them grid has not been modified; but my form needs to be submitted with all values and a grid no matter if a grid has been modified or not.

So I decided to pass data from a grid in the hidden fields.
$('#btnSave').click(function () {
    var grid = $('#Grid').data('tGrid');
 
    $('#inserted').val(JSON.stringify(grid.insertedDataItems()));
    $('#updated').val(JSON.stringify(grid.updatedDataItems()));
    $('#deleted').val(JSON.stringify(grid.deletedDataItems()));
     
    $("#form").submit();
 
});

And in my controller I deserialize values
public ActionResult UpdateForm(MyFormModel model, FormCollection f)
        {
//...
            JavaScriptSerializer jsSerializer = new JavaScriptSerializer();
            IList<MyGridModel> inserted = jsSerializer.Deserialize<MyGridModel[]>(f["inserted"]).ToList<MyGridModel>();
            IList<MyGridModel> updated = jsSerializer.Deserialize<MyGridModel[]>(f["updated"]).ToList<MyGridModel>();
            IList<MyGridModel> deleted = jsSerializer.Deserialize<MyGridModel[]>(f["deleted"]).ToList<MyGridModel>();
//...
 }

My grid is very small so it works for me.
Tags
Grid
Asked by
Ricardo
Top achievements
Rank 1
Answers by
Daniel
Telerik team
Ricardo
Top achievements
Rank 1
Michael
Top achievements
Rank 1
Svetlana
Top achievements
Rank 1
Share this question
or