Validation on edit popup window of KendoUI grid with editor templates

1 Answer 3738 Views
Grid
Jennifer
Top achievements
Rank 2
Jennifer asked on 15 Mar 2013, 07:13 PM

Hi,

I am using the popup editing feature of the grid. Now I need to put some validation in. I was able to figure out how to validate the string field but can't figure out how to validate the date fields since I am usingt the DateTimePicker on the popup window (code at bottom).
I would like to validate that the days are greeater than today and that EndDate > StartDate for example.

Thanks in advance.

jennifer

var AuctionGrid = {};
  
/// class variables
AuctionGrid._id = null;
AuctionGrid._auctionDataSource = null;
  
/// <summary>Initialize the auctions grid</summary>
AuctionGrid.init = function () {
  
    // Auction Datasource
    AuctionGrid._auctionDataSource = new kendo.data.DataSource({
        transport: {
            read: {
                url: _rootUrl + "Test/GetAuctions/"
            },
            update: {
                url: _rootUrl + "Test/UpdateAuctions/",
                type: "POST"
            },
            destroy: {
                url: _rootUrl + "Test/DestroyAuction/",
                type: "POST"
            },
            create: {
                url: _rootUrl + "Test/CreateAuction/",
                type: "POST"
            },
            parameterMap: function (data, type) {
                // If update, create or destroy, then serialize the data
                // as JSON so that it can be more easily read on the server.
                if (type != "read") {
                    return { models: JSON.stringify(data.models) };
                } else {
                    return data;
                }
            }
        },
        schema: {
            model: {
                id: "AuctionID",
                fields: {
                    AuctionID: {
                        editable: false,
                        type: "number"
                    },
                    AuctionName: {
                        type: "string",
                        validation: {
                            required: { message: "An Auction Name is Required!" },
                            validateAuctionName: function (input) {
                                //alert(input.attr("data-bind"));
                                if (input.attr("data-bind") == "value:AuctionName") { // check if this is the element to validate
                                    alert(input.val().length);
                                    if (input.val().length > 10) {
                                        input.attr("data-validateAuctionName-msg", "AuctionName can only have a maximum of 10 characters.");
                                        return false;
                                    }
                                    else
                                        return true;
                                }
                                return true;
                            }
                        }
                    },
                    ShortDescription: {
                        type: "string"
                    },
                    LongDescription: {
                        type: "string"
                    },
                    StartDate: {
                        type: "date"
                    },
                    EndDate: {
                        type: "date",
                        validation: {
                            required: { message: "End Date is Required!" },
                            validateEndDate: function (input) {
                                  
                                    HOW DO I USE VALIDATION HERE - HOW DO I VALIDATE THAT END DATE > START DATE  
                            }
                        }
                    },
                    Active: { type: "boolean" }
                }
            }
        }
    });
  
  
    // Display the active auctions in a kendo grid.
    $("#AuctionGrid").kendoGrid({
        dataSource: AuctionGrid._auctionDataSource,
        scrollable: true,
        editable: "popup",
        pageSize: 6,
        edit: onEdit,
        height: 300,
        toolbar: ["create"],
        columns: [{
            field: "AuctionName",
            title: "Auction Name",
            width: "200px"
        }, {
            field: "ShortDescription",
            title: "Description",
            editor: textareaEditor
        }, {
            field: "StartDate",
            title: "Start Date",
            format: "{0:MM-dd-yyyy hh:mm tt}",
            editor: dateTimeEditor,
            width: "100px"
        }, {
            field: "EndDate",
            title: "End Date",
            format: "{0:MM-dd-yyyy hh:mm tt}",
            editor: dateTimeEditor,
            width: "100px"
        }, {
            field: "Active",
            title: "Active",
            template: "<input type=\"checkbox\" />",
            width: "80px"
        }, {
            command: ["edit", "destroy"], title: " ", width: "110px"
        }],
        groupable: false
    });
  
}
  
function onEdit(e) {
    $(e.container).parent().css({
        width: '600px',
        height: '400px'
    });
    // set maxLengths
    e.container.find("input[name=AuctionName]").attr("maxlength", 10);
}
  
function dateTimeEditor(container, options) {
  
    $('<input data-text-field="' + options.field + '" data-value-field="' + options.field + '" data-bind="value:' + options.field + '" data-format="' + options.format + '"/>')
                .appendTo(container)
                .kendoDateTimePicker({});
}
  
function textareaEditor(container, options) {
  
    $('<textarea data-bind="value:' + options.field + '" style="width:400px;" rows="4" ></textarea>')
        .appendTo(container);
}

1 Answer, 1 is accepted

Sort by
0
Vladimir Iliev
Telerik team
answered on 19 Mar 2013, 10:41 AM
Hi Jenifer,

 
Basically you should attach kendoValidator and define your custom validation rules for these fields - please check the example below:

//Custom validation
        $("#grid").kendoValidator({
            rules: {
                // custom rules
                custom: function (input, params) {
                    if (input.is("[name=StartDate]") || input.is("[name=EndDate]")) {
 
                        //If the input is StartDate or EndDate
                        var container = $(input).closest("tr");
 
                        var start = container.find("input[name=StartDate]").data("kendoDatePicker").value();
                        var end = container.find("input[name=EndDate]").data("kendoDatePicker").value();
 
 
                        if (start > end) {
                            return false;
                        }
                    }
                    //check for the rule attribute
                    return true;
                }
            },
            messages: {
                custom: function (input) {
                    // return the message text
                    return "Start Date must be greater than End Date!";
                }
            }
        })

For more information about the validator I would suggest to check the validator API and the validator overview guide. 
 
Kind Regards,
Vladimir Iliev
the Telerik team
Join us on our journey to create the world's most complete HTML 5 UI Framework - download Kendo UI now!
Will
Top achievements
Rank 1
commented on 09 Mar 2015, 09:54 AM

I tried the code above and when I changed one of the dropdownlists in my popup editor, the validator's "input" was the (nameless) pageSizes selector of the grid itself.

outerHTML   "<select style=\"display: none;\" data-role=\"dropdownlist\"><option selected=\"selected\" value=\"10\">10</option><option value=\"20\">20</option><option value=\"40\">40</option><option value=\"80\">80</option></select>"
Will
Top achievements
Rank 1
commented on 09 Mar 2015, 11:15 AM

Just to follow up, my popup uses a template enclosed in a div with an id="popupContainer".

This worked for me:

popupValidator = $("#popupContainer").kendoValidator({
    rules: {
        companyIDRule: function (input) {
            var result = true;
            if (input.is("[name=CompanyIDSelect]")) {
                if (!input.val()) {
                    result = false;
                } else if (input.val() <= 0) {
                    result = false;
                }
            }
            return result;
        }
    }
    , messages: {
        companyIDRule: "Comparison Operator is not compatible with the number of CompanyID values specified. Eg. 'Equals' should correspond to a single value."
    }
}).data("kendoValidator");
Vladimir Iliev
Telerik team
commented on 09 Mar 2015, 11:21 AM

Hello Will,

With current version of Kendo UI you can now define the desired custom validation rules directly in the "dataSource.schema.model.fields.rules" option as described below:

var dataSource = new kendo.data.DataSource({
  schema: {
    model: {
      id: "ProductID",
      fields: {
        ProductID: {
          editable: false,
          nullable: true
        },
        StartDate: {
          type: "date",
          validation: {
            required: true,
            customValidation: function(input, params) {
              if (input.is("[name=StartDate]")) {
                 
                var date = $(input).data("kendoDatePicker").value();
                 
                 
                if (date > new Date()) {
                  return false;
                }
              }
              //check for the rule attribute
              return true;
            }
          }
        }
      }
    }
  },


Regards,
Vladimir Iliev
Telerik
 
Join us on our journey to create the world's most complete HTML 5 UI Framework - download Kendo UI now!
 
Will
Top achievements
Rank 1
commented on 09 Mar 2015, 12:05 PM

Hello Vladimir,

Thank you for your suggestion.  When I tried that approach, the rule is called but the "input" parameter always has a length of 0.  So, no name and no value.

Taking a rule directly from your Demos:

CompanyIDValue: {
                    nullable: true
                    ,validation: {
                        wakavalid: function (input) {
                            if (input.is("[name='CompanyIDValue']") && input.val() != "") {
                                input.attr("data-productnamevalidation-msg", "Product Name should start with capital letter");
                                return /^[A-Z]/.test(input.val());
                            }
                            return true;
                        }
                    }
                },


Will Dougherty
Will
Top achievements
Rank 1
commented on 09 Mar 2015, 12:14 PM

By the way, while the Kendo UI documentation has improved tremendously over the last year or two, this area is still weakly described.  Or maybe I just haven't found the right place.  If you go to the API document for DataSource, it trails off at Model.  If you go to the API document for Model, it does not even mention rules or validation.
Vladimir Iliev
Telerik team
commented on 09 Mar 2015, 12:29 PM

Hello Will,

I tried to reproduce the problem locally but to no avail – everything is working as expected on our side. Could you please check the example below and let us know how it differs from your real setup?

Regards,
Vladimir Iliev
Telerik
 
Join us on our journey to create the world's most complete HTML 5 UI Framework - download Kendo UI now!
 
Will
Top achievements
Rank 1
commented on 09 Mar 2015, 04:22 PM

Hi Vladimir,
I have spent a bit of time decomposing my somewhat involved example to the point between working and not working.
What I found is that when I'm specifying an popup editor template, I lose the input.
I have simplified my Model and the template down to the absolute minimum to eliminate complicating factors and still that's what I'm seeing.

The template is simple:
<!-- popup editor template -->
    <script id="popup_editor_template" type="text/x-kendo-template">
        <div id="popupContainer">
 
            <div class="k-edit-label">
                <label for="referenceNumber">Ref \\#</label>
                <span data-bind="text: CarrierCommissionRuleID"></span>
            </div>
 
            <div class="k-edit-label">
                <label for="CompanyIDSelect">Company ID: </label>
                <input id="companyIDComparisonOperator" name="CompanyIDComparisonOperator" data-bind="value: CompanyIDComparisonOperatorID" />
            </div>
        </div>
    </script>


And the schema/model:
schema: $.extend(true, {}, kendo.data.schemas["aspnetmvc-ajax"], {
    data: "Data",
    total: "Total",
    errors: "Errors",
    model: {
        id: "CarrierCommissionRuleID",
        fields: {
            CarrierCommissionRuleID: { type: "number", editable: false },
            CompanyIDComparisonOperatorDisplay: {
                type: "string", nullable: true, validation: {
                    wakavalid: function (input, params) {
                        if (input.is("[name='CompanyIDValue']") && input.val() != "") {
                            input.attr("data-productnamevalidation-msg", "Product Name should start with capital letter");
                            return /^[A-Z]/.test(input.val());
                        }
                        return true;
                    }
                }
            }
        }
    }
})


Sorry but I haven't learned jsFiddle yet and I tried unsucessfully to modify your example to test with it.

Any suggestions?

Will
Vladimir Iliev
Telerik team
commented on 10 Mar 2015, 08:39 AM

Hello Jennifer,

From the provided code it seems that the validation is looking for input with "name" attribute equal to "CompanyIDValue", however the editor template doesn't have such editor. Could you please update the editor template / validation function to search for editors that are available and let us know of the result? 

Also for convenience I updated the previous example to use custom editor: Regards,
Vladimir Iliev
Telerik
 
Join us on our journey to create the world's most complete HTML 5 UI Framework - download Kendo UI now!
 
Will
Top achievements
Rank 1
commented on 10 Mar 2015, 09:58 AM

Hi Vladimir,

I did as you suggested but it did not change the results.

What I am seeing is that when I do NOT use the editor template, my "input" parameter looks like this:
_proto: {...}
context: {...}
length: 1
selector: ""
[0]: {...}

When I do use the editor template, my "input" parameter looks like this:
_proto: {...}
context: {...}
length: 0
selector: ""

So, the name I'm specifying is not relevant, there is simply NO information available, no name at all. 

I'm working on a small example project that I can send to you guys to demonstrate.  Would it be better to continue working through the forum or to open a Support Ticket?

Will
Vladimir Iliev
Telerik team
commented on 10 Mar 2015, 11:10 AM

Hi Will,

It seems that the described behavior is related to the current setup that you have - that why I would ask you to open a new support ticket (as you suggested) and provide the example where the issue is reproduced. In this way it is much easier to follow and concentrate on the particular issue which usually leads to its faster resolving.

Regards,
Vladimir Iliev
Telerik
 
Join us on our journey to create the world's most complete HTML 5 UI Framework - download Kendo UI now!
 
Will
Top achievements
Rank 1
commented on 16 Mar 2015, 10:52 AM

Just to follow up, I did open a Support Ticket.

Support ID:916107 -- Validator is called with no "input" when in Grid popup editor using a template.

"For performance reasons, the editor will search for inputs only with value binding without space:"

In my template's data-bind="value:..." declarations, I had a space after the colon, value: Name vs. value:Name. 

I REALLY don't like the answer but I'm very happy to have it.

Will
RK
Top achievements
Rank 1
commented on 03 Jun 2018, 02:26 PM

hello, any update on this ticket . i am not sure where i can track the support ticker.

I also ran into same problem where my custom validation is not able to figure out the input while using custom editor template.

RK
Top achievements
Rank 1
commented on 03 Jun 2018, 06:33 PM

Please ignore my concern , as mentioned my Will I removed the spaces in editor name ="' + options.field + '" to name ="'+options.field+'" and it worked.
Ethan
Top achievements
Rank 1
commented on 18 Mar 2020, 05:29 PM

Hey guys I have an issue where if say the user put in a malicious text into the field..After validation even if I return false the payload executes.Been at this for days and its really annoying me .For example a text like this kk</script><img src=1 onerror='alert(223)'/> would show an alert even if I have failed validation or removed the tags.

Something after I return from validation is doing this 

Denitsa
Telerik team
commented on 20 Mar 2020, 04:01 PM

Hello Ethan,

I try to replicate the described issue, but it works as expected.

I use a simple pattern validation in an input tag, grid datasource model and custom form validator. They all do what are suppose to without further execution on fail. Here are the corresponding code snippets:

<input type="text" class="k-textbox" name="UserName" id="UserName" required="required" pattern="^\w*"/>

schema: {model: {fields: {username: {validation: {pattern:"^\\w*"}}}}}

                $(function () {
                    var container = $("#employeeForm");
                    kendo.init(container);
                    container.kendoValidator({
                        rules: {
                          username: function (input) {
                                if (input.is("[data-username-msg]") && input.val() != "") {                                      													var patt = new RegExp("\\W");
                                    return !patt.test(input.val());
                                }
                                return true;
                            },
                        }
                    });
                });


Please consider that in some cases for example, when a submit event is thrown you may need to prevent its default behavior. As shown in https://demos.telerik.com/kendo-ui/validator/index the event.preventDefault(); is used at the beginning of the form submission function.

If the described behaviour persists could you give some more details? Or a code snippet with the validation you are doing?

Regards,
Denitsa
Progress Telerik

Get quickly onboarded and successful with your Telerik and/or Kendo UI products with the Virtual Classroom free technical training, available to all active customers. Learn More.
Ethan
Top achievements
Rank 1
commented on 20 Mar 2020, 04:11 PM

hey Denitsa

Thanks very much for the reply Its helpful.Il have a look at prevent default also .I have noticed since that the src in kk</script><img src=1 onerror='alert(223)'/> executes a call to a service after the validation has finished like so /VisualReporting/Admin/1 which obviously returns an error

So the validation finishes and then it executes a call

Ethan
Top achievements
Rank 1
commented on 20 Mar 2020, 04:22 PM

its a bit different to what you posted it looks like this 

(function ($, kendo) {
    $.extend(true, kendo.ui.validator, {
        rules: { // custom rules
            qtmlValidation: function (event,input) {
                if (input.is("[name='Qtml']")) {
                    if (InputContainsUnSanitizeHtml(input[0].value) === true) {
                        input.attr("data-qtml-msg", "@(Strings.ValidQtml)");
                         
                        //code was used to santize the input and change it in the gridDataSource
                        //var sanitizedValue = sanitizeHtml(input[0].value);
                        //input[0].value = sanitizedValue;
                        //var id = $("#Id").val();
                        //var grid = $("#QtmlGrid").data("kendoGrid");
                        //var previousName = grid.dataSource.get(id).Qtml;
                        //previousName = sanitizedValue;
                        return false;
                    }
 
 
                    return true;
                }
                return true;
            }
        },
        messages: { //custom rules messages
            qtmlValidation: function (input) {
                return input.attr("data-qtml-msg");
            }
        }
    });
})(jQuery, kendo);
Denitsa
Telerik team
commented on 23 Mar 2020, 09:50 AM

Hi Ethan,

I taka e closer look to the code snippet you have posted and I noticed that you have two parameters (event and input ) in the custom rules function. You could pass more than one parameter to this function, but it is expected the first one to be the input field. The current implementation throws an error in the development console at my side. 

 

Please use the input as a first parameter, like this: 

qtmlValidation:function(input, event) 

 

I would suggest checking our documentation for Using Kendo UI Validator in ASP.NET MVC and How to Implement Remote Validation in Grid, as well as the Troubleshooting page.

You may also check if the framework or the application server you are using provide some additional capabilities for preventing dangerous requests like the Request Validation in ASP.NET. This will secure your application in a better way and you don't have to make all client-side and server-side validation on your own.

Regards,
Denitsa
Progress Telerik

Get quickly onboarded and successful with your Telerik and/or Kendo UI products with the Virtual Classroom free technical training, available to all active customers. Learn More.
Ethan
Top achievements
Rank 1
commented on 23 Mar 2020, 10:20 AM

Hi Denitsa

Thanks for reply.Sorry the parameters are wrong there that was just me playing around.There should only be 1 param input there.If I pass event there it just comes up as null.

The issue im having is I dont seem to have control after the custom validator finishes it goes off into the kendo code and somewhere there it executes the script(even if I have set the model value or js value to have the malicious code removed).It just seems to ignore this 

Ethan
Top achievements
Rank 1
commented on 23 Mar 2020, 10:22 AM

Thanks very much for the links also Il look into the remote one I havent come across it yet 

Thanks 

Ethan 

Ethan
Top achievements
Rank 1
commented on 23 Mar 2020, 03:03 PM

I have done the remote validation and this still happens.We have the validation done ok when it reaches the save but its the on blur custom validation one where we have no control of what happens..THe validation fails successfully but the script onerror still executes..

Why does the kendo.min.js _validate use the old text containing the payload even when I have removed this from the model.I cannot find this anywhere in the document

 

Ethan 

Denitsa
Telerik team
commented on 25 Mar 2020, 10:15 AM

Hello Ethan,

Here is a runnable example of how you could sanitize (change) the value of the input field client-side, so it doesn't contain undesired characters:

http://dojo.telerik.com/AFUheHub/2

I try to make this example close to the code snippet you sent. If this is not what you want to achieve, could you please send an isolated, runnable sample or project showing the issue you have?

Regards,
Denitsa
Progress Telerik

Progress is here for your business, like always. Read more about the measures we are taking to ensure business continuity and help fight the COVID-19 pandemic.
Our thoughts here at Progress are with those affected by the outbreak.
Ethan
Top achievements
Rank 1
commented on 25 Mar 2020, 10:21 AM

hi Denitsa here is an example https://kendogrid20200324104055.azurewebsites.net/

It will not happen in your case as its all front end .So if you click on edit paste in kk</script><img src=1 onerror='alert(223)'/> and then click outside you will see the alert

Denitsa
Telerik team
commented on 27 Mar 2020, 09:56 AM

Hi Ethan,

Thank you for the link.

Indeed the behavior described by you is clearly replicated at this application. As it seems the cause is in the server-side implementation could you send us the sample project, so we could investigate the code for further assistance? 

Additional information like application server, framework, specific libraries, and the corresponding versions (if this information not available in the project itself) could also help for solving the issue.

 

Another thing that has an effect in case you are using ASP.NET MVC is its Request Validation feature. Have you disabled it? You may check that such potentially harmful inputs are prevented by it at this demo:

https://demos.telerik.com/aspnet-mvc/grid/editing-popup

Regards,
Denitsa
Progress Telerik

Progress is here for your business, like always. Read more about the measures we are taking to ensure business continuity and help fight the COVID-19 pandemic.
Our thoughts here at Progress are with those affected by the outbreak.
Ethan
Top achievements
Rank 1
commented on 27 Mar 2020, 10:29 AM

Hi Denitsa 

The issue isnt in the server side part as these are literally placeholder endpoints that are sending data back.The issue comes from _validate  in kendo.min that cause the img src tag to be executed.We dont have any control over this as it is done as nothing is submitted.It goes to kendo _validate twice and this then executes the img src which of course is a rubbish link which guarantees the onerror executes.

 

I can send the VS project on but will have to fix some ref links first as they wont point to the same place on your machine 

 

Denitsa
Telerik team
commented on 30 Mar 2020, 03:50 PM

Hi Ethan,

 

Actually, after taking a closer look at the code of your shared example it appears that the function you are using for validation (sanitizeHtml) is calling  $.parseHTML(value) that will execute when the HTML is parsed. So replacing the jQuery.parseHTML method or changing the jQuery version (as of 3.0 the default behavior for this method is changed) should stop the execution of harmful inputs.

 

You are correct that the validation is happening twice - once on input change and once when the form is submitted (click Save, Update button). The first validation makes it possible to notify the user immediately after entering a value and the second one will validate even the fields that have not changed their values.

And if you want to have more control of the popup editor you may create Custom Editor Template.


Regards,
Denitsa
Progress Telerik

Progress is here for your business, like always. Read more about the measures we are taking to ensure business continuity and help fight the COVID-19 pandemic.
Our thoughts here at Progress are with those affected by the outbreak.
Tags
Grid
Asked by
Jennifer
Top achievements
Rank 2
Answers by
Vladimir Iliev
Telerik team
Share this question
or