javascript - array filtering does not work as expected -


i have array of objects , wanna filter them based on size, color , collar.

everything works expected whenever uncheck checkbox when re-check again brings unwanted objects.

var database = [      {id:0o1, size: "xl",  color:"red",    collar: "v-neck"},      {id:0o2, size: "s",   color:"blue",   collar: "regular"},      {id:0o3, size: "xxl", color:"red",    collar: "scoop"},      {id:0o4, size: "l",   color:"green",  collar: "v-neck"},      {id:0o5, size: "xl",  color:"blue",   collar: "turtle-neck"},      {id:0o6, size: "l",   color:"red",    collar: "v-neck"}  ];      window.onload = function () {        var vneckcollarcheckbox = document.queryselector('#vneck-collar-checkbox');      var xlsizecheckbox = document.queryselector('#xl-size-checkbox');      var redcolorcheckbox = document.queryselector('#red-color-checkbox');        var div = document.queryselector('div');          var db = database;          function filterbyvneckcollar() {          let vneckcollar = database.filter(function (item) {              return item.collar === "v-neck";          });          if(!vneckcollarcheckbox.checked){              db = db.filter(function (i) {                  return vneckcollar.indexof(i) < 0;              });              div.innerhtml = json.stringify(db);          }          else{              db = db.concat(vneckcollar);              div.innerhtml = json.stringify(db);          }      }        function filterbyxlsize() {          let xlsize = database.filter(function (item) {              return item.size === "xl";          });          if(!xlsizecheckbox.checked){              db = db.filter(function (i) {                  return xlsize.indexof(i) < 0;              });              div.innerhtml = json.stringify(db);          }          else{              db = db.concat(xlsize);              div.innerhtml = json.stringify(db);          }      }        function filterbyredcolor() {          let redcolor = database.filter(function (item) {              return item.color === "red";          });          if(!redcolorcheckbox.checked){              db = db.filter(function (i) {                  return redcolor.indexof(i) < 0;              });              div.innerhtml = json.stringify(db);          }          else{              db = db.concat(redcolor);              div.innerhtml = json.stringify(db);          }        }          div.innerhtml = json.stringify(db);        vneckcollarcheckbox.addeventlistener('change', filterbyvneckcollar);      xlsizecheckbox.addeventlistener('change', filterbyxlsize);      redcolorcheckbox.addeventlistener('change', filterbyredcolor);    };
<html>  <head>      <script src="js.js"></script>  </head>    <body>  <form action="#">        <input type="checkbox" id="vneck-collar-checkbox" checked>      <label for="vneck-collar-checkbox">v-neck collar</label>      <br>      <input type="checkbox" id="xl-size-checkbox" checked>      <label for="xl-size-checkbox">xl size</label>      <br>      <input type="checkbox" id="red-color-checkbox" checked>      <label for="red-color-checkbox">red color</label>    </form>  <div></div>  </body>  </html>

try this:

  1. uncheck "red color"
  2. uncheck "xl size"
  3. check "xl size"

you see object containing "color: red" appears.

i know problem in db = db.concat(xxxxx); of else{} statement don't know how achieve desired output.

any other solution/concept achieve sort of filter appreciated.

just filter on database once combination of rules need.

i've put jsdoc on more complicated function you, made generic can used other things too

/**  * @callback filterruletest  * @param {object} obj target object  * @returns {boolean} whether obj passed test  */  /**  * @typedef {object} filterrule  * @property {string} [key] property key find on target  * @property {string} [value] value assigned key of target  * @property {filterruletest} [test] function run on target, return bool  */  /** filters array of objects  * @param {[object]} arrayofobjects array of objects filter  * @param {[filterrule]} arrayofrules array of objects filter  * @param {boolean} [invert] return opposite of rules  * @param {boolean} [emptyrulepasses] default behaviour of empty rule  * @returns {[object]} filtered result  */ function objfilter(arrayofobjects, arrayofrules, invert = false, emptyrulepasses = false) {     return arrayofobjects.filter(obj => {         return invert !== arrayofrules.every(rule => {             if ('key' in rule) {                 if ('value' in rule)                     return obj[rule.key] === obj[rule.value];                 return rule.key in obj;             }             if ('test' in rule) {                 return rule.test(obj);             }             return emptyrulepasses;         });     }); }  function createfilterrules(collar, size, color) {     let rules = [];     if (collar) rules.push({key: 'collar', value: collar});     if (size) rules.push({key: 'size', value: size});     if (color) rules.push({key: 'color', value: color});     return rules; }  const vneckcollarcheckbox = document.queryselector('#vneck-collar-checkbox'); const xlsizecheckbox = document.queryselector('#xl-size-checkbox'); const redcolorcheckbox = document.queryselector('#red-color-checkbox'); const div = document.queryselector('div');  function filterclothes(db) {     return objfilter(         db,         createfilterrules(             vneckcollarcheckbox.checked ? 'v-neck' : null,             xlsizecheckbox.checked ? 'xl' : null,             redcolorcheckbox.checked ? 'red' : null         )     ); }  function clotheshandle() {     div.innerhtml = json.stringify(filterclothes(database)); }  vneckcollarcheckbox.addeventlistener('change', clotheshandle); xlsizecheckbox.addeventlistener('change', clotheshandle); redcolorcheckbox.addeventlistener('change', clotheshandle); 

Comments

Popular posts from this blog

ios - RestKit 0.20 — CoreData: error: Failed to call designated initializer on NSManagedObject class (again) -

java - Digest auth with Spring Security using javaconfig -

laravel - PDOException in Connector.php line 55: SQLSTATE[HY000] [1045] Access denied for user 'root'@'localhost' (using password: YES) -