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

Kendo grid with numberEditor and validation

6 Answers 2771 Views
General Discussions
This is a migrated thread and some comments may be shown as answers.
Jim
Top achievements
Rank 1
Jim asked on 31 May 2018, 09:03 AM

I am using a kendo grid for user input and for each parameter I have a max and min value. I managed to implement a validation so that the user cannot input a value outside the limits and if a value outside the range is entered there is a text shown “Value must be between <max> and <min>”. This was done via a validation function.

Now to be more flexible with number of decimals, I added a number editor to the input column. After this it is still not possible for the user to enter a value outside the range, which is good, but the text is not showing. Why is this and what can I do to get this text back although I am using a number editor?

 

    this.myDataSource = new kendo.data.DataSource({
        autoSync: true,
        data: [
            { label: "Parameter1",  ref: 89.82, min: 60,    max: 100,   isInput: true },
            { label: "Parameter2",  ref: 9.18,  min: 8,     max: 20,    isInput: false }
        ],
        schema: {
            model: {
                fields: {
                    label: { type: "string", editable: false },
                    ref: {
                        validation: {
                            required: true,
 
                            validateFunction: function (isInput) {
                                return OfflinePredictionController.validateInput("#myGrid", isInput);
                            }
                        }
                    },
                    min: { type: "number", editable: false },
                    max: { type: "number", editable: false },
                    isInput: { type: "boolean", editable: false }
                }
            }
        },
    });
     
 
    $("#myGrid").kendoGrid({
        dataSource: this.myDataSource,
        scrollable: false,
        editable: true,
        columns: [
            {
                field: "label",
                title: "Parameter",
            },
            {
                field: "ref",
                title: "Reference",
                editor: numberEditor,
                width: "140px",
            },
            {
                hidden: true,
                field: "min",
                width: "30px"
            },
            {
                hidden: true,
                field: "max",
                width: "30px"
            },
            {
                hidden: true,
                field: "isInput",
                width: "40px"
            }
        ]
    });
 
 
static validateInput(gridName: string, input: any) {
 
    var minIndex = 0;
    var maxIndex = 0;
    var grid = $(gridName).data("kendoGrid");
 
    for (var columnIndex = 0; columnIndex < grid.columns.length; columnIndex++) {
        if (grid.columns[columnIndex].field == "min") {
            minIndex = columnIndex;
        }
        else if (grid.columns[columnIndex].field == "max") {
            maxIndex = columnIndex;
        }
    }
 
    var reference = $(input).val();
    var min = parseFloat($(input).closest("tr").find("td:eq(" + minIndex + ")").text());
    var max = parseFloat($(input).closest("tr").find("td:eq(" + maxIndex + ")").text());
 
    if ((reference < min) || (reference > max)) {
        input.attr("data-validateFunction-msg", "Value must be between " + min + " and " + max);
        return false;
    }
    return true;         
}

 

function numberEditor(container, options) {
    $('<input name="' + options.field + '"/>').appendTo(container).kendoNumericTextBox({
            format: "{0:n4}",
            decimals: 4,
            step: 0.1,
    });
}

 

 

 

 

 

 

6 Answers, 1 is accepted

Sort by
0
Georgi
Telerik team
answered on 04 Jun 2018, 08:19 AM
Hello Jim,

Thanks for the provided code.

The issue is caused since the id field of the data model is not specified. It is necessary to specify which field of the model is its identifier as the dataSource keeps track of each dataItem (whether it is modified) via its id.

Once an id field is added to the model and it is specified in the configuration of the dataSource, the grid exits edit mode as expected.

e.g.

// add id field
 
{itemId:1,  label: "Parameter1", ref: 89.82, min: 60, max: 100, isInput: true },
 
//specify id field in dataSource
 
 var myDataSource = new kendo.data.DataSource({
      ....
        schema: {
          model: {
            id:'itemId',
     ....

On a side note, I would recommend you to get the min and max values from the dataItem instead of iterating through the cells of the current row.

e.g.

validateFunction: function (input) {
  var grid = $('#myGrid').data('kendoGrid');
  var dataItem = grid.dataItem($(input).parents('tr'));
 
  if ((input.val() < dataItem.min) || (input.val() > dataItem.max)) {
    input.attr("data-validateFunction-msg", "Value must be between " + dataItem.min + " and " + dataItem.max);
    return false;
  }
  return true;    
 
}


Regards,
Georgi
Progress Telerik
Try our brand new, jQuery-free Angular components built from ground-up which deliver the business app essential building blocks - a grid component, data visualization (charts) and form elements.
0
Jim
Top achievements
Rank 1
answered on 05 Jun 2018, 08:06 AM

Thank you Georgi for your reply.

I tried your suggestion but unfortunately the text is still not showing up when I set "editor: numberEditor" in the "ref" column in the grid. If I remove that it works, but then I don't have the same options to control decimals as I understand it. This is what I tried now for the DataSource:

this.myDataSource = new kendo.data.DataSource({
    autoSync: true,
    data: [
        { itemId:1, label: "Parameter1",  ref: 89.82, min: 60,    max: 100,   isInput: true },
        { itemId:2, label: "Parameter2",  ref: 9.18,  min: 8,     max: 20,    isInput: false }
    ],
    schema: {
        model: {
            id:'itemId',
            fields: {
                label: { type: "string", editable: false },
                ref: {
                    validation: {
                        required: true,
 
                        validateFunction: function (isInput) {
                            return OfflinePredictionController.validateInput("#myGrid", isInput);
                        }
                    }
                },
                min: { type: "number", editable: false },
                max: { type: "number", editable: false },
                isInput: { type: "boolean", editable: false }
            }
        }
    },
});

 

Your suggestion for the validation function works fine! I first got a compiler error saying  "Property 'min' does not exist on type ObservableObject". But when I defined it like this it worked:

let dataItem: any = grid.dataItem($(input).parents('tr'));

I guess because we are using typescript.

 

 

 

0
Georgi
Telerik team
answered on 06 Jun 2018, 07:28 AM
Hi Jim,

Thanks for the update.

Have in mind that if the data is invalid (validation fails) it is expected that the cell remains in edit mode. By default the cell will exit edit mode when the blur event of the editor is fired and the validation passes.

I have assembled a small sample using the provided code. Have in mind that I have added an additional condition within the validation since the numeric uses two inputs (one for formatted value and another for raw value) to avoid duplicate tooltips.

e.g.
if(input.is("[name='ref']") && (input.val() < dataItem.min) || (input.val() > dataItem.max))

Below you will find the sample. Please examine it and let me know if I am missing something:



Regards,
Georgi
Progress Telerik
Try our brand new, jQuery-free Angular components built from ground-up which deliver the business app essential building blocks - a grid component, data visualization (charts) and form elements.
0
Jim
Top achievements
Rank 1
answered on 06 Jun 2018, 10:35 AM

Thanks a lot!

The secret seems to have been this part:

<style>
    #myGrid .k-edit-cell{
        overflow: visible;
    }
</style>

 

Once I added it, it worked. So probably the tooltip was hidden when that style was not added.

 

I only noticed one thing that is strange now. If you look on the attached screenshots you can see that exclamation mark in the circle is a bit cut off when numberEditor is used. This is not the case when numberEditor is not in use. Any idea what could be the reason for that? That is nothing critical, but it would be nice if it looks good.

 

0
Georgi
Telerik team
answered on 07 Jun 2018, 08:49 AM
Hello Jim,

I am glad to hear that the initial issue has been resolved.

I believe that warning icon is cut off due to its height.

Could you please try to set its height explicitly and let me know if it is displayed as expected?

e.g.

#myGrid .k-numerictextbox .k-numeric-wrap .k-i-warning{
  height:20px;
}


Regards,
Georgi
Progress Telerik
Try our brand new, jQuery-free Angular components built from ground-up which deliver the business app essential building blocks - a grid component, data visualization (charts) and form elements.
0
Jim
Top achievements
Rank 1
answered on 08 Jun 2018, 10:19 AM

Hello Georgi,

that worked! I just had to change .k-i-warning to .k-warning. Thank you so much for your support!

 

Regards

Jim

Tags
General Discussions
Asked by
Jim
Top achievements
Rank 1
Answers by
Georgi
Telerik team
Jim
Top achievements
Rank 1
Share this question
or