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

Kendo Grid - MVC and client-side add/edit/delete

6 Answers 3389 Views
Grid
This is a migrated thread and some comments may be shown as answers.
Mike
Top achievements
Rank 1
Mike asked on 24 Feb 2015, 10:18 PM
Please see my two questions below.

I'm using Kendo UI with MVC and Razor.

I have a page with header fields, and a grid.

The goal: When page is saved to database, one row is inserted for header data, and multiple rows are inserted into another table for each grid row (each row has foreign key to header row). Obviously, if I add a new header, the grid will be empty, and when I add rows to the grid, I don't have a foreign key yet, because the header data hasn't been saved yet.

What seems to be the best approach: The grid data will to be maintained client-side. In the initial page load, the grid will get data from the server (if there is data); then adding and deleting rows will be done on the client without any communication with the server. When user clicks "save" to save header and grid data, the view should post post the all the data, including the grid data, to a controller on the server.

Question 1: Can someone please provide me with some direction on how to do this, perhaps point me to some online examples?

I've started looking into how to do this, and ran into the following issue:

1) I have the grid defined in cshtml view:

            <div class="row">

                @(Html.Kendo().Grid<CapEdit2.Models.Matrix>()
                    .Editable(e => e.Mode(GridEditMode.InLine))               
                    .Name("NewGrid")
                    .DataSource(d => d
                        .Ajax()
                        .ServerOperation(false)
                        .Model(mod => mod.Id(m => m.Id))
                        .Read(r => r
                            .Action("MatrixRead", "Report")
                            .Data("matrixReadData")
                        )
                    )
                    .Columns(c =>
                        {
                            c.Bound(m => m.Id);
                            c.Bound(m => m.IncludeRecordDate).Title("Include Record Date");
                            c.Bound(m => m.IncludeExDate).Title("Include Ex Date");
                            c.Bound(m => m.IncludeTransDate).Title("Include Trans Date");
                            c.Bound(m => m.Ddf).Title("DDF");
                            c.Bound(m => m.IssueDescription).Title("Issue Description");
                            c.Bound(m => m.Cusip).Title("Cusip");
                            c.Bound(m => m.Amount).Title("Amount");
                            c.Bound(m => m.UsMarketValue).Title("Market Value");
                            c.Bound(m => m.CchBasisFactor).Title("CCH Basis Factor");
                            c.Bound(m => m.LocalMarketValue).Title("Local Market Value");
                            c.Bound(m => m.FractionalRate).Title("Fractional Rate");
                        }
                    )
                )

2. I have an "Add row" button, that calls this code:

        var grid = $('#MyGrid').data('kendoGrid');
        grid.addRow();

3. The issue: First time I click the button, a row is added. Second, and all subsequent times I click the button, a new row replaces the existing row, and the grid apparently has one row, and never has more than one row, no matter how many times I click "add row".

Question 2: Can someone tell me why I'm seeing this issue?

Thank you for your help!
Mike



6 Answers, 1 is accepted

Sort by
0
Daniel
Telerik team
answered on 27 Feb 2015, 08:40 AM
Hello Mike,

You could pass the grid data initially and use the DataSource Custom builder to configure a local client-side dataSource so that adding and delete is performed only client-side without request to the server:
@(Html.Kendo().Grid<CapEdit2.Models.Matrix>(GridData)
    .Editable(e => e.Mode(GridEditMode.InLine))              
    .Name("NewGrid")
    .DataSource(d => d
        .Custom()
        .Schema(schema=> schema
           .Model(mod => mod.Id(m => m.Id))
        )
    )

If the data should initially be populated via Ajax then you should again use the Custom builder to specify custom functions for the transport operations and make the request manually for read.
I am not sure if I understand how should the data be posted but if a form is used in your scenario then you can use the approach demonstrated in this code-library to include the grid data.

The other issue will occur because the grid is configured for inline editing. In this mode you should use an edit column command and sync the changes by pressing the update button. You should use InCell editing if an edit buttons should not be used and the changes should not be synchronized. If InLine editing should be used for the grid, the you should use custom functions for the transport operations and assign some non default id to the new items on create.
 
Regards,
Daniel
Telerik
 
Join us on our journey to create the world's most complete HTML 5 UI Framework - download Kendo UI now!
 
0
Mike
Top achievements
Rank 1
answered on 01 Mar 2015, 06:08 PM
Thank you Daniel. I will give that a try.
0
Mike
Top achievements
Rank 1
answered on 23 Mar 2015, 04:33 PM
Thanks again Daniel. I have some more questions about this:

I followed the example you provided a link to, and was able to run the grid client-side, while adding and deleting rows, and posting the grid to the controller on "save". That's great news for me! However, the one main problem I'm having is that boolean values are displayed as "true" or "false" (not good) and edited as check boxes (good). Is there a way to make booleans display as check boxes, while still using the ClientTemplate property for storing value in hidden form variable?

Here's what I'm using -- it works and behaves just like I described above, and displays the boolean as "true" or "false":

@(Html.Kendo().Grid(Model.MatrixLines)
      .Name("Matrix")
      .ToolBar(tools => tools.Create().Text("Add new Matrix"))
      .Editable(editable => editable.Mode(GridEditMode.InCell).CreateAt(GridInsertRowPosition.Bottom))
      .Columns(columns =>
      {

 columns.Bound(p => p.Id).Hidden().ClientTemplate("#= Id #" +
   "<input type='hidden' name='MatrixLines[#= index(data)#].Id' value='#= Id #' />"
 );

 columns.Bound(p => p.IncludeRecordDate).ClientTemplate("#= IncludeRecordDate #" +
     "<input type='hidden' name='IncludeRecordDate[#= index(data)#].IncludeRecordDate' value='#= IncludeRecordDate #' />"
 ).Title("Include Record Date");


 columns.Command(command => command.Destroy()).Width(100);
      })
      .DataSource(dataSource => dataSource.Ajax()
  .Model(model => 
      {
  model.Id(p => p.Id);
  model.Field(p => p.Id).Editable(false);
      })
  .ServerOperation(false)
      )
)

Thanks,
Mike

0
Daniel
Telerik team
answered on 25 Mar 2015, 12:58 PM
Hi,

You can include a checkbox instead of the true / false text in the same template:
columns.Bound(p => p.IncludeRecordDate).ClientTemplate("<input type='checkbox' #if (IncludeRecordDate) {# checked='checked'#}# disabled />" +
    "<input type='hidden' name='IncludeRecordDate[#= index(data)#].IncludeRecordDate' value='#= IncludeRecordDate #' />"
).Title("Include Record Date");


Regards,
Daniel
Telerik
 
Join us on our journey to create the world's most complete HTML 5 UI Framework - download Kendo UI now!
 
0
Mike
Top achievements
Rank 1
answered on 25 Mar 2015, 03:24 PM
Thanks again Daniel. That has gotten me closer to the completed solution. One more little thing: The values of the check boxes (after user changes them) aren't being posted back to the controller. Is there a short-hand way of getting the check box values into the corresponding hidden array, or should I create jQuery script to accomplish this?

Thanks,
Mike
0
Daniel
Telerik team
answered on 27 Mar 2015, 08:42 AM
Hello Mike,

Sorry I missed that the name is incorrect. Should be:
columns.Bound(p => p.IncludeRecordDate).ClientTemplate("<input type='checkbox' #if (IncludeRecordDate) {# checked='checked'#}# disabled />" +
    "<input type='hidden' name='MatrixLines[#= index(data)#].IncludeRecordDate' value='#= IncludeRecordDate #' />"
).Title("Include Record Date");
in order for the value to be bound. 

Regards,
Daniel
Telerik
 
Join us on our journey to create the world's most complete HTML 5 UI Framework - download Kendo UI now!
 
Tags
Grid
Asked by
Mike
Top achievements
Rank 1
Answers by
Daniel
Telerik team
Mike
Top achievements
Rank 1
Share this question
or