Need help creating two kendo validators in the same view

5 posts, 1 answers
  1. Andrew
    Andrew avatar
    12 posts
    Member since:
    Jan 2017

    Posted 25 Jan 2017 Link to this post

    Hello,

    I've a view with one Form and one Kendo Grid like this

    01.<div>
    02.   <form id="form1">
    03.   </form>
    04.</div>
    05. 
    06.<div>
    07.    @(Html.Kendo().Grid<ProductsModel>()
    08.       .Name("grid")
    09.       .....
    10.    )
    11.</div>

     

    The grid is using a custom popup editor's template like this

    1.<form id="gridEditorTemplate">
    2.    ....
    3.</form>

     

    I've defined a kendo validator for the form1 in this way

    01.var validator1 = $("#form1").kendoValidator({
    02.    rules: {
    03.        customRule1: function (input) {
    04.            // all of the input must have a value
    05.            return $.trim(input.val()) !== "";
    06.        },
    07.    },
    08.    messages: {
    09.        customRule1: "All fields are required",
    10.    }
    11.}).data("kendoValidator");

     

    This validator work in the way I expected but when I define a new validator like this one for the gridEditorTemplate the custom rule isn't called by the grid when the user click the Update button.

    However if I declare the custom rule for the popup editor like this

    01.(function ($, kendo) {
    02.    $.extend(true, kendo.ui.validator, {
    03.        rules: {
    04.            positive: function (input) {
    05.                if (input.attr("id") === "xx") {
    06.                    var val = input.val();
    07.                    if (val !== "") {
    08.                        return val > 0;
    09.                    }
    10.                }
    11.                return true;
    12.            }
    13.        },
    14.        messages: {
    15.            positive: function (input) {
    16.                return "positive";
    17.            }
    18.        }
    19.    });
    20.})(jQuery, kendo);

     

    it works as expected.

    The problem with this approach is that when I call validate() for the form1 like this validator1.validate() the rules defined in the popup editor's validator are analyzed too.

    What I need is to define a validator for the popup editor's template in such a way that when I call validator1.validate() it doesn't analyze the rules defined in the popup editor's template.

    Thank you.

  2. Ianko
    Admin
    Ianko avatar
    1949 posts

    Posted 30 Jan 2017 Link to this post

    Hello Andrew,

    Typically, the Grid popup has some built-in validation. In your case, I assume, it is the popup validator that is not tied up to the proper DOM element. And thus, the default popup validator takes place. This is why only the global custom rule works.

    On my end, I was unable to reproduce the same behavior. Here you are the sample code I used:

    <form action="/" method="post" id="form1">
        <input class="k-textbox" data-val="true" data-val-required="The Product name field is required." id="ProductName" name="ProductName">
        <input type="submit" value="Submit" />
    </form>
     
    @(Html.Kendo().Grid<Kendo.Mvc.Examples.Models.ProductViewModel>()
        .Name("grid")
        .Columns(columns =>
        {
            columns.Bound(p => p.ProductName);
            columns.Bound(p => p.UnitPrice).Width(120);
            columns.Bound(p => p.UnitsInStock).Width(120);
            columns.Bound(p => p.Discontinued).Width(120);
            columns.Command(command => { command.Edit(); command.Destroy(); }).Width(250);
        })
        .ToolBar(toolbar => toolbar.Create())
        .Editable(editable => editable.Mode(GridEditMode.PopUp).TemplateName("temp"))
        .Pageable()
        .Sortable()
        .Scrollable()
        .HtmlAttributes(new { style = "height:550px;" })
        .DataSource(dataSource => dataSource
            .Ajax()
            .PageSize(20)
            .Events(events => events.Error("error_handler"))
            .Model(model => {
                model.Id(p => p.ProductID);
            })
            .Create(update => update.Action("EditingPopup_Create", "Grid"))
            .Read(read => read.Action("EditingPopup_Read", "Grid"))
            .Update(update => update.Action("EditingPopup_Update", "Grid"))
            .Destroy(update => update.Action("EditingPopup_Destroy", "Grid"))
        )
    )
    <script type="text/javascript">
        $("#form1").kendoValidator({
            rules: {
                custom: function (input, params) {
                    console.log("Custom rules for the form");
     
                    return false;
                }
            }
        })
     
        function error_handler(e) {
            if (e.errors) {
                var message = "Errors:\n";
                $.each(e.errors, function (key, value) {
                    if ('errors' in value) {
                        $.each(value.errors, function () {
                            message += this + "\n";
                        });
                    }
                });
                console.log(message);
            }
        }
    </script>

    temp.cshtml
    <div id="validatable">
        <input class="k-textbox" data-val="true" data-val-required="The Product name field is required." id="ProductName" name="ProductName" data-bind="value:ProductName">
    </div>
     
    <script>
        $("#validatable").kendoValidator({
            rules: {
                custom: function (input, params) {
                    console.log("Custom rules for the popup field");
     
                    return false;
                }
            }
        });
    </script>


    I guess, it is possible this to happen if the kendoValidator for the template is configured in the main page and not in the partial view template. 

    If this does not help you with the case, please provide a simple, locally runnable solution so that I can investigate the exact situation properly.

    Regards,
    Ianko
    Telerik by Progress
    Try our brand new, jQuery-free Angular 2 components built from ground-up which deliver the business app essential building blocks - a grid component, data visualization (charts) and form elements.
  3. Andrew
    Andrew avatar
    12 posts
    Member since:
    Jan 2017

    Posted 31 Jan 2017 in reply to Ianko Link to this post

    Hello Ianko,

    I did exactly what you say and it works!

    But could you tell me why the template's validator have to be placed in the same template's cshtml file?

    Also if I add some line comments inside $("#validatable").kendoValidator({}) I get a jQuery error. Why?

    Thank you for your help.

  4. Answer
    Ianko
    Admin
    Ianko avatar
    1949 posts

    Posted 31 Jan 2017 Link to this post

    Hello Andrew,

    This is because the popup editor is evaluated from the template when opened. Having this script in the main page runs the code before the popup elements are rendered, and thus, there is no DOM element with id "validatable".

    As for the JS errors when using comments in the template. Most probably is due to the Regex operation ran over the template, where / character is a special one in Regex. I suggest you using this comment blocks: /* Comment */.

    Regards,
    Ianko
    Telerik by Progress
    Try our brand new, jQuery-free Angular 2 components built from ground-up which deliver the business app essential building blocks - a grid component, data visualization (charts) and form elements.
  5. Andrew
    Andrew avatar
    12 posts
    Member since:
    Jan 2017

    Posted 31 Jan 2017 in reply to Ianko Link to this post

    Hello Ianko,

    This is because the popup
    editor is evaluated from the template when opened. Having this script
    in the main page runs the code before the popup elements are rendered,
    and thus, there is no DOM element with id "validatable".

    It makes sense.

    As for the JS errors when using comments in the template. Most probably
    is due to the Regex operation ran over the template, where / character
    is a special one in Regex. I suggest you using this comment blocks

    I used the /**/ block comment and it works!

    Thank you for your explanations.

Back to Top