Пользовательская проверка числового текстового поля Kendo для процентного значения

Мы пытаемся отобразить сообщение об ошибке проверки, переопределив поведение по умолчанию числового текстового поля Кендо для отображения процентного значения.

мы ожидаем предоставить пользовательское сообщение, когда пользователь вводит любое значение больше 100.

По умолчанию Kendo NumericTextbox для процента автоматически исправляет значение, если пользователь вводит что-либо большее, чем 100 (мы не хотим такого поведения)

Пожалуйста, найдите справочный URL-адрес jsfiddle для того же, чтобы лучше понять его 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>

Вот html, который я получаю в реальном сценарии

<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>

Правило, используемое в реальном сценарии

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;
            }

person Jayesh Jayakumar    schedule 09.07.2018    source источник
comment
Я взял вашу скрипку и модифицировал ее здесь для вас. dojo.telerik.com/OsUCiJuT это то, что вам нужно?   -  person David Shorthose    schedule 09.07.2018
comment
@DavidShortose, спасибо за модификацию. Я видел сделанную вами модификацию (корень изменился на $('body')), но в моем реальном коде у меня есть правильная ссылка на корень. Проблема, с которой я сталкиваюсь, заключается в том, что даже несмотря на то, что валидатор кендо выполняет определенные правила, он все еще не устанавливает сообщение проверки. У меня около 10 правил, и это последнее. Он запускает правила и возвращает false, если условие не выполняется, но затем выполняет последний return true; также заявление.   -  person Jayesh Jayakumar    schedule 09.07.2018
comment
Я обновил свой додзё другим элементом управления, и он запускает правила проверки, как и ожидалось.   -  person David Shorthose    schedule 09.07.2018
comment
@DavidShortose: спасибо за обновление. Я внес изменения в вопрос, добавив фактический html, отображаемый на моей стороне. Я создаю html на стороне сервера и преобразую ввод на стороне клиента в kendoNumericTextBox. Как только я это сделаю, я получу вышеупомянутый html. Также я создал додзё с таким же. dojo.telerik.com/@jayesh.jayakumar/aJaWuHaC здесь вы можете увидеть сообщение проверки не срабатывает для всех трех правильно.   -  person Jayesh Jayakumar    schedule 09.07.2018
comment
обновлено снова dojo.telerik.com/UHIhACOh Я думаю, проблема, с которой вы столкнулись, заключается в отсутствии проверки not a number и поэтому проверка запускается неправильно, как только вы ввели значение с первой попытки (в процентном поле 3), поэтому я применил проверку, чтобы увидеть, является ли значение, которое пытались преобразовать, числом, и если нет, то вернуть 0. вы всегда можете изменить это значение на incorrect, чтобы выделить проблему. но я бы предположил, что вы используете 0 в качестве значения по умолчанию. Если это то, что ожидается, я создам для вас полный ответ.   -  person David Shorthose    schedule 09.07.2018
comment
@DavidShorthose: я обновил вопрос с правилом, используемым в реальном сценарии.   -  person Jayesh Jayakumar    schedule 09.07.2018
comment
@DavidShorthose: я обновил додзё так, как вы упомянули. Теперь проверка выполняется, но сообщения отображаются неправильно. У меня есть 3 элемента управления и назначено 3 разных сообщения. Но я получаю следующие проблемы: 1) Если я ввожу значение больше 100 на 3-м элементе управления, он показывает правильное сообщение, но когда я пытаюсь получить доступ к другому элементу управления, сообщения проверки отображаются перекрывающими элемент управления. 2) Если я ввожу правильное значение для 2-го и 3-го, но неправильное значение для 1-го, сообщения отображаются для 3-го также при повторном доступе к нему [ссылка]dojo.telerik.com/@jayesh.jayakumar/aJaWuHaC)   -  person Jayesh Jayakumar    schedule 09.07.2018


Ответы (1)


Сразу после проб и ошибок и, наконец, понимания, чего вы хотите. Я думаю, вы неправильно поняли, как работают правила валидатора.

http://dojo.telerik.com/UHIhACOh

Правила: 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;

   }

 }

Каждое правило, указанное в списке настраиваемых правил, выполняется для каждого проверяемого элемента управления.

Таким образом, ваше текущее правило проверяет каждый элемент управления вводом, а затем снова любые другие элементы управления вводом этого типа, предполагая, что они соответствуют утвержденному условию.

Таким образом, вы запускаете проверки несколько раз, и если одна из них проходит, ваше правило предполагает, что все прошли, если оно соответствует истинному условию, и то же самое верно для элемента с ошибкой, поэтому вы получаете проблемы, которые вы получаете в настоящее время. Очевидно, что если это то, что вы хотите (одновременная проверка нескольких элементов), вам нужно сохранить значение true/false в переменной, чтобы она вернула сообщение (но это сообщение будет отображаться только рядом с элементом управления, который выбил от первоначальной проверки/фокуса)

Надеюсь, добавление второго элемента управления покажет вам, что происходит, яснее.

Как вы можете видеть, при первом входе в элемент управления ваше правило будет выполняться дважды, пока одно из полей ввода не укажет, что оно находится в состоянии ошибки, а затем ваше правило будет выполняться только тогда, когда один из элементов управления находится в недопустимом состоянии, если вы поместите неправильное значение во втором поле, тогда ваше правило утверждает, что оно успешно завершено и является действительным.

Я добавил кнопку, чтобы вы могли видеть, считает ли валидатор, что она находится в действительном/недействительном состоянии на основе предоставленных правил.

Если что-то неясно или вам нужна дополнительная информация, дайте мне знать, и я соответствующим образом обновлю ответ.

person David Shorthose    schedule 09.07.2018
comment
Спасибо, Дэвид. Я изменю свой код на основе вашего ввода и обновлю вас. Каждое правило, указанное в списке настраиваемых правил, выполняется для каждого проверяемого элемента управления, я думаю, я допустил ошибку. - person Jayesh Jayakumar; 09.07.2018
comment
Я пытался изменить правило, но у меня возникла проблема. Я отредактирую свой вопрос с результатом, полученным после внесения нового изменения, а также с полным набором правил, которые я использую, и сгенерированным html. Было бы здорово, если бы мы могли обсудить это в чате, так как здесь сложно рассказать больше о коде и html. - person Jayesh Jayakumar; 10.07.2018
comment
Это сработало, Дэвид .. Большое спасибо. Но, конечно же, я хотел бы поговорить с вами, чтобы обсудить и прояснить некоторые сомнения, которые у меня есть в отношении проверки пользовательского интерфейса Kendo. - person Jayesh Jayakumar; 10.07.2018