我们尝试通过覆盖Kendo numerictextbox的默认行为来显示验证错误消息以显示百分比值。
我们的期望是在用户键入任何大于 100 的值时提供自定义消息。
默认情况下,如果用户键入的任何内容超过 100,则用于百分比自动的 Kendo NumericT文本框会更正该值(我们不希望此行为)
请找到一个相同的jsfiddle引用URL以更好地理解它 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;
}
经过一些反复试验,终于明白你想要什么。我认为您误解了验证器规则的工作原理。
http://dojo.telerik.com/UHIhACOh
规则: checkPercentMaxValue: 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 值,以便它返回消息(但此消息只会显示在启动初始验证/焦点的控件旁边)
希望添加第二个控件将更清楚地显示正在发生的事情。
正如您第一次输入控件时所看到的,您的规则将运行两次,直到其中一个输入框状态处于错误状态,然后您的规则将仅在其中一个控件处于无效状态时运行,如果您在第二个框中输入了错误的值,那么您的规则将声明它已成功退出并且有效。
我添加了一个按钮,以便您可以根据提供的规则查看验证器是否认为它处于有效/无效状态。
如果有任何不清楚的地方或您需要更多信息,请告诉我,我会相应地更新答案。