提问人:micky 提问时间:3/31/2018 最后编辑:micky 更新时间:4/9/2018 访问量:1362
如果 foreach 中的所有条件都匹配
If all conditions matches inside foreach
问:
我有这种类型的html:
<p id="username_input" data-priority="">
<label for="username">Username</label>
<input type="text" class="input-text um-field " name="username" id="username" placeholder="" value="" required="required" data-label="Username">
</p>
<p id="firstname_input" data-priority="">
<label for="firstname">First Name</label>
<input type="text" class="input-text um-field " name="firstname" id="firstname" placeholder="" value="" required="required" data-label="FirstName">
</p>
<p class="form-row " id="radio_SXsPOwVSD_input">
<input type="radio" class="input-radio um-field" value="Male" name="radio_SXsPOwVSD" id="radio_SXsPOwVSD_male">Male
<input type="radio" class="input-radio um-field" value="Female" name="radio_SXsPOwVSD" id="radio_SXsPOwVSD_Female">Female
</p>
applyConditions
数组包含 和 索引。可以是任何输入,也可以是许多条件。假设input
condition
value
input = username
condition = 0 (is)
value = abc
input = firstname
condition = 1 (is not)
value = pqr
如果出现以下情况,我需要做点什么(显示/隐藏复选框)
username is abc and firstname isnot pqr
从前端。但可以输入radio_sXsPOwVSD、条件 1 和值 Male。
然后
applyConditions.forEach( function( item ) {
if(item.condition == 0) {
jQuery("#"+ item.input+"_input").on('change', ( function( avalue ) {
return function(e) {
if( e.target.value == avalue ) {
//show checkbox
}
else {
//hide checkbox
}
};
})(item.value));
}
else if( item.condition == 1 ) {
jQuery("#"+ item.input+"_input").on('change', ( function( avalue ) {
return function(e) {
if( e.target.value != avalue ) {
//show checkbox
}
else {
//hide checkbox
}
};
})(item.value));
}
});
但是,这似乎是 OR,如果有任何匹配,但我需要所有匹配。我可以计算匹配项并与数组长度进行比较,但是在同一字段上使用 onChange 计数似乎会增加/减少多次。解决方案是什么?我被困在上面一段时间了。
applyConditions =
[
{"input":"username","condition":"0","value":"abc"},
{"input":"firstname","condition":"1","value":"pqr"}
];
也可能是{"input":"radio_SXsPOwVSD","condition":"0","value":"Male"},
答:
比较是否相等($(ele).val() == item.value)
item.condition
以确定它是否与条件匹配。
以下版本现在适用于按钮和 .radio
checkbox
好吧,我终于发现每个输入上都有名字。attr
var applyConditions = [
{
'input': 'username',
'condition': 0,
'value': 'abc'
},
{
'input': 'firstname',
'condition': 1,
'value': 'pqr'
},
{
"input": "radio_SXsPOwVSD",
"condition": 0,
"value":"Male"
},
{
"input": "check_box_XmNoe",
"condition": 0,
"value": "Apple"
}
]
applyConditions.forEach(function(condition) {
var targetInput = $('input[name='+condition.input+']');
targetInput.on('change',function(){
var results = $.map(applyConditions,(item, index)=>{
var targetInput = $('input[name='+item.input+']');
var type = targetInput.get(0).type;
var check = false;
if(type == "radio" || type == "checkbox"){
var input = targetInput.get().find(x=>$(x).is(":checked") && $(x).val() == item.value)
if (input)
{
check = input.value == item.value != item.condition;
}
else{
// since 0 means equal, if there's no any radio button or checkbox is checked, check = false
check = item.condition ? true : false;
}
}
else{
check = (targetInput.val() == item.value) != item.condition;
}
if(check){
// matches
}
else{
// not matches
}
return check;
})
console.log(...results);
})
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<p id="username_input" data-priority="">
<label for="username">Username</label>
<input type="text" class="input-text um-field" name="username" id="username" placeholder="" value="" required="required" data-label="Username">
( ==abc )
</p>
<p id="email_input" data-priority="">
<label for="username">Username</label>
<input type="text" class="input-text um-field" name="email" id="email" placeholder="" value="" required="required" data-label="Email">
( no condition )
</p>
<p id="firstname_input" data-priority="">
<label for="firstname">First Name</label>
<input type="text" class="input-text um-field" name="firstname" id="firstname" placeholder="" value="" required="required" data-label="FirstName">
( !=pqr )
</p>
<p class="form-row" id="radio_SXsPOwVSD_input">
<input type="radio" class="input-radio um-field" value="Male" name="radio_SXsPOwVSD" id="radio_SXsPOwVSD_male">Male
<input type="radio" class="input-radio um-field" value="Female" name="radio_SXsPOwVSD" id="radio_SXsPOwVSD_Female">Female
( Male should be checked )
</p>
<p id="check_box_XmNoe_input">
<label class="checkbox data-label=">Checkbox</label>
<input type="checkbox" class="input-checkbox um-field" name="check_box_XmNoe" id="check_box_XmNoe_Apple" value="Apple"> Apple
<input type="checkbox" class="input-checkbox um-field" name="check_box_XmNoe" id="check_box_XmNoe_Orange" value="Orange"> Orange
( Apple should be checked )
</p>
评论
这只是一种替代算法。
var applyConditions = [
{
"input": "username",
"condition": "0",
"value": "abc",
},
{
"input": "firstname",
"condition": "1",
"value": "pqr",
},
{
"input": "radio_SXsPOwVSD",
"condition": "0",
"value": "Male"
},
];
var totalConditions = applyConditions.length,
conditionFulfilled = 0;
function compare($element, rule) {
if ($element.length > 1) $element = $element.filter(':checked'); //radio
return ($element.val() == rule.value) == (rule.condition == "0");
}
function setOK() {
if (conditionFulfilled == totalConditions) $('#iresult').html('OK');
else $('#iresult').html('Completed('+conditionFulfilled+'/'+totalConditions+')');
}
applyConditions.forEach(function(rule) {
var $element = $('[name=' + rule.input + ']');
var isConditionTrue = compare($element, rule);
if (isConditionTrue) conditionFulfilled++;
$element.change(function() {
var updatedIsConditionTrue = compare($element, rule);
if (isConditionTrue != updatedIsConditionTrue) {
if (updatedIsConditionTrue) conditionFulfilled++;
else conditionFulfilled--;
isConditionTrue = updatedIsConditionTrue;
setOK();
}
});
});
setOK();
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<p id="username_input" data-priority="">
<label for="username">Username</label>
<input type="text" class="input-text um-field " name="username" id="username" placeholder="value = abc" value="" required="required" data-label="Username">
</p>
<p id="firstname_input" data-priority="">
<label for="firstname">First Name</label>
<input type="text" class="input-text um-field " name="firstname" id="firstname" placeholder="value != pqr" value="" required="required" data-label="FirstName">
</p>
<p class="form-row " id="radio_SXsPOwVSD_input">
<input type="radio" class="input-radio um-field" value="Male" name="radio_SXsPOwVSD" id="radio_SXsPOwVSD_male">Male
<input type="radio" class="input-radio um-field" value="Female" name="radio_SXsPOwVSD" id="radio_SXsPOwVSD_Female">Female
</p>
<div>Result: <b id="iresult">Not OK</b></div>
删除了 Array 并改用了 data 属性。
$(document).ready(function(){
$('.validator').delegate('input', 'change', function(event){
event.stopPropagation();
var condition = $(this).closest('.validator').data('condition');
var valueToCompare = $(this).closest('.validator').data('value');
var result = "";
if(condition == "1"){
result = $(this).val().trim() == valueToCompare ? "Condition Satisfied" : "Condition Not Satisfied";
}else{
result = $(this).val().trim() != valueToCompare ? "Condition Satisfied" : "Condition Not Satisfied";
}
console.log(result)
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="validator" data-condition="1" data-value="Rony">
<label for="username">First Name</label>
<input type="text" >
</div>
<div class="validator" data-condition="0" data-value="White">
<label for="username">Last name</label>
<input type="text" >
</div>
<div class="validator" data-condition="1" data-value="Male">
<input type="radio" name="gender" value="Male">Male
<input type="radio" name="gender" value="Female">Female
</div>
<div class="validator" data-condition="0" data-value="Banana">
<input type="radio" name="fruit" value="Apple">Apple
<input type="radio" name="fruit" value="Banana">Banana
</div>
要测试一组条件中的每一个都为真,请使用 Array.prototype.every
。
此解决方案有一个函数 ,它接受上述格式的一组规则,并返回一个对象,该对象具有用于添加侦听器的属性。当任何值发生更改并传递新的布尔值时,将触发这些侦听器。保留当前值并不难,这样它只在从切换到 时触发,反之亦然。setRules
onChange
true
false
你可以像这样使用它:
const ruleHandler = addRules(applyConditions);
ruleHandler.onChange(function(newValue) { /* do something */ }
(或者简单地将它们链接在一起,如下所示。
这也使得添加新条件变得容易,因为它们是接受当前值和整个规则的简单函数(通过对元素的 jQuery 引用进行增强)。您可以添加如下条件:
'2': function(val, rule) {return val.length >= rule.minLength;}
并像这样使用它:
{input: "lastname", condition: "2", minLength: "4"},
这还指出,您可以对这些条件使用任意名称,而不是 和 。也许它们可能是 , ,如果你使用最后一个,."0"
"1"
eq
not_eq
minLength
其中大部分都相当简单。我认为唯一需要解释的部分是:
var newVal = rules.every(function(rule) {
var $elt = (rule.$elt.length > 1) ? rule.$elt.filter(':checked') : rule.$elt;
return (conds[rule.condition] || function() {return true;})($elt.val(), rule);
})
首先要注意的是,我们从调用我们的规则开始。every
在第二行中,我们让单选按钮由元素表示,其他单选按钮由对象中的唯一元素表示。:checked
$elt
第三行是这段代码的核心:它通过查找来找到正确的条件函数,或者如果找不到,则选择一个只返回 true 的函数。然后,它使用元素和规则本身的值调用此函数。
var setRules = function(rules) {
var listeners = [];
var conds = {
'0': function(val, rule) {return val === rule.value;},
'1': function(val, rule) {return val !== rule.value;},
}
var test = function() {
var newVal = rules.every(function(rule) {
var $elt = (rule.$elt.length > 1) ? rule.$elt.filter(':checked') : rule.$elt;
return (conds[rule.condition] || function() {return true;})($elt.val(), rule);
})
listeners.forEach(listener => listener(newVal));
}
rules.forEach(function(rule) {
rule.$elt = $('[name=' + rule.input + ']').change(test);
});
return {
onChange: function(listener) {
listeners.push(listener);
test();
}
};
}
var applyConditions = [
{input: "username", condition: "0", value: "abc"},
{input: "firstname", condition: "1", value: "pqr"},
{input: "radio_SXsPOwVSD", condition: "0", value: "Male"}
];
const $results = $('#result');
setRules(applyConditions).onChange(function(newVal) {
$results.html(newVal ? 'OK' : 'Not OK');
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<p id="username_input" data-priority="">
<label for="username">Username</label>
<input type="text" name="username" id="username" value="abc">
</p>
<p id="firstname_input" data-priority="">
<label for="firstname">First Name</label>
<input type="text" name="firstname" id="firstname" value="pqr">
</p>
<p id="radio_SXsPOwVSD_input">
<input type="radio" value="Male" name="radio_SXsPOwVSD" id="radio_SXsPOwVSD_male" checked>Male
<input type="radio" value="Female" name="radio_SXsPOwVSD" id="radio_SXsPOwVSD_Female">Female
</p>
<div>Result: <b id="result">Not OK</b></div>
另请注意,如果您使用的是 ES6,这将更清晰、更易读:
const setRules = (rules) => {
const listeners = [];
const conds = {
'0': (val, rule) => val === rule.value,
'1': (val, rule) => val !== rule.value
}
const test = () => {
var newVal = rules.every(function(rule) {
var $elt = (rule.$elt.length > 1) ? rule.$elt.filter(':checked') : rule.$elt;
return (conds[rule.condition] || (() => true))($elt.val(), rule);
})
listeners.forEach(listener => listener(newVal));
}
rules.forEach((rule) => {
rule.$elt = $('[name=' + rule.input + ']').change(test);
});
return {
onChange: (listener) => {
listeners.push(listener);
test();
}
};
}
下一个:处理未定义的变量
评论