0

We are trying to display a validation error message by overriding the default behavior of Kendo numerictextbox for displaying percentage value.

our expectation is to provide a custom message when user type in any value more than 100.

By default Kendo NumericTextbox for percentage auto corrects the value if the user type in anything more than 100 (we don't want this behavior)

Please find a jsfiddle reference URL for the same to understand it better https://jsfiddle.net/6uyp825h/57/

<!DOCTYPE html>
<html>
<head>
<base href="https://demos.telerik.com/kendo-ui/numerictextbox/index">
<style>html { font-size: 14px; font-family: Arial, Helvetica, sans-serif; }</style>
<title></title>
<link rel="stylesheet" href="https://kendo.cdn.telerik.com/2018.2.620/styles/kendo.common-material.min.css" />
<link rel="stylesheet" href="https://kendo.cdn.telerik.com/2018.2.620/styles/kendo.material.min.css" />
<link rel="stylesheet" href="https://kendo.cdn.telerik.com/2018.2.620/styles/kendo.material.mobile.min.css" />

<script src="https://kendo.cdn.telerik.com/2018.2.620/js/jquery.min.js"></script>
<script src="https://kendo.cdn.telerik.com/2018.2.620/js/kendo.all.min.js"></script>

</head>
<body>

    <div id="example">
        <div id="add-product" class="demo-section k-content">
            <p class="title">Add new product</p>
            <ul id="fieldlist">
                <li>
                    <label>
                        Price Discount:
                        <input id="percentage" value="5" title="percentage" style="width: 100%;" />
                    </label>
                </li>

            </ul>
        </div>


        <script>
            $(document).ready(function() {

                // create Percentage NumericTextBox from input HTML element
                $("#percentage").kendoNumericTextBox({
                    format: "##.00 \\%",
                    min: 0,
                    spinner: false
                });

    var container = root;
    kendo.init(container);

    container.kendoValidator({
        rules: {
            checkPercentageMaxValue: function (input) {

               var maxAllowedValue = 100;
               var currentValue = parseInt($("#percentage").val());
                        if (currentValue > maxAllowedValue)
                        {
                            return false;
                        }
                        else {
                            return true;
                        }
                    return true;
            }
        },
        messages: {

            checkPercentageMaxValue: "Percentage value cannot be greater than 100."
        }
    });


            });
        </script>

        <style>
            .demo-section {
                padding: 0;
            }

            #add-product .title {
                font-size: 16px;
                color: #fff;
                background-color: #1e88e5;
                padding: 20px 30px;
                margin: 0;
           }

           #fieldlist {
               margin: 0 0 -1.5em;
               padding: 30px;
           }

           #fieldlist li {
               list-style: none;
               padding-bottom: 1.5em;
           }

           #fieldlist label {
               display: block;
               padding-bottom: .6em;
               font-weight: bold;
               text-transform: uppercase;
               font-size: 12px;
           }

           #fieldlist label .k-numerictextbox {
               font-size: 14px;
           }
        </style>

    </div>

Here is the html which I gets in real scenario

<div class="col-sm-8">
        <span class="k-widget k-numerictextbox single-line text-box form-control">
            <span class="k-numeric-wrap k-state-default k-expand-padding">
                <input tabindex="0" title="112.00 %" class="k-formatted-value single-line text-box form-control k-input k-valid" role="spinbutton" aria-disabled="false" aria-valuenow="112" style="display: inline-block;" type="text">
                <input name="PercentHeld3" class="single-line text-box form-control k-input k-valid" id="PercentHeld3" role="spinbutton" aria-disabled="false" aria-valuenow="112" style="display: none; border-color:black; " type="text" maxlength="16" data-role="numerictextbox" data-bind="value: PercentHeld" data-spinners="false" data-numberformat="percentage" data-decimals="2" data-validate="true" data-maxallowedvalue="100" data-max-msg="Percentage value cannot be greater than 100.">
                <span class="k-select" style="display: none;">
                    <span title="Increase value" class="k-link k-link-increase" style="touch-action: none;" aria-label="Increase value" unselectable="on">
                        <span class="k-icon k-i-arrow-60-up" unselectable="on"></span>
                    </span>
                    <span title="Decrease value" class="k-link k-link-decrease" style="touch-action: none;" aria-label="Decrease value" unselectable="on">
                        <span class="k-icon k-i-arrow-60-down" unselectable="on"></span>
                    </span>
                </span>
            </span>
        </span>
    </div>

Rule used in real scenario

checkPercentageMaxValue: function (input) {
                $('input[data-maxallowedvalue][data-validate="true"]').each(function (index, item) {
                    var maxAllowedValue = parseInt($(item).attr('data-maxallowedvalue'));
                    var currentValue = parseInt($(item).val().replace(/%?$/, ''));
                    if (currentValue > maxAllowedValue) {
                        return false;
                    }
                    else {
                        return true;
                    }
                });
                return true;
            }
  • I have taken your fiddle and modified it here for you. http://dojo.telerik.com/OsUCiJuT is this what you are after? – David Shorthose Jul 09 '18 at 12:59
  • @DavidShorthose , thanks for the modification. I have seen the modification you have made (root changed to $('body')), but in my real code, I have the reference to root correctly. Issue what I am facing is, even though the kendo validator runs through the defined rules, its still don't set the validation message. I have around 10 rules and this one is the last one. It runs the rules and returns "false" if condition fails, but then executes the last "return true;" statement as well. – Jayesh Jayakumar Jul 09 '18 at 13:20
  • I have updated my dojo with another control and it fires the validation rules as expected. – David Shorthose Jul 09 '18 at 13:28
  • @DavidShorthose: thanks for the update. I have made edit to the question, adding the actual html rendered at my side. I am creating a html from server side and converts the input at client side to "kendoNumericTextBox". Once i do that, i am getting the above mentioned html. Also i have created a dojo with the same. http://dojo.telerik.com/@jayesh.jayakumar/aJaWuHaC here you can see the validation message are not firing for all three correctly. – Jayesh Jayakumar Jul 09 '18 at 14:03
  • updated again http://dojo.telerik.com/UHIhACOh I think the issue you are experiencing is there is no check for `not a number` and so the validation is firing incorrectly once you have put a value in on the first attempt (in percentage box 3) so I have applied a check to see if the value attempted to be converted is a number and if not then return 0. you could always change this to an `incorrect` value to highlight the issue. but I would assume you are using 0 as the default value. If this is what is expected then I will create a full answer for you. – David Shorthose Jul 09 '18 at 14:56
  • @DavidShorthose : I have updated the question with rule used in real scenario – Jayesh Jayakumar Jul 09 '18 at 15:09
  • @DavidShorthose: I have updated the dojo the way you have mentioned. Now validation do gets fired,but messages are not shown correctly. I have 3 controls and have assigned 3 different messages. But I am getting below issues 1) If I enter value greater than 100 on 3rd control, its shows correct message, but when i try to access other control, the validation messages are shown overlapping the control. 2) If i enter correct value to the 2nd and 3rd but wrong value to 1st, the messages are shown for 3rd also on accessing it again [link]http://dojo.telerik.com/@jayesh.jayakumar/aJaWuHaC) – Jayesh Jayakumar Jul 09 '18 at 18:16

1 Answers1

0

Right after some trial and error and finally understanding what it is you want. I think you have misunderstood how the validator rules work.

http://dojo.telerik.com/UHIhACOh

The rules: checkPercentageMaxValue: function(input) {

     var valid = true;
     singlerule += 1;
     if ($(input).is('[data-maxallowed-value][data-validate="true"]')) {
       var maxAllowedValue = parseFloat($(input).attr('data-maxallowed-value'));
       var currentValue = parseFloat($(input).val());
       if (isNaN(currentValue)) {
         currentValue = 0;
       }
       valid = (currentValue <= maxAllowedValue);
       $('#control1').html('Max Allowed Value::' + maxAllowedValue + ',Current Parsed Value::' + currentValue);
     } else {
       $('#control1').html('<pre><code>' + JSON.stringify($(input), null, 4) + '</code></pre>');

     }

     $('#control1').append('I ran <b>checkPercentageMaxValue</b> rule: ' + singlerule + 'time(s)<br/>');


     singlerule = 0;

     return valid;
   },
   yourrule: function(input) {
     $('input[data-maxallowed-value][data-validate="true"]').each(function(index, item) {
       multirule += 1;
        $('#control1').append('I ran <b>yourrule</b> rule: ' + multirule + 'time(s)<br/>');
       var maxAllowedValue = parseFloat($(item).attr('data-maxallowed-value'));
       var currentValue = parseFloat($(item).val());
       if (isNaN(currentValue)) {
         currentValue = 0;
       }
       if (currentValue > maxAllowedValue) {
         return false;
       } else {
         return true;
       }
     });


     multirule = 0;
     return true;

   }

 }

Each rule listed in the custom rules list is ran on every control that is being validated.

So your current rule is checking each input control and then any other input controls of that type again assuming they meet the approved condition.

So you are running the checks multiple times and if one passes then your rule assumes all have passed if it hits a true condition and the same is true for an error'd item which is why you are getting the issues you are currently getting. Obviously if this is what you want (checking multiple items are the same time) then you need to hold the true/false value in a variable so that it will return back the message (but this message will only be displayed next the control that kicked off the initial validation/focus)

Hopefully adding the second control will show you what is happening clearer.

As you can see the first time you enter a control your rule will run twice until one of the input boxes states that is in an error state and then you rule will only run when one of the controls is in a invalid state, if you put a value incorrectly in the second box then your rule states that it has exited successfully and is valid.

I added a button so you can see if the validator thinks it is in a valid/invalid state based on the rules provided.

If anything isn't clear or you need more info let me know and I will update the answer accordingly.

David Shorthose
  • 4,489
  • 2
  • 13
  • 12
  • Thank you David. I will modify my code based on your input and will update you. "Each rule listed in the custom rules list is ran on every control that is being validated" , I guess I made the mistake there. – Jayesh Jayakumar Jul 09 '18 at 18:24
  • I have tried with the rule change, but shill I am getting an issue. I will edit my question with the result I obtained after implementing the new change and as well the complete set of rule which I am using and the html which been generated. It would be great help if we could discuss this over a chat as well as its difficult to reveal more about the code and html here. – Jayesh Jayakumar Jul 10 '18 at 07:25
  • It worked David.. Thank you so much. But certainly I would like to have a chat with you to discuss and clarify few doubts I have in relation to Kendo UI validation. – Jayesh Jayakumar Jul 10 '18 at 08:15