...">

If all conditions match inside the foreach

I have this html type:

<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 array contains the indices input , condition and value . There may be any inputs, as well as many conditions. Suppose

 input = username condition = 0 (is) value = abc input = firstname condition = 1 (is not) value = pqr 

I need to do something (show / hide) if

username is abc and firstname isnot pqr

from the interface. But radio_sXsPOwVSD, condition 1 and the value Male can be entered.

then

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

However, it seems to be OR if there are any matches, but I need all the matches. I could calculate matches and compare with the length of the array, but with onChange counting on one field, it seems to increase / decrease several times. What could be the solution? I was stuck on this for a while.

 applyConditions = [ {"input":"username","condition":"0","value":"abc"}, {"input":"firstname","condition":"1","value":"pqr"} ]; 

can also be {"input":"radio_SXsPOwVSD","condition":"0","value":"Male"},

+5
source share
4 answers

Compare if ($(ele).val() == item.value) equals item.condition

to determine if this is true.

The next version now works with the radio and checkbox buttons.

Well, finally, I found that each input has the name 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 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> 
+8
source

This is just an alternative algorithm.

 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
source

To verify that everyone is using one of a variety of conditions, use Array.prototype.every .

This solution has a setRules function that accepts a set of rules in the above format and returns an object with the onChange property to add listeners. These listeners are triggered when any of the values ​​is changed and a new boolean value is passed. It is easy to save the current value so that it only works when switching from true to false or vice versa.

You can use it as follows:

 const ruleHandler = addRules(applyConditions); ruleHandler.onChange(function(newValue) { /* do something */ } 

(or just connect them together as shown below).

It also makes it easier to add new conditions, because they are simple functions that take the current value and the whole rule (extended using the jQuery link for the element.) You can add a condition like this:

 '2': function(val, rule) {return val.length >= rule.minLength;} 

And use it as follows:

 {input: "lastname", condition: "2", minLength: "4"}, 

This also indicates that you can use arbitrary names for these conditions, rather than "1" and "2" . Perhaps they could

Most of them are quite simple. The only part that I think needs to be explained is this:

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

Please note that first we call every in our rules.

In the second line, we allow the radio buttons to be represented by the element :checked , and others by the only element in the $elt object.

The third line is the heart of this code: it finds the correct condition function, looking through it, or if it is not found, selects a function that simply returns true. Then it calls this function with the value of the element and the rule itself.

 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> 

Also note that this would be cleaner and more readable if you were to use 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(); } }; } 
+2
source

Removed the array and used the data attribute instead.

 $(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> 
+1
source

Source: https://habr.com/ru/post/1276203/


All Articles