Custom Validation of field using the read method of a datasource dedicated for this purpose.

2 posts, 0 answers
  1. Ananth
    Ananth avatar
    1 posts
    Member since:
    Aug 2012

    Posted 24 Aug 2012 Link to this post

    The following code is dataSource for validating values via a controller method:

                SampleDataSource: new kendo.data.DataSource({
                    transport: {
                        read: {
                            url:  "Sample/ValidateSampleCodes",
                            contentType: "application/json; charset=utf-8",
                            dataType: "json",
                            type: "POST"
                        },
                        parameterMap: function (options, operation) {
                            return JSON.stringify({ SampleCode: options.SampleCode });
                        },
                    },
                    schema: {
                        model: {
                            id: "Id"
                        },
                        parse: function (data) {
                            viewModel.set("SampleCodesFromDB",data[0]);
                            return data;
                        }
                    }
                }),

    The following code is the grid in which i need to validate values entered, instantly and display an in-line validation message. I am using the custom validator as shown below...

                    $("#Sample-code-grid").kendoGrid({
                        dataSource: { 
                            data: viewModel.SampleCodes,
                            schema: {
                                model: {
                                    id:"Id",
                                    fields : {
                                        SampleCode : { editable: true, validation: { custom: function (input) {
                                                var isValid = true;
                                                if (input.attr("name") == "SampleCode") {
                                                    
                                                    // Reading the below datasource to check if value already exists in DB
                                                    
                                                    viewModel.SampleDataSource.read({ SampleCode: input.val() });


                                                    // When debugging, i find that the above read method call is skipped until 
                                                    // custom validator function is fully executed...


                                                    var isValidMessage = viewModel.get("SampleCodesFromDB");
                                                    if(isValidMessage == "Code Exists")
                                                        isValid = false;
                                                    if(!isValid)
                                                        input.attr("data-custom-msg", "Sample Code already added.");
                                                }
                                                return isValid;
                                            }
                                            }
                                        }
                                    }
                                }
                            },
                            change: function(e) {
                                if(e.action == "itemchange" || "remove") {debugger;
                                    viewModel.SampleCodes = [];
                                    $.each(e.sender.data(), function(inx, val) {
                                        viewModel.SampleCodes.push({ SampleCode : val.SampleCode });
                                    });
                                }
                            }
                        },
                        selectable: true,
                        editable: "inline",
                        toolbar: [{ name: "create" , text : "Add Sample Code" }],
                        columns: [
                            { field: "SampleCode", title: "Sample Codes" },
                            { command: ["edit", "destroy"], title: " ", width: "210px" }
                        ]
                    });

    I have added some comments inside the code so that you get some idea about my problem. I just need to know how to approach validation for duplicates using the custom validator that calls a dataSource for the same purpose.

    Any help will be greatly appreciated.
  2. Alex
    Alex avatar
    2 posts
    Member since:
    Aug 2012

    Posted 19 Sep 2012 Link to this post

    This is what works for me, field name is "Code":

    validation: { //set validation rules
                                    required: { message: "Code is required." },
                                    unique: function (input) {
                                        input.attr("data-unique-msg", "A Code must be unique across list.");
                                        
                                        if (!input.is("[name=Code]")) {
                                            return true;
                                        }
                                        var grid = $(input).parents("[data-role=grid]").data('kendoGrid');
                                        if (!grid) {
                                            return true;
                                        }
                                        var dataItem = grid.dataItem($(input).parents('tr'));
                                        if (!dataItem.dirty || (input.val() === dataItem.Code)) {
                                            return true;
                                        }
                                        
                                        var data = dataItem.parent();
                                        var localItems = $.grep(data, function(v, i) {
                                            return (v.uid != dataItem.uid) && (v.Code.toLowerCase() === input.val().toLowerCase());
                                        });
                                        if (localItems.length) {
                                            return false;
                                        }

                                        var dataSource = grid.dataSource;
                                        var dataUrl = dataSource.options.transport.read.url;

                                        var ds = new kendo.data.DataSource(
                                            {
                                                transport: {
                                                    read: {
                                                        url: dataUrl,
                                                        async: false
                                                    }
                                               },
                                               error: function (e) {
                                                   input.attr("data-unique-msg", e.Message);
                                                   ret = false;
                                               }
                                            });
                                        ds.filter({
                                            logic: "or",
                                            filters: [
                                                {Code: input.val()}
                                            ]
                                        });
                                        
                                        return (ds.total() == 0);
                                    }
                                }
  3. Kendo UI is VS 2017 Ready
Back to Top