如果所有条件都匹配foreach

时间:2018-03-31 12:16:10

标签: javascript jquery

我有这种类型的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数组包含inputconditionvalue索引。可以是任何输入,也可以是许多条件。假设,

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"},

4 个答案:

答案 0 :(得分:13)

比较($(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>

答案 1 :(得分:3)

这只是一种替代算法。

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>

答案 2 :(得分:3)

要测试每个一组条件之一为真,请使用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"。也许它们可能是eqnot_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的函数。然后它使用元素的值和规则本身调用此函数。

&#13;
&#13;
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');
})
&#13;
<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>
&#13;
&#13;
&#13;

另请注意,如果您使用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(); 
    }
  };
}   

答案 3 :(得分:2)

删除了数组并改为使用数据属性。

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