Unable to get Custom Validation Working on a Grid

Thread is closed for posting
21 posts, 1 answers
  1. John DeVight
    John DeVight avatar
    209 posts
    Member since:
    Jan 2010

    Posted 06 Apr 2012 Link to this post

    I have a grid bound to a datasource containing a list of poeple defined with 4 fields (Id, FirstName, LastName, and Birthday).  I would like to perform custom validation on the Birthday field.  The DataSource is defined as follows:

    var peopleData = [
        { Id: 1, FirstName: "Person", LastName: "One", Birthday: new Date(1973, 11, 30) },
        { Id: 2, FirstName: "Person", LastName: "Two", Birthday: new Date(1967, 9, 5) }
    ];
      
    var peopleDataSource = new kendo.data.DataSource({
        data: peopleData,
        schema: {
            model: {
                id: "Id",
                fields: {
                    Id: { type: "number" },
                    FirstName: { type: "string" },
                    LastName: { type: "string" },
                    Birthday: {
                        type: "date",
                        validation: {
                            rules: {
                                custom: function(input) {
                                    if (console != undefined) { console.log(input); }
                                    var today = new Date();
                                    return input < today;
                                }
                            },
                            messages: {
                                custom: "Birthday cannot be in the future"
                            }
                        }
                    }
                }
            }
        }
    });

    The grid is defined as follows:

    $("#personGrid").kendoGrid({
        dataSource: peopleDataSource,
        editable: true,
        columns: [{
            field: "FirstName",
            title: "First Name"
        },{
            field: "LastName",
            title: "Last Name"
        },{
            field: "Birthday",
            title: "Birthday",
            template: "#= kendo.toString(Birthday, 'MM/dd/yyyy') #"
        }]
    });

    When I edit the Birthday field, the custom validation defined in the peopleDataSource for the Birthday field is not called.

    What am I doing wrong?

    I am using Kendo UI, version: 2012.1.322.open-source.

    Code is attached.

    Regards,

    John DeVight
  2. Answer
    Rosen
    Admin
    Rosen avatar
    3234 posts

    Posted 09 Apr 2012 Link to this post

    Hello John,

    Setting custom validation for fields during grid editing requires slightly different syntax:

    Birthday: {
         type: "date",
         validation: {
             custom: function(input) {
                 // set the custom message
                 input.attr("data-custom-msg", "Birthday cannot be in the future");
     
                 if (console != undefined) { console.log(input); }
                 var today = new Date();
                 return input < today;
             }
         }
     }

    All the best,
    Rosen
    the Telerik team
    Join us on our journey to create the world's most complete HTML 5 UI Framework - download Kendo UI now!
  3. Kendo UI is VS 2017 Ready
  4. John DeVight
    John DeVight avatar
    209 posts
    Member since:
    Jan 2010

    Posted 09 Apr 2012 Link to this post

    Thanks Rosen!  That worked perfectly =)

    For anyone else who looks at this, I also had to correct my validation code.  I had assumed that the "input" parameter that was passed in was the value of the input field and not the input field itself.  Here are the changes to the datasource:

    var peopleDataSource = new kendo.data.DataSource({
        data: peopleData,
        schema: {
            model: {
                id: "Id",
                fields: {
                    Id: { type: "number" },
                    FirstName: { type: "string" },
                    LastName: { type: "string" },
                    Birthday: {
                        type: "date",
                        validation: {
                            custom: function(input) {
                                if (console != undefined) { console.log(input); }
                                input.attr("data-custom-msg", "Birthday cannot be in the future");
                                return new Date(input.val()) < new Date();
                            }
                        }
                    }
                }
            }
        }
    });
  5. Doug
    Doug avatar
    18 posts
    Member since:
    Feb 2011

    Posted 13 Apr 2012 Link to this post

    What happens when you have more than one field which needs validating?  This solution worked for me as well, but setting the "data-custom-msg" set the error tooltip for all the fields I am validating even though some of the fields had valid values.  If I was doing this the validator way, I would do the following:

    PromoCodeName: {
        type: "string",
        validation: {
            rules: {
                required: true,
                custom: function(input) {
                    return input.val().length > 15;
                }
            },
            messages: {
                required: "A Promo Code Name is Required!",
                custom: "A Promo Code Cannot Be Longer Than 15 Characters!"
            }
        }
    },
    PromoCodeDescription: {
        type: "string",
        validation: {
            rules: {
                required: true,
                custom: function(input) {
                    return input.val().length > 20;
                }
            },
            messages: {
                required: "A Promo Code Description is Required!",
                custom: "A Promo Code Description Cannot Be Longer Than 20 Characters!"
            }
        }
    },

    I am, however, like the OP, working inside the grid.  What is the correct syntax for doing multiple validations on multiple fields with custom messages so that one validation does not overlap another.  Or is there something I'm missing altogether?

    Regards and Thanks for Your Time,
    Doug
  6. Rosen
    Admin
    Rosen avatar
    3234 posts

    Posted 17 Apr 2012 Link to this post

    Hello Doug,

    As you may know you are not constraint to use custom as a name for all custom rules. Thus, you should pick meaningful names for the rules in the context of single field.

    PromoCodeName: {
        type: "string",
        validation: {
            required: { message: "A Promo Code Name is Required!" },
            nameCheckLength: function(input) {
                 input.attr("data-nameCheckLength-msg", "A Promo Code Name Cannot Be Longer Than 15 Characters!");
                 return input.val().length <= 15;
            }
        }
    },
    PromoCodeDescription: {
        type: "string",
        validation: {
           required: { message: "A Promo Code Description is Required!" },
           descriptionCheckLength: function(input) {
              input.attr("data-descriptionCheckLength-msg", "A Promo Code Description Cannot Be Longer Than 20 Characters!");
              return input.val().length <= 20;    
           }
        }
    }

    Regards,
    Rosen
    the Telerik team
    Join us on our journey to create the world's most complete HTML 5 UI Framework - download Kendo UI now!
  7. Doug
    Doug avatar
    18 posts
    Member since:
    Feb 2011

    Posted 17 Apr 2012 Link to this post

    Actually, I wasn't aware of that.  My apologies if I did not read something thoroughly enough.  I appreciate the information!

    Regards,
    Doug
  8. Sarvesh
    Sarvesh avatar
    16 posts
    Member since:
    May 2012

    Posted 08 May 2012 Link to this post

    Hi,

    Below is my schema definition 

    schema: {
    model: {
    id: "Id",
    fields: {
    EmailId: { type: "string", editable: true, nullable: false,
    validation: {
    required: { message: "EMail ID Required." },
    validateEmailFormat: function (input) {
    input.attr("data-validateEmailFormat-msg", "Email format invalid.");
    return checkEmail(input.val());
    }
    }
    },
    FirstName: { editable: true, nullable: false, validation: {
    required: { message: "First Name Required." }

    },
    LastName: { editable: true, nullable: false, validation: {
    required: { message: "Last Name Required."}
     } 
    },
    UserId: { editable: true, validation: {
    required: { message: "User ID Required." }

    },
    Id: { editable: false }
    }
    }
    }

    the checkEmail method implementation is below
    function checkEmail(val) {
    var emailFormat = /^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,4}$/i;
    if (val == "") {
    return false;
    } else if (val.search(emailFormat) == -1) {
    return false;
    }
    return true;
    }

    I am facing a issue similar to Doug, the error tooltip message is being displayed for the firstname, lastname and userid fields even though they have valid values. Am i doing something wrong?
  9. Rosen
    Admin
    Rosen avatar
    3234 posts

    Posted 08 May 2012 Link to this post

    Hi Sarvesh,

    Could you please provide a jsFiddle test page in which this issue can be observed?

    Regards,
    Rosen
    the Telerik team
    Join us on our journey to create the world's most complete HTML 5 UI Framework - download Kendo UI now!
  10. Sarvesh
    Sarvesh avatar
    16 posts
    Member since:
    May 2012

    Posted 08 May 2012 Link to this post

    Hi, 

    Tried creating a jsfiddle page but was facing some issue so attaching a test file.

    Regards,
    Sarvesh
  11. Rosen
    Admin
    Rosen avatar
    3234 posts

    Posted 08 May 2012 Link to this post

    Hi Sarvesh,

    As you are using popup edit mode (and the validation rules will be executed against every input element),  the custom validation logic should be a bit more involved. This way it will identify the correct element on which the specific rule should be executed:

    EmailId: {
        validation: {
            validateEmailFormat: function(input) {
                input.attr("data-validateEmailFormat-msg", "Email format invalid.");
                 
                if (input.is("name=EmailId")) { // check if this is the element to validate
                    return checkEmail(input.val());
     
                }
                return true;
            }
        }

    Regards,
    Rosen
    the Telerik team
    Join us on our journey to create the world's most complete HTML 5 UI Framework - download Kendo UI now!
  12. Sarvesh
    Sarvesh avatar
    16 posts
    Member since:
    May 2012

    Posted 08 May 2012 Link to this post

    Thanks for your quick response. Managed to get this working.

    Regards,
    Sarvesh
  13. Justin
    Justin avatar
    3 posts
    Member since:
    Feb 2012

    Posted 26 Jun 2012 Link to this post

    This may be a topic for another forum thread, but since it is tightly coupled with what is discussed here, I'll discuss it here. Is there a way to get a reference to these validators directly? I would like to do things like check for accumulated errors for a logger, and get a callback to confirm validation worked before performing other operations. 

    It would be really nice to know if this approach works across all the widgets in your web library:

    UI WIDGETS








     

     
    Including any notes on special cases with each widget.

    PS--This page gives a hint of what could be done, but it seems to rely on "declarative (HTML) initialization" rather than the datasource model:
    http://www.kendoui.com/forums/framework/validation/validation-messages-on-window.aspx 
  14. Jeff
    Jeff avatar
    18 posts
    Member since:
    Jun 2012

    Posted 04 Jul 2012 Link to this post

    I added a UserVoice suggestion to be able to DataSource the model (with validation) and request it from the server rather than hard code it into the client.  Place your votes here - http://kendo.uservoice.com/forums/127393-kendo-ui-feedback/suggestions/2976821-datasource-model-separately-datasourcable.

    Thanks,
    Jeff
  15. Boris
    Boris avatar
    24 posts
    Member since:
    Jun 2012

    Posted 10 Jul 2012 Link to this post

    Using a grid with a popup edit
    Price is a field and the validation is: make sure is numeric

    This is what worked for me:
                        Price: {
                            editable: true, type: "double",
                            validation: {
                                required: true,
                                custom: function (input) {
                                    input.attr("data-custom-msg""Price is not valid");
                                    // check if this is the element to validate - required for the popup edit mode
                                    if (input.attr("data-bind") == "value:Price") {
                                        return $.isNumeric(input.val());
                                    }
                                    return true;
                                }
                            }
                        },
    Good luck!
  16. Marcela
    Marcela avatar
    2 posts
    Member since:
    May 2012

    Posted 04 Sep 2012 Link to this post

    I've validated some columns with custom functions as I show you:

     

    Placement: { type: "string",
    validation:{
    required:true,
    PlaceCheck: function(input){
    if(input.attr("data-bind") == "value:Placement"){
    input.attr("data-placeCheck-msg","El placement es requerido.");
    var placeValue = input.val();
    return placeValue != null;
    }
    return true;
    }
    }
    },
    Format: { type: "string" },
    Size: { type: "string",
    validation:{
    SizeCheck: function(input){
    //Set the custom message
    if(input.attr("data-bind") == "value:Size"){
    input.attr("data-sizeCheck-msg","El valor introducido para el tamaño no es correcto. Se espera ancho(X*x)alto.");
    //Validar el formato del campo formato
    var regEx = "^[0-9]{1,4}[X*x][0-9]{1,4}$";
    var sizeValue = input.val();
    return sizeValue.match(regEx);
    }
    return true;
    }
    }
    },
    StartDate: { type: "date",validation:{ required:true } },
    EndDate: { type: "date",validation:{ required:true } },


    Validations works fine, but when I introduce the right data and later I get the data for the row selected in order to save it, the value for these columns are empty. If I remove the validation option from the column it works fine but I don't have validation.

    I have in the change event the next:
    change: function() {
        var text = "";
        var grid = this;
        grid.select().each(function() {
            itemSelected = grid.dataItem($(this));               
        });
    },

    Can anyone help me, please?

    Thanks in advance.

  17. chris
    chris avatar
    11 posts
    Member since:
    Nov 2011

    Posted 13 Sep 2012 Link to this post

    Hi Rosen,

    How do i apply the validation settings on a customer editor template?
    ie. validation: { required: true, min: 1 }


    ie.validation: {         required: { message: "A Promo Code Name is Required!" },
                                    nameCheckLength: function (input) {
                                         input.attr("data-nameCheckLength-msg", "A Promo Code Name Cannot Be Longer Than 15 Characters!");
                                          return input.val().length <= 15;
                                       }
                        }
    Is there an example of setting common attributes, like email, number formats, currency, min-max values etc.  which can be applied to a custom popup editor template.  Also can the editor widget be used in the edit template like in telerik MVC version?

    regards

    chris
  18. Matthew
    Matthew avatar
    5 posts
    Member since:
    Sep 2012

    Posted 27 Dec 2012 Link to this post

    The same issue with the custom validator applying to multiple fields occurs during in-line editing also, not just the pop-up.

    It appears any custom validator applied to a FIELD in the MODEL ends up being called for every field that has a corresponding bound input element (I have verified this in script). I do not see how this could possibly be correct.

    This seems to be a bug, and should be marked as so!




  19. Jennifer
    Jennifer avatar
    4 posts
    Member since:
    May 2012

    Posted 28 May 2013 Link to this post

    Telerik Team,

    I have a grid and am doing custom validation for the grid popup like you suggested in this thread to ROSEN a few posts previously


    EmailId: {
        validation: {
            validateEmailFormat: function(input) {
                input.attr("data-validateEmailFormat-msg", "Email format invalid.");
                 
                if (input.is("name=EmailId")) { // check if this is the element to validate
                    return checkEmail(input.val());
     
                }
                return true;
            }
        }

    But I just cannot figure out how to compare 1 field in the popup to another in the same popup. Like in the example above, I want to compare EmailID to another email field in the popup called EmailID2 . How do I "FIND" or "REFERENCE" the other field in the function above validateEmailFormat:

    Thanks in advance!
  20. Rosen
    Admin
    Rosen avatar
    3234 posts

    Posted 29 May 2013 Link to this post

    Hi Jennifer,

    You could use the supplied input element to get a reference to the parent container in which to search for the appropriate input element for the comparison. For example:

    validateEmailFormat: function(input) {
        if (input.is("name=EmailId")) {
            var otherEmail =  input.closest(".k-edit-form-container").find("input[name=Email2]").val();
            return compare(input.val(), otherEmail);
        }
        return true;
    }

    Regards,
    Rosen
    Telerik
    Join us on our journey to create the world's most complete HTML 5 UI Framework - download Kendo UI now!
  21. Jennifer
    Jennifer avatar
    4 posts
    Member since:
    May 2012

    Posted 29 May 2013 Link to this post

    Sorry guys I am just not getting it. This is my schema that I defined on my datasource for my grid:

     schema: {
                model: {
                    id: "AuctionID",
                    fields: {
                        AuctionID: {
                            editable: false,
                            type: "number"
                        },
                        EndDate: {
                            type: "date",
                            validation: {
                                required: { message: "End Date is Required!" },
                                validateEndDate: function (input) {

                                    if (input.attr("data-bind") == "value:EndDate") { // check if this is the element to validate

                                        alert("We are in End Date");

                                        // I WANT TO COMPARE END DATE to START DATE - I get NULL REFERENCE HERE
                                        var startDate = input.closest(".k-edit-form-container").find("input[name=StartDate]").val();

                                    }
                                    return true;
                                }
                            }
                        },

    Even using this does not work:       if (input.is("name=EndDate")) { 

    Seems I have to say it like this:

    if (input.attr("data-bind") == "value:EndDate")

    So I still don't know how to get a reference to another item in my schema to compare to. My grid has 2 dates among other fields and I am using popup editing and I need to make sure startdate is < enddate.

    And I am not sure where you come up with ".k-edit-form-container"

    Sorry - coming from webforms and server controls  - this is really tricky for me!

    Thanks!


  22. Jennifer
    Jennifer avatar
    4 posts
    Member since:
    May 2012

    Posted 29 May 2013 Link to this post

    I figured it out! - I was using this to make the date time picker in the popup and was not setting the name attribute!

    function dateTimeEditor(container, options) {
        $('<input data-text-field="' + options.field + '" name = "' + options.field +  '" data-value-field="' + options.field + '" data-bind="value:' + options.field + '" data-format="' + options.format + '"/>')
                    .appendTo(container)
                    .kendoDateTimePicker({});
    }
Back to Top
Kendo UI is VS 2017 Ready