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

Kendo Grid Template Input onChange

4 Answers 2860 Views
Grid
This is a migrated thread and some comments may be shown as answers.
Marvin
Top achievements
Rank 1
Marvin asked on 28 Jun 2013, 05:50 AM
Hello,

Is it possible to to change the value(recalculate) the cell of the "Total" column in the grid while the user types in a "Quantity"(input)?  This is a shopping list grid, there is a "Price" (bound column) and I need to calculate the Total dynamically based on the Quantity that the user will input. Maybe I'm doing it wrong, can you please point me to the right direction? Thanks,

var gridResult = $("#grid").kendoGrid({
    dataSource: {
        type: "aspnetmvc-ajax",
        //                     type: "json",
        transport: {
            read: "Home/Products_Read"
        },
        schema: {
            data: "data",
            total: "total",
            model: {
                id: "products",
                fields: {
                    Code: { editable: false },
                    Number: { editable: false },
                    Name: { editable: false },
                    Supplier: { editable: false },
                    Price: { editable: false, type: "number" },
                    Quantity: { editable: true, type: "number" },
                    Total: { editable: true, type: "number" }
                }
            }
        },
        pageSize: 20,
        serverPaging: true,
        serverFiltering: true,
        serverSorting: true
    },
    selectable: "row",
    sortable: true,
    pageable: true,
    columns: [
        { field: "Number", title: "Number", width: "100px" },
        { field: "Name", title: "Name" },
        { field: "Supplier", title: "Supplier", width: "100px" },
        { field: "Price", title: "Price", width: "100px", format: "{0:n}" },
        { field: "Quantity", title: "Quantity", width: "100px", template: '<input data-role="numerictextbox" data-bind="value: Quantity" data-max-value="100" class="quantityTextArea" />' },
        { field: "Total", title: "Total", width: "100px", template: "#= Price #" }
        ],
    rowTemplate:
        '<tr data-uid="#= Code #">' +
            '<td><span>${Number}</span></td>' +
            '<td><span>${Name}</span></td>' +
            '<td><span>${Supplier}</span></td>' +
            '<td><span>${Price}</span></td>' +
            '<td><input data-role="numerictextbox" data-bind="value: Quantity" data-max-value="100" class="quantityTextArea" /></td>' +
            '<td>#=Price*Quantity#</td>' +
        '</tr>'
});

4 Answers, 1 is accepted

Sort by
0
Jayesh Goyani
Top achievements
Rank 2
answered on 28 Jun 2013, 01:15 PM
Hello,

Please try with below code snippet.
<div id="Grid">
</div>
<script>
 
 
    $(document).ready(function () {
 
 
 
 
        $("#Grid").kendoGrid({
            dataSource: {
                type: "Data",
                transport: {
                    read: "http://localhost/Home/GetDummydata"
                },
                schema: {
                    model: {
                        fields: {
                            ID: { type: "number" },
                            Name: { type: "string" },
                            Price: { type: "number" },
                            Quantity: { type: "number" },
                            Total: { type: "number" }
                        }
                    }
                },
                pageSize: 10,
                serverPaging: true,
                serverFiltering: true,
                serverSorting: true
            },
 
            filterable: true,
            sortable: true,
            pageable: true,
            columns: [
            { field: "ID", title: "ID" },
            { field: "Name", title: "Name" },
            { field: "Price", title: "Price", width: "100px", format: "{0:n}" },
        { field: "Quantity", title: "Quantity", width: "100px", template: '<input data-role="numerictextbox" data-bind="value: Quantity" data-max-value="100" class="quantityTextArea" />' },
        { field: "Total", title: "Total", width: "100px", template: "#= Price #" }
        ],
            rowTemplate:
            '<tr>' +
            '<td><span>${ID}</span></td>' +
            '<td><span>${Name}</span></td>' +
            '<td><span>${Price}</span></td>' +
            '<td><input data-role="numerictextbox" id="someInput" name=#=ID# value=#=Quantity# data-max-value="100" class="quantityTextArea" /></td>' +
            '<td>#=Price*Quantity#</td>' +
        '</tr>'
        });
 
        $('#someInput').live('change', function () {
             
            var grid = $("#Grid").data("kendoGrid");
 
            for (var i = 0; i < grid.dataSource.data().length; i++) {
                if (parseInt(grid.dataSource.data()[i].ID) == parseInt($(this).attr('name'))) {
                    grid.dataSource.data()[i].Quantity = $(this).val();
                }
            }
            grid.refresh();
        });
    });
</script>
[AllowAnonymous]
       [HttpGet]
       public JsonResult GetDummydata()
       {
           List<TestModels> models = new List<TestModels>();
 
           for (int i = 1; i < 6; i++)
           {
               TestModels t1 = new TestModels();
               t1.ID = i;
               t1.Name = "Name" + i;
               t1.Price = i;
               t1.Quantity = 1;
               t1.Total = 1;
               models.Add(t1);
           }
 
           return Json(models, JsonRequestBehavior.AllowGet);
       }
[Serializable]
public class TestModels
{
    public int ID { get; set; }
    public string Name { get; set; }
    public int Price { get; set; }
    public int Quantity { get; set; }
    public int Total { get; set; }
}


Thanks,
Jayesh Goyani
0
Alexander Valchev
Telerik team
answered on 02 Jul 2013, 06:54 AM
Hello guys,

I would like to point out that using an ID inside the column/row template is not recommended. In almost all cases the template will render more than once, in case its elements have an ID this will result in invalid HTML. Please use class instead:

'<td><input data-role="numerictextbox" class="someInput" name=#=ID# value=#=Quantity# data-max-value="100" class="quantityTextArea" /></td>'

By default the template will not be bound to a ViewModel, so the input will not be enhanced to NumericTextBox widget nor the binding will be evaluated (data-bind="value: Quantity").

One possible way to configure such scenario is to hook up to the change event of the .someInput element as Jayesh suggested. But instead of using the "=" operator to modify the data item's value, please work with the set method of the Model. In this way the Grid will be notified for the change and will refresh automatically, respectively the calculated column ('<td>#=Price*Quantity#</td>') will be re-evaluated.

Last but not least, the data-uid attribute should contain the uid of the data item. Please do not fill it with other values.
'<tr data-uid="#= Code #">'
'<tr data-uid="#= uid #">'

I hope this will help.

Regards,
Alexander Valchev
Telerik
Join us on our journey to create the world's most complete HTML 5 UI Framework - download Kendo UI now!
0
Sandro
Top achievements
Rank 1
answered on 17 Jul 2013, 10:23 AM

I tried doing what you suggested, but still no luck.. Did I use the Set correctly?

columns: [
                    { field: "Code", title: "Code", width: "100px" },
                    { field: "Number", title: "Number", width: "100px" },
                    { field: "Name", title: "Name" },
                    { field: "Supplier", title: "Supplier", width: "100px" },
                    { field: "Price", title: "Price", width: "100px", format: "{0:n}" },
                    { field: "UnitStock", title: "Unit", width: "100px" },
                    { field: "Quantity", title: "Quantity", width: "100px", template: '<input name=#=Code# class="quantityTextArea" value=#=Quantity# />' },
                    { field: "Total", title: "Total", width: "100px", template: '#=Price*Quantity#' },
                    ]
            });

 

$('#quantityTextArea').on('change', function () {
 
                for (var i = 0; i < gridResult.dataSource.data().length; i++) {
                    if (parseInt(gridResult.dataSource.data()[i].Code) == parseInt($(this).attr('name'))) {                       
                        gridResult.dataSource.data()[i].Quantity.Set($(this).val());
                    }
                }
                gridResult.refresh();
            });
0
Alexander Valchev
Telerik team
answered on 18 Jul 2013, 08:11 AM
Hi Sandro,

I noticed two issues in the provided code:
  1. The selector is incorrect, the input should be selected by class (not ID)

    $('#quantityTextArea') -> $('.quantityTextArea')

  2. The set method starts with lowercase letter and accepts two parameters - the name of the field whose value is going to be returned and the new value of the field. For more information please check the corresponding documentation:

    http://docs.kendoui.com/api/framework/observableobject#methods-set


Regards,
Alexander Valchev
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
Marvin
Top achievements
Rank 1
Answers by
Jayesh Goyani
Top achievements
Rank 2
Alexander Valchev
Telerik team
Sandro
Top achievements
Rank 1
Share this question
or