0

How do I implement a function to display values when selecting different choices(including multi choice from one dropdown) from multi dropdown list selection for instance, the html would be

<!DOCTYPE html>
<html>
<body>
<div>
 <select name="entities">
  <option value="0">--Select one item--</option>
  <option value="1">entity1</option>
  <option value="2">entity2</option>
  <option value="3">entity3</option>
 </select>
</div>

<div>
 <select name="categories" multiple>
  <option value="0">--Select one item--</option>
  <option value="1">category1</option>
  <option value="2">category2</option>
  <option value="3">category3</option>
 </select>
 </div>

<p> Display values </p>
<div id="displayValues"></div>
</body>
</html>

For example, the display rules that need to satisfy the following table

|--------------------------|------------------|----------------------|
|      Display Value       |     Entities     | Categories           |
|--------------------------|------------------|----------------------|
| "value1"                 |        entity1   | category1            |
|--------------------------|------------------|----------------------|
|  "value2"                |        entity2   | category1            |
|--------------------------|------------------|----------------------|
|  "value3"                |        entity1   | category2            |
|--------------------------|------------------|----------------------|
|  "value4"                |        entity1   | category1 & category2|
|--------------------------|------------------|----------------------|
|    ...                   |         ...      |      ...             |

how can I create a generic javascript function to control the display value for different conditions? instead of writing all conditions using if else inside the function? (ps.may write a generic function and a seperate dictionary for containing all rules??)

user3651247
  • 238
  • 1
  • 7
  • 19
  • Where your display values, and how they look like? – Chayim Friedman Aug 12 '18 at 08:04
  • The display value should be in the div tag called "displayValues", which the value should be a list of statements(string type) that controlled by the combination of Entity selection and category selections. When select a different option from the two dorpdown list, the display value should be different. – user3651247 Aug 12 '18 at 08:10
  • Please attach the object of the display values, and the rules for show the values. – Chayim Friedman Aug 12 '18 at 08:13
  • For example the display value can be displayValue = ["Value1", "Value2", "Value3", "Value4", "Value5" ... ]. Based on the above table, the rules can be if we select entities=entity1 && categories=category1, then the display value should be "value1". – user3651247 Aug 12 '18 at 08:30
  • Can we create a rules generate? like creating an array for containing the display values displayValue=["value1", "value2", "value3","value4" ...], and then create a dictionary to be consume by a function displayDic = {{0:["Entities":1, "Categories":1]}, {1:["Entities":2, "Categories":1]}}. The key stands for the index of displayValue. Once more cobinations added in the above table, we can directly add the rules in the displayDic dictionary???? or any other idea for solving it? thanks – user3651247 Aug 12 '18 at 08:31
  • But what are the rules? Why you decide to show Value1 when the user select category1 and entity`? – Chayim Friedman Aug 12 '18 at 08:42
  • As the above is just a demo, the real problem contain more then hundreds selection for more than 10 dropdown list (many to many relationships that does not use db to store the data relations). and each combination selection from different dropdown list will produce different display values(above one example is select category1 and entity1 to produce value1). The above table is just the few displayValues with selecting different combinations. so this is why I am trying to produce a generator which can consume all the different rules from the table. – user3651247 Aug 12 '18 at 08:54
  • You didn't answer me. There aren't rules? Nothing mean to which values show by the selected categories & entity? – Chayim Friedman Aug 12 '18 at 08:56
  • Right, I understand your question, so this is why I feel confused. As in the real problem, there is no generic rules for different dropdown list. Its just with different combination selection for the dropdown list, the display value are different. The above "value1", "value2"... is just an example, which are different string statement for the real problem. For example value1 is "provide email address", value2 is "provide home address" and so on... – user3651247 Aug 12 '18 at 09:03
  • Do you want that _both the entity and category_ will select to display value, or that _the entity or category_? For example dou you want to show Value1 when both category1 and entity1 selected, or when category1 or entity1 selected? – Chayim Friedman Aug 12 '18 at 09:18
  • Thanks Chayim, the value1 should be displayed only both category1 and entity1 selected. If only one of them is selected, the value will not be displayed. From my understanding, as without using realtional db, all the combinations have to be implemented by manually, right? – user3651247 Aug 12 '18 at 09:23

1 Answers1

1

I think you should build an dictionary and use it, for example:

var dict = {
  "Value1": { entities: [1, 3], categories: [1] },
  "Value2": { entities: [1], categories: [2] },
  "Value3": { entities: [1, 2], categories: [1, 3] },
  "Value4": { entities: [1, 2, 3], categories: [1, 3] },
  "Value5": { entities: [2, 3], categories: [1, 2] }
};
var entitiesList = document.querySelector('[name=entities]'),
  categoriesList = document.querySelector('[name=categories]'),
  displayValues = document.querySelector('#displayValues');

function getSelectValues(select) {
  var result = [];
  var options = select && select.options;
  var opt;

  for (var i = 0, iLen = options.length; i < iLen; i++) {
    opt = options[i];

    if (opt.selected) {
      result.push(opt.value || opt.text);
    }
  }
  return result;
}

function arrayContainsElementFrom(arr1, arr2) {
  for (var i in arr2) {
    if (-1 !== arr1.indexOf(arr2[i])) {
      return true;
    }
  }
  return false;
}

document.querySelectorAll('[name=entities],[name=categories]').forEach(function(el) {
  el.addEventListener('change', function() {
    while (displayValues.firstChild) {
      displayValues.removeChild(displayValues.firstChild); // Remove the previous children
    }
    
    var entity = parseInt(entitiesList.options[entitiesList.selectedIndex].value),
      categories = getSelectValues(categoriesList)
        .map(function(v) { return parseInt(v); });
    
    for (var value in dict) {
      if (-1 !== dict[value].entities.indexOf(entity) &&
          arrayContainsElementFrom(dict[value].categories, categories)) {
        var el = document.createElement('div');
        el.textContent = value; // For old browsers use innerText
        displayValues.appendChild(el);
      }
    }
  }, false);
});
<div>
  <select name="entities">
    <option value="0">--Select one item--</option>
    <option value="1">entity1</option>
    <option value="2">entity2</option>
    <option value="3">entity3</option>
  </select>
</div>

<div>
  <select name="categories" multiple>
    <option value="0">--Select one item--</option>
    <option value="1">category1</option>
    <option value="2">category2</option>
    <option value="3">category3</option>
  </select>
</div>

<p>Display values</p>
<div id="displayValues"></div>
Chayim Friedman
  • 47,971
  • 5
  • 48
  • 77
  • Hi Chayim, do I need to import any API in the html to run this code? why it does not work neither running this on a local editor or testing in w3c editor? – user3651247 Aug 12 '18 at 12:38
  • My guess is that on your local computer, the code run before the DOM loaded. So, you should place the ` – Chayim Friedman Aug 12 '18 at 12:43
  • Hi Chayim, if i wanna add the displayValues to be a list of checkboxes that can be ticked. If just change the el=document.createElement('input') and el.type='checkbox' then added to displayValue, the checkboxes will be showed. But those checkboxes can not be ticket. Does this due to the 'addEventListener' in the code? how to solve it? thanks – user3651247 Aug 13 '18 at 11:01
  • @user3651247 Yes, this was a problem - I attached the event `change` to `this`, and forgot that inside `forEach()` `this` doesn't change and it's `window`. So, change the checkbox state changed `window` (bubbling), and so the checkbox are re-created with losting the previous state... I fixed my answer. – Chayim Friedman Aug 13 '18 at 11:07